2017年3月14日 星期二

(js)建構樹狀階層的 dom

var data = {
            "外文": undefined,
            "理工": {
                "理": {
                    "物理": undefined,
                    "化學": undefined
                },
                "工": {
                    "機械": undefined,
                    "電機": undefined
                }
            },
            "社會文學": {
                "社會": {
                    "心理": undefined,
                    "社工": undefined
                },
                "文學": null
            }
        };



        function main_job(data) {
            var hierarchyData = [];
            job_1(data);

            if (hierarchyData.length) {
                job_2();

                job_3();
            }

            console.dir(hierarchyData);
            /* ================================== */
            /**
             * 建構第一層資料
             */
            function job_1(data) {
                var level = hierarchyData.length;
                var list = hierarchyData[level] = [];

                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        var node = {
                            content: key,
                            dom: null,
                            parent: null,
                            value: data[key],
                            haveHierarchy: false,
                            path: key
                        }

                        if (node.value != null && typeof node.value === 'object') {
                            node.haveHierarchy = true;
                        }

                        list.push(node);
                        /* ---------------------------------- */
                    }
                }
            }

            /* ================================== */
            /**
             * 依序建構各層資料
             */
            function job_2() {

                for (var i = 0; i < hierarchyData.length; i++) {
                    var parentList = hierarchyData[i];
                    var nextLevel = i + 1;
                    var list = [];

                    parentList.forEach(function(parentNode) {

                        if (parentNode.haveHierarchy) {
                            var childList = parentNode.value;

                            for (var key in childList) {
                                if (childList.hasOwnProperty(key)) {
                                    var child = childList[key]

                                    var node = {
                                        content: key,
                                        dom: null,
                                        parent: parentNode,
                                        value: childList[key],
                                        haveHierarchy: false,
                                        path: ''
                                    }

                                    node.path = node.parent.path + '.' + key;

                                    if (node.value != null && typeof node.value === 'object') {
                                        node.haveHierarchy = true;
                                    }

                                    list.push(node);
                                }
                            }
                        }
                    });

                    if (list.length) {
                        hierarchyData[nextLevel] = list;
                    } else {
                        break;
                    }
                }
            }
            /* ================================== */
            /**
             * 根據建立好的資料結構,建立 dom
             */
            function job_3() {

                var rootDom = document.createElement('ul');

                hierarchyData.forEach(function(hierarchy) {


                    hierarchy.forEach(function(node, i) {
                        debugger;
                        var parentDom = (node.parent ? node.parent.dom : rootDom);

                        var liDom = document.createElement('li');
                        liDom.textContent = node.content + '(' + node.path + ')';
                        parentDom.appendChild(liDom);

                        if (node.hasOwnProperty) {
                            var ulDom = document.createElement('ul');
                            liDom.appendChild(ulDom);
                            node.dom = ulDom;
                        } else {
                            node.dom = liDom;
                        }

                    });
                });
                document.querySelector('#test').appendChild(rootDom);
            }

        }
        /* ================================================================== */


        function test_1() {
            main_job(data);
            // console.dir(hierarchyData);
        }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
