To implement the dropdown tree in JavaScript using array-linked list method

Source: Internet
Author: User
Tags abstract abstract tree arrays expression html tags join sort

In web development, most of the Pull-down menus are on one line and up and down, which is good but lacks a hierarchy and the customer doesn't know the relationship between the options, so sometimes we need to display the dropdown in a tree structure in the Drop-down menu to give the customer a better experience. For example: Suppose there is a table in the database that stores information about China's provinces and cities, as follows:

This table is in accordance with the tree structure features, its tree structure as shown on the right, I believe that many tables have such characteristics, the structure of the table below the pull tree display is best, the user can directly see the relationship between the options.

There are a number of ways JavaScript can implement a tree structure, I do not know how those methods are implemented, and do not want to download the ready-made from the Internet, so decided to write one, just start without a clue, then suddenly a moment, thought of the array linked list method, probably thought the following, first figure:

The above picture is the form of the tree structure in the array, each node is stored as an object in an array, each object has an "array" attribute, an array that points to all of its child nodes, and "array" is very important, and all operations of the tree structure are used, especially the traversal of the tree, It can be said that this attribute brings together multiple arrays to form a tree, but this tree is invisible in memory, I think of it as "abstract tree (I just nonsense, only personal name, no basis)", is not a bit of array list of the taste ah? To make it into a tangible tree, we can iterate over it, generate the appropriate HTML tags when traversing, and finally generate the complete HTML code for the tree.

The following is an introduction to the implementation process:

First of all, the table in the database in the form of objects stored in the array, how to save I do not say, not the focus of this article, in order to simplify my direct definition of an array, the code is as follows:

For ease of processing, the information in each row of the table is stored in the array in the form of an object
var array = [
            {id:0,parentid: -1,name: "China"},{id:1, Parentid:0,name: "Henan"  },{id:2, Parentid:1, Name: "Luoyang"},
            {id:3,parentid:1,name: "Zhengzhou"},{id:4,parentid:0,name: "HeBei"},{id: 5,parentid:4,name: "Tangshang"},
            {id:6,parentid:4,name: "Shijiangzhuang"},{id:7,parentid:0,name: "HeiLongJian G "},{id:8,parentid:7,name:" Haerbin "},
            {id:9,parentid:7,name:" Daqing "},{id:10,parentid:0,name:" GuangDong "} , {id:11,parentid:10,name: "Guangzhou"},
            {id:12,parentid:10,name: "Foshan"},{id:13,parentid:1,name: "KaiFeng"} , {id:14, parentid:2, Name: "Ruyang"},
            {id:15,parentid:0,name: "meself"},{id:16,parentid:-1,name: "America"},{id : 17,parentid:16,name: "Maiami"},  {id:18,parentid:17,name: "Heat"}
        ];      

Then, to handle this array, add a "level" attribute to each object, to facilitate the sorting of the array by the "level" attribute of the object, add the most important "array" attribute to each object in the array, and then traverse the HTML of the tree-spanning tree, the code reads as follows:

