tree menu, checking / uncheching all child items, client side, possible?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kigoobe
    New Member
    • May 2007
    • 67

    tree menu, checking / uncheching all child items, client side, possible?

    Hi friends,

    I'm having a menu like this -



    that I've fetched from the database, using recursive function, where data is stored as - id | title | parent

    I need a javascript function, that will help me to check / uncheck child elements (if present) when I click on a parent at different level.

    Like,
    • if I check / uncheck Test March, all the check boxes should be checked / unchecked.
    • If I check / uncheck A scent during sleep, only this title should be checked / unchecked.
    • If I check / uncheck Sub March 1, this title and all titles following this should be checked / unchecked.
    • If I check / uncheck test sub sub march, the last two should be checked / unchecked.


    Wondering, if anyone is having any idea here on how to do this.

    Thanks.
  • kigoobe
    New Member
    • May 2007
    • 67

    #2
    I thought to give an update here -

    At this moment, I'm having a javascript array, having a form id~title~parent -

    Code:
    menuArray["59"] = "174~Test March~1";
    menuArray["60"] = "178~A Scent During Sleep~174";
    menuArray["61"] = "175~Sub March 1~174";
    menuArray["62"] = "208~Sub sub March 2~175";
    menuArray["63"] = "209~Sub level 5~208";
    menuArray["64"] = "210~Sub level 6~209";
    menuArray["65"] = "211~Sub level 7~210";
    menuArray["66"] = "207~test Sub Sub March~175";
    menuArray["67"] = "229~test Sub March 03-23~207";
    Hmmm ... now what ?

    Do I need a js recursive function here ?

    Conceptually, I need a function here, like -

    Code:
    function check(id, array) {
     for(var i=0;i<array.length;i++) {
      var vArr = array[i].split("~");
      if (vArr[0] == id) {
      newMenu[] = vArr[0];
      check(vArr[2],array); // this doing the recursion, but again, I need 
    // something similar in javascript, and what about multiple submenus at 
    // the same level, this function will probably take just one line.
      }
     }
    }

    Comment

    • kigoobe
      New Member
      • May 2007
      • 67

      #3
      Check / uncheck all descendents of a menu. Possible?

      Hi guys

      Well, I am storing a multilevel menu in mysql, in the following way.

      id | menu_name | parent_id

      where, ids are linked to each other with parent_id. ie, if menu_y is a child of menu_x, for menu_y the parent_id would be menu_x's id.

      In the webpage, the menu is listed with a check box associated with each menu.

      I need to make a javascript array, where all the menu items will be listed along with their id and parent_id. Then, I need a way to figure out a given menu's children and subsequent descendents.

      The idea is, once we check / uncheck a check box, all it's descendants get checked / unchecked.

      Any tips / hints here friends? Is the recursive thing a possible solution here, that could help me to get all descendents of a menu from it's id?

      I had a post earlier on this subject

      Comment

      • kigoobe
        New Member
        • May 2007
        • 67

        #4
        Speaking about the recursive function, here is what I'm using server side, for php ...

        [php]
        function getNodes($menu_ id, $level = 0, $version='') {
        global $myversion;
        global $arrCheckMenu;
        $sql = "SELECT id, menu_name, parent_menu FROM menu_management WHERE parent_menu='". $menu_id."' AND version = '".$version. "' ORDER BY position";
        $result = mysql_query($sq l);
        while ($row = mysql_fetch_arr ay($result)) {
        if ($row['id']!=1) {
        echo '<p><input type="checkbox" name="check_men uid[]" value="'.$row['id'].'">&nbsp;'.str _repeat('&nbsp; »&nbsp;', $level-1).$row['menu_name'].'</p>';
        }
        getNodes($row['id'], $level+1, $myversion);
        }
        }
        getNodes(0);
        [/php]

        Probably I need a way to convert this php function to a javascript function, with a modification that instead of printing the checkbox I'll be checking / unchecking it. The function could be called onclick with checkbox ... hmmm ... thinking aloud ...

        Comment

        • acoder
          Recognized Expert MVP
          • Nov 2006
          • 16032

          #5
          Originally posted by kigoobe
          Merged with the previous thread.

          To get all the checkboxes, you can use elem.getElement sByTagName("inp ut") where elem is the parent container containing the checkboxes that you need to access. You would also need to check that the elements are checkboxes by checking type.

          One other possibility is to use document.getEle mentsByName() instead and use the name of the set of checkboxes.

          Comment

          • kigoobe
            New Member
            • May 2007
            • 67

            #6
            Thanks acoder ... but the problem is, how to get all child elements recursively !!!

            Comment

            • acoder
              Recognized Expert MVP
              • Nov 2006
              • 16032

              #7
              For recursion to work, it needs to have an end case where it can stop.

              Am I correct in assuming that no parent id is greater than the menu id, e.g. a menu has an id of, say, 175. Its parent id cannot be greater than 175?

              Comment

              • kigoobe
                New Member
                • May 2007
                • 67

                #8
                thanks again, acoder. Actually, no. A menu can have a parent_id which is greater than it's id. Because, id is getting attributed when a menu is getting created, and at that given point it's parent is always smaller than it's id.

                However, when we are moving individual menu items to reorganize the menu, we can easily place a menu created earlier as a child of a menu created later.

                Does this makes the task more difficult? To get the end, we can either start from zero (telling that's the end), or can loop through a javascript array (where we can store all data collected using php on page load) to find the maximum number.

                What is your suggestion here ?

                Comment

                • acoder
                  Recognized Expert MVP
                  • Nov 2006
                  • 16032

                  #9
                  No, I was thinking in terms of efficiency, but here is a better idea. Earlier, you posted this:
                  Originally posted by kigoobe
                  At this moment, I'm having a javascript array, having a form id~title~parent -

                  Code:
                  menuArray["59"] = "174~Test March~1";
                  menuArray["60"] = "178~A Scent During Sleep~174";
                  menuArray["61"] = "175~Sub March 1~174";
                  menuArray["62"] = "208~Sub sub March 2~175";
                  menuArray["63"] = "209~Sub level 5~208";
                  menuArray["64"] = "210~Sub level 6~209";
                  menuArray["65"] = "211~Sub level 7~210";
                  menuArray["66"] = "207~test Sub Sub March~175";
                  menuArray["67"] = "229~test Sub March 03-23~207";
                  How about changing it to:
                  [code=javascript]menuArray[174][0] = "Test March";
                  menuArray[174][1] = 1;
                  menuArray[178][0] = "A Scent During Sleep";
                  menuArray[178][1] = 174;[/code]and so on. This avoids having to split the string to get the values.

                  A tree-based store would be better, but if we're using an array, we need to get all the children and their children. A function could get the children by checking the parent id of each array item. If it matches, then get its children too. The recursion would stop when there are no children.

                  Comment

                  • kigoobe
                    New Member
                    • May 2007
                    • 67

                    #10
                    Thanks ... so first I work on to make the first function to make the changed array, and then a second function for the rest ...

                    thanks ... let's see how far I can go with this wisdom ... :)

                    Comment

                    • acoder
                      Recognized Expert MVP
                      • Nov 2006
                      • 16032

                      #11
                      Originally posted by kigoobe
                      Thanks ... so first I work on to make the first function to make the changed array, and then a second function for the rest ...
                      I was assuming the array was generated by PHP, so you would just generate it differently to make things easier with the JavaScript.

                      As for the function, something like a getChildren function which returns all the children as an array. It might be inefficient, but something like this might work (not tested):
                      [code=javascript]function getChildren(id) {
                      var children = [];
                      for (var i=0;i < array.length; i++) {
                      var parentid = array[i][1];
                      if (parentid == id) {
                      children.push(i );
                      children.concat (getChildren(i) );
                      }
                      }
                      return children;
                      }[/code]

                      Comment

                      • kigoobe
                        New Member
                        • May 2007
                        • 67

                        #12
                        Thanks acoder, I'm still in the first phase. I added a javascript at the top of my page -

                        Code:
                        <script type="text/javascript">
                        <!--
                        var menuArray = new Array();
                        function onloadEvents(id,menu,parent){
                        //alert(id +"="+ menu +"="+ parent);
                        menuArray[id][0] = menu;
                        menuArray[id][1] = parent;
                        alert(dump(menuArray));
                        }
                        -->
                        </script>
                        IE giving menuArray[...] is null or not an object error, while in FF i'm getting menuArray[id] has no properties .... the alert, if unquoted, shows that the values are perfectly present.

                        I'm calling the function from inside of my php code (inside the foreach loop that's printing the full menu) in this way -

                        [PHP]echo '<img src="img/spacer.gif" width="1" height="1" onload="onloadE vents('.$row['id'].', \''.addslashes( $row['menu_name']).'\', '.$row['parent_menu'].');" />'."\r\n";[/PHP]

                        After a second thought, since all what I need is to check and uncheck the checkboxes, I don't even need the menu_names, only menu_id will do here ...

                        hmmm ...

                        Comment

                        • kigoobe
                          New Member
                          • May 2007
                          • 67

                          #13
                          The above javascript code is now reduced to -

                          Code:
                          <script type="text/javascript">
                          <!--
                          	var menuArray = [];
                          	function onloadEvents(id,parent){
                          		menuArray[id] = parent;
                          	}
                          -->
                          </script>
                          And it's not giving any error. However, if I try to call the same at the end of my page like -

                          Code:
                          <script type="text/javascript">
                          <!--
                          	alert(dump(menuArray));
                          -->
                          </script>
                          I get an alert with nothing inside. Probably the javascript is getting created but then getting lost somewhere ...

                          Comment

                          • acoder
                            Recognized Expert MVP
                            • Nov 2006
                            • 16032

                            #14
                            Why not let PHP generate it?
                            [CODE=php]echo "menuArray[".$row['id']."] = ".$row['parent_menu'].";";[/CODE]

                            Comment

                            • kigoobe
                              New Member
                              • May 2007
                              • 67

                              #15
                              thanks acoder ... this php code is working perfectly ... :)

                              now the previous function becomes something like this, right ...

                              [code=javascript]
                              function getChildren(id) {
                              var children = [];
                              for (var i=0;i < array.length; i++) {
                              var parentid = array[i];
                              if (parentid == id) {
                              children.push(i );
                              children.concat (getChildren(i) );
                              }
                              }
                              return children;
                              }
                              [/code]

                              let me try this ... :)

                              Comment

                              Working...