var data = {
            "外文": undefined,
            "理工": {
                "_link": '.....理工',
                "理": {
                    "_link": '.....理',
                    "物理": {
                        "_link": '.....物理'
                    },
                    "化學": {
                        "_link": '.....化學'
                    }
                },
                "工": {
                    "機械": {
                        "_link": '.....'
                    },
                    "電機": {}
                }
            },
            "社會文學": {
                "社會": {
                    "心理": {
                        "_link": '.....心理'
                    },
                    "社工": {
                        "_link": '.....社工'
                    }
                },
                "文學": null
            }
        };



        function main_job(data) {
            var hierarchyData = [];
            job_1(data);

            if (hierarchyData.length) {
                job_2();

                job_3();
            }

            console.dir(hierarchyData);

            // 做出第一層
            function job_1(data) {
                var level = hierarchyData.length;
                var list = hierarchyData[level] = [];

                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        var node = {
                            content: key,
                            dom: null,
                            parent: null,
                            value: data[key],
                            haveHierarchy: false,
                            path: key,
                            link: ''
                        }

                        if (node.value != null && typeof node.value === 'object') {
                            node.haveHierarchy = true;

                            if (typeof node.value._link !== 'undefined') {
                                node.link = node.value._link;
                                delete node.value._link;
                            }
                        }

                        list.push(node);
                        /* ---------------------------------- */
                    }
                }
            }

            /* ================================== */
            function job_2() {

                for (var i = 0; i < hierarchyData.length; i++) {
                    var parentList = hierarchyData[i];
                    var nextLevel = i + 1;
                    var list = [];

                    parentList.forEach(function(parentNode) {

                        if (parentNode.haveHierarchy) {
                            var childList = parentNode.value;

                            for (var key in childList) {
                                if (childList.hasOwnProperty(key)) {
                                    var child = childList[key]

                                    var node = {
                                        content: key,
                                        dom: null,
                                        parent: parentNode,
                                        value: childList[key],
                                        haveHierarchy: false,
                                        path: '',
                                        link: ''
                                    }

                                    node.path = node.parent.path + '.' + key;

                                    if (node.value != null && typeof node.value === 'object') {
                                        node.haveHierarchy = true;
                                        if (typeof node.value._link !== 'undefined') {
                                            node.link = node.value._link;
                                            delete node.value._link;
                                        }
                                    }



                                    list.push(node);
                                }
                            }
                        }
                    });

                    if (list.length) {
                        hierarchyData[nextLevel] = list;
                    } else {
                        break;
                    }
                }
            }
            /* ================================== */
            function job_3() {

                var rootDom = document.createElement('ul');

                hierarchyData.forEach(function(hierarchy) {


                    hierarchy.forEach(function(node, i) {
                        debugger;
                        var parentDom = (node.parent ? node.parent.dom : rootDom);

                        var liDom = document.createElement('li');
                        liDom.textContent = node.content + '(' + node.link + ')';
                        parentDom.appendChild(liDom);

                        if (node.hasOwnProperty) {
                            var ulDom = document.createElement('ul');
                            liDom.appendChild(ulDom);
                            node.dom = ulDom;
                        } else {
                            node.dom = liDom;
                        }

                    });
                });
                document.querySelector('#test').appendChild(rootDom);
            }

        }
        /* ================================================================== */


        function test_1() {
            main_job(data);
            // console.dir(hierarchyData);
        }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
var data = {
            "外文": undefined,
            "理工": {
                "理": {
                    "物理": undefined,
                    "化學": undefined
                },
                "工": {
                    "機械": undefined,
                    "電機": undefined
                }
            },
            "社會文學": {
                "社會": {
                    "心理": undefined,
                    "社工": undefined
                },
                "文學": null
            }
        };


        function main_job(data) {
            debugger;
            var result = '';
            result += '<ul>';

            result += job_1(data);


            result += '</ul>';

            console.log(result);


            document.querySelector('#test').innerHTML = result;
            /* ================================== */


            function job_1(data) {
                debugger;

                var result = '';

                /**
                 * 先確認 data 是否為 list 
                 */

                var _keyList = Object.keys(data);

                if (Array.isArray(_keyList) && _keyList.length > 0) {
                    // data 是 list

                    // 回圈 data
                    for (var key in data) {
                        if (data.hasOwnProperty(key)) {
                            // data[key]

                            var child = data[key];

                            try {
                                var childKeyList = Object.keys(child);
                            } catch (error) {
                                childKeyList = null;
                            }

                            if (Array.isArray(childKeyList) && childKeyList.length > 0) {
                                // node have child
                                result += '<li>' + key + '<ul>';

                                // loop child
                                result += job_1(data[key]);

                                result += '</ul>';
                                result += '</li>';
                            } else {
                                // node no child
                                result += '<li>' + key + '</li>';
                            }
                        }
                    }
                } else {
                    // data 不是 list
                    result = '<li>' + data + '</li>';
                }




                return result;
            }
        }
        /* ================================================================== */


        function test_1() {
            main_job(data);
            // console.dir(hierarchyData);
        }