пятница, 8 февраля 2013 г.

JStree AJAX lazy loading and submitting of selected nodes to server

Sometimes your need to work with trees.
After some time of research I could find 2 implementations of javascript trees: jsTree (http://www.jstree.com/) and Dynatree (http://code.google.com/p/dynatree/).

I could only try jsTree because of limited time.
So, here are my requirements:
1) lazy loading of selected nodes. It's because tree size can be quite big. And store all the tree is unnecessary.
2) one can choose any number of nodes and submit selected nodes of the tree to server.



 The first task i could solve with the help of this post (http://www.miketyka.com/2012/10/lazy-loading-with-jstree-and-ajax/) with the exception that i need to request nodes based on more than one criteria:
Here is the code:
 $("#newStreet").jstree({
      "json_data" : {
        "ajax" : {
            "url" : function( node ){
                      // lets figure out the url - this function needs to
                      // return the formed URL. If "node" is "-1" then
                      // this is the top of the hierarchy and there's no parent
                      // key. Otherwise, node is a jquery object of
                      // the respective node from which we can fish out the
                      // metadata needed. (added below at "metadata" : op )
                      if( node == -1 ){
                        return app.findFromUpToDown + "?";
                      } else {
                        return app.findFromUpToDown + "?code=" + node.data("code")+"&name="+ node.data("name")+"&type="+node.data("type");
                      }
                    },
            "contentType": 'application/x-www-form-urlencoded; charset=UTF-8',
            "type" : "POST",  // this is a GET not a POST
            "success" : function(ops) {
                  // this is called when the AJAX request is successful. "ops"
                  // contains the returned data from the server, which in
                  // my case is a json object containing an array of objects.
                  data = [];
                  // go through data and create an array of objects to be given
                  // to jsTree just like when you're creating a static jsTree.
                  for( opnum in ops ){
                    var op = ops[opnum];
                    node = {
                        "data" : op.data,
                        "metadata" :  op.metadata,
                        // THIS LINE BELOW IS THE MAGIC KEY!!! This will force
                        //  jsTree to consider the node
                        // openable and thus issue a new AJAX call hen the
                        // user clicks on the little "+" symbol or
                        // whatever opens nodes in your theme
                        "state" : "closed"
                    }
                    data.push( node );
                  }
                  return data; // this will return the formed array
                               // "data" to jsTree which will turn
                               // it into a list of nodes and
                               // insert it into the tree.
            }
         },
      },
      checkbox:{
          real_checkboxes: true,
          real_checkboxes_names: function (n) {
                           return [("check_" + (Math.ceil(Math.random() * 10000))), n.data("code")+"&"+n.data("type")];
                    }
      },
      "core" : {"html_titles" : true,  "load_open" : true },
      "plugins" : [ "themes", "json_data", "ui", "crrm", "checkbox" ]
  });
   
The key is ajax.url function which allows you to build the request for nodes based on some criteria of the selected node ( return app.findFromUpToDown + "?code=" + node.data("code")+"&name="+ node.data("name")+"&type="+node.data("type");).
Also note that to be able to use "data" function on the node we need to store the node data in "metadata" attribute.
Please also take a look at the attribute "state" : "closed". We need it, because we don't know weather the response nodes can be unfolded further.

For working the checkboxes we use the checkbox module which is included in the jsTree distribution.  What we need is to generate the real checkboxes near the node and generate the id and value for the checkbox. This is achieved with "real_checkboxes_names" function.

After one have selected the nodes you can get the checkboxes like this:
$('input[type=checkbox]:checked[value$="03"]').each(function(){
            current = $(this).val().split("&")[0];      
            if (serStr == ''){
                serStr += current;
            }else{
                serStr += '&'+current;
            }
        });
After this we will have all the selected values in the serStr string which you can submit to server.

Комментариев нет:

Отправить комментарий