Add the level attribute This.initlevel = function () {for (var i=0; i<this.array.length;i++) to an object in the array  {this.level = 0;
                    Before calculating the level of each node, reset to 0 this.getlevel (this.array[i].id);
                This.array[i].level = This.level; The Hierarchy This.getlevel = function (ID) {if (!) of each node is evaluated. Boolean (This.array[id]) | |
                Id==-1) {//alert ("the ID" + ID + "is isn't included in array!");
            return false;
                } if (this.array[id].id!=-1) {this.level = this.level + 1;
                var Iidd = This.array[id].parentid;
                Arguments.callee (Iidd);
            This.getlevel (This.array[id].parentid); }//Initialize the abstract tree to handle the root node (multiple root nodes are supported, i.e., multiple trees)//View more highlights of this column: HTTP://WWW.BIANCENG.CNHTTP://WWW.BIANCENG.CN/WEBKF/SC Ript/this.initabstructtree = function() {var rootcount = 0;
             Array_1 is a global variable array_1 = new Array (1);
             shaobing = shaobing + 1;
                     for (Var i=0;i<this.array.length;i++) {if (this.array[i].level==1) {
                     rootcount++;
                     Array_1[i] = This.array[i];
                 shaobing = shaobing + 1;
             else break;
        }//Create an abstract tree, recursively handle all nodes other than the root node, and create a tree structure in the form of an array this.createabstructtree = function (Arrayn)
            {//Save is now traversing the first layer of var layer = Arrayn[0].level + 1 in array arrays;
    
            if (layer>this.array[this.array.length-1].level) return;
                  for (Var i=0;i<arrayn.length;i++) {for (Var j=0;j<this.array.length;j++)
           {if (This.array[j].level>layer)               Break
                          if (This.array[j].level = = Layer&&this.array[j].parentid = = arrayn[i].id) { if (!
                          Boolean (Arrayn[i].array)) {Arrayn[i].array = new array ();
                      } arrayn[i].array.push (This.array[j]); } if (Boolean (Arrayn[i].array)) {This.create
                  Abstructtree (Arrayn[i].array); The HTML this.generatetreehtml = function of the tree structure is recursively generated by following the abstract tree structure stored in the array. Arrayn,signalarray) {for (Var i=0;i<arrayn.length;i++) {if (ARRAYN[I].L
                    Evel = = 1)///root node {if (i = = (arrayn.length-1))//The last node of the first layer has a different icon. {this.html = "<div><Div id= ' Level "+arrayn[i].level+" _ "+arrayn[i].id+" ' ><span>" +arrayn[i].name+ "</span></div>"; else this.html = "<div><div id= ' Level" +arrayn[i].level+ "_" +arrayn[ I].id+ "' ><span>" +
    
                    Arrayn[i].name+ "</span></div>";
                        Control the display of the label, if there are child nodes, then put all the child nodes in the <div> tag if (Boolean (Arrayn[i].array)) {
                    this.html + = "<div>"} if (i = = (arrayn.length-1))
                            {if (Boolean (Arrayn[i].array))//have child nodes {
                            Signalarray.push ("blank");
    This.generatetreehtml (Arrayn[i].array,signalarray);                        Signalarray.pop (); } else {if (Boolean arrayn[i].a
                            Rray))//has child nodes {Signalarray.push ("I");
                            This.generatetreehtml (Arrayn[i].array,signalarray);
                        Signalarray.pop ();
                        } if (Boolean (Arrayn[i].array)) { this.html = "</div></div>"; End Label} else this.html + = "</div>";
                    End label} else//non-root node {//Add corresponding outer picture
                    var outerbiaoqian= "";
                    var innerbiaoqian= ""; if (signalarray.length>0) {foR (var k=0; k<signalarray.length;k++) {Outerbiaoqian = " '}}//Add your own picture if (i = = arrayn.length-1)//Last node {if (Boolean arrayn[i].  Array)) {//and has child nodes innerbiaoqian+= " ';
                        Signalarray.push ("blank"); else {//No child nodes I
                            nnerbiaoqian+= "</div><div>";
                        if (i = = arrayn.length-1)//Last node {signalarray.push ("blank");
else Signalarray.push ("I");                        This.generatetreehtml (Arrayn[i].array,signalarray);
                        Signalarray.pop ();
                    this.html = "</div>"; else//No child nodes this.html = "<div id= ' Level" +arrayn[i].level+ "_" +arrayn[i
    
                ].id+ "' >" +outerbiaoqian+innerbiaoqian+ "<span>" +arrayn[i].name+ "</span></div>";
            This method is called to create a tree structure in which the above method is called to complete the creation of the tree This.createtree = function () {
            This.array = array; This.initlevel (); Add property named level to all Object This.array.sort (This.compare ("level"));
            Sort the array according to the object ' s property of Level This.initabstructtree (); This.createabstructtree (array_1);
            After this method is executed, the array array_1 preserves the information of the tree structure, namely: Array_1 is the root this.generatetreehtml (Array_1,this.signalarray) of the abstract tree; $ ("#tree"). HTML (this.htmL);
    
            This.success = true;
        Tree_additionalfunction (); }///Create a tree structure, add some event and style function to the tree tree_additionalfunction () {//
               Add Style $ ("div[id^=level]" when the mouse is passed). Hover (function () {$ (this). addclass ("DD");
            },function () {$ (this). Removeclass ("DD");
    
            }); When the node is clicked, the value of the node is obtained, and then the tree is not visible $ ("Div[id^=level]"). Click (function () {$ (' #sele '). Val ($ (this). Find ("s
                Pan "). text ());
               Alert ($ (this). FIND ("span"). text ());
            $ ("#tree"). Slideup ();
    
            });
                The corresponding icon $ ("div[id^=level]>img") is replaced when the node is expanded and closed. Click (function () {if (This.nodename = = "img")
                    {var temp = this.src.split ('/');
    
                    var index = temp.length-1; if (temp[index] = = "Tminus.png" | | temp[index] = = "LminUs.png ") {///left expression first removes the last value in the path: the name of the picture to be replaced temp.pop () =
    
                        = "Tminus.png"? this.src = Temp.join ('/') + "/tplus.png": this.src = Temp.join ('/') + "/lplus.png";
    
                        Replace the folder icon $ (this). Next (). attr ("src", temp.join ('/') + "/foldericon.png");
                        $ (this). Parent (). Next (). Slideup ();
                    return false;
                        else if (temp[index] = = "Tplus.png" | | | temp[index] = = "Lplus.png") { The expression on the left first removes the last value in the path: the name of the picture to be replaced temp.pop () = = "Tplus.png"? this.src = Temp.join ('/') + "/T
    
                        Minus.png ": this.src = Temp.join ('/') +"/lminus.png ";
    
                        Replace the folder icon $ (this). Next (). attr ("src", temp.join ('/') + "/openfoldericon.png");
                        $ (this). Parent (). Next (). Slidedown ();
          return false;          }
                }
            } 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.