Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: How to save a tree structure

  1. #1
    Ext User
    Join Date
    Mar 2008
    Posts
    34

    Default How to save a tree structure

    Hi,
    I'm starting with ExtJS and I have a problem.
    I show a tree in my webpage and and after drag&drop, I have changed the tree's structure.
    How can I save the new tree's structure??

    thx

  2. #2
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    Use this class to create an XML representation, and post that.

    Code:
    /**
     * @class Ext.tree.TreeSerializer
     * A base class for implementations which provide serialization of an
     * {@link Ext.tree.TreePanel}.
     * <p>
     * Implementations must provide a toString method which returns the serialized
     * representation of the tree.
     * 
     * @constructor
     * @param {TreePanel} tree
     * @param {Object} config
     */
    Ext.tree.TreeSerializer = function(tree, config){
        if (typeof this.toString !== 'function') {
        	throw 'Ext.tree.TreeSerializer implementation does not implement toString()';
        }
    	this.tree = tree;
    	if (this.attributeFilter) {
    		this.attributeFilter = this.attributeFilter.createInterceptor(this.defaultAttributeFilter);
    	} else {
    		this.attributeFilter = this.defaultAttributeFilter;
    	}
    	if (this.nodeFilter) {
    		this.nodeFilter = this.nodeFilter.createInterceptor(this.defaultNodeFilter);
    	} else {
    		this.nodeFilter = this.defaultFilter;
    	}
        Ext.apply(this, config);
    };
    
    Ext.tree.TreeSerializer.prototype = {
    
    	/*
    	 * @cfg nodeFilter {Function} (optional) A function, which when passed the node, returns true or false to include
    	 * or exclude the node.
    	 */
    	/*
    	 * @cfg attributeFilter {Function} (optional) A function, which when passed an attribute name, and an attribute value,
    	 * returns true or false to include or exclude the attribute.
    	 */
    	/*
    	 * @cfg attributeMap {Array} (Optional) An associative array mapping Node attribute names to XML attribute names.
    	 */
    
    	/* @private
    	 * Array of node attributes to ignore.
    	 */
        standardAttributes ["expanded", "allowDrag", "allowDrop", "disabled", "icon",
        "cls", "iconCls", "href", "hrefTarget", "qtip", "singleClickExpand", "uiProvider"];
        
    
    	/** @private
    	 * Default attribute filter.
    	 * Rejects functions and standard attributes.
    	 */
    	defaultAttributeFilter: function(attName, attValue) {
    		return	(typeof attValue != 'function') &&
    				(this.standardAttributes.indexOf(attName) == -1);
    	},
    
    	/** @private
    	 * Default node filter.
    	 * Accepts all nodes.
    	 */
    	defaultNodeFilter: function(node) {
    		return true;
    	}
    };
    
    /**
     * @class Ext.tree.XmlTreeSerializer
     * An implementation of Ext.tree.TreeSerializer which serializes an
     * {@link Ext.tree.TreePanel} to an XML string.
     */
    Ext.tree.XmlTreeSerializer = function(tree, config){
    	Ext.tree.XmlTreeSerializer.superclass.constructor.apply(this, arguments);
    };
    
    Ext.extend(Ext.tree.XmlTreeSerializer, Ext.tree.TreeSerializer, {
    	/**
    	 * Returns a string of XML that represents the tree
    	 * @return {String}
    	 */
    	toString: function(nodeFilter, attributeFilter){
    		return '\u003C?xml version="1.0"?>\u003Ctree>' +
    			nodeToString(this.getRootNode()) + '\u003C/tree>';
    	},
    
    	/**
    	 * Returns a string of XML that represents the node
    	 * @param {Object} node The node to serialize
    	 * @return {String}
    	 */
    	nodeToString: function(node){
    	    if (!this.nodeFilter(node)) {
    	        return '';
    	    }
    	    var result = '\u003Cnode';
    	    if (this.attributeFilter("id", node.id)) {
    	        result += ' id="' + node.id + '"';
    	    }
    
    //		Add all user-added attributes unless rejected by the attributeFilter.
    	    for(var key in node.attributes) {
    	        if (this.attributeFilter(key, node.attributes[key])) {
    		        result += ' ' + (this.attributeMap ? (this.attributeMap[key] || key) : key) + '="' + node.attributes[key] + '"';
    		    }
    	    }
    
    //		Add child nodes if any
    	    var children = node.childNodes;
    	    var clen = children.length;
    	    if(clen == 0){
    	        result += '/>';
    	    }else{
    	        result += '>';
    	        for(var i = 0; i < clen; i++){
    	            result += this.nodeToString(children[i]);
    	        }
    	        result += '\u003C/node>';
    	    }
    	    return result;
    	}
    
    });
    
    /**
     * @class Ext.tree.JsonTreeSerializer
     * An implementation of Ext.tree.TreeSerializer which serializes an
     * {@link Ext.tree.TreePanel} to a Json string.
     */
    Ext.tree.JsonTreeSerializer = function(tree, config){
    	Ext.tree.JsonTreeSerializer.superclass.constructor.apply(this, arguments);
    };
    
    Ext.extend(Ext.tree.JsonTreeSerializer, Ext.tree.TreeSerializer, {
    
    	/**
    	 * Returns a string of Json that represents the tree
    	 * @return {String}
    	 */
    	toString: function(){
    	      return this.nodeToString(this.getRootNode());
    	}
    
    	/**
    	 * Returns a string of Json that represents the node
    	 * @param {Object} node The node to serialize
    	 */
    	nodeToString: function(node){
    //		Exclude nodes based on caller-supplied filtering function
    	    if (!this.nodeFilter(node)) {
    	        return '';
    	    }
    	    var c = false, result = "{";
    	    if (this.attributeFilter("id", node.id)) {
    	        result += '"id":"' + node.id + '"';
    	        c = true;
    	    }
    
    //		Add all user-added attributes unless rejected by the attributeFilter.
    	    for(var key in node.attributes) {
    	        if (this.attributeFilter(key, node.attributes[key])) {
    		        if (c) result += ',';
    		        result += '"' + (this.attributeMap ? (this.attributeMap[key] || key) : key) + '":"' + node.attributes[key] + '"';
    		        c = true;
    		    }
    	    }
    	
    //		Add child nodes if any
    	    var children = node.childNodes;
    	    var clen = children.length;
    	    if(clen != 0){
    	        if (c) result += ',';
    	        result += '"children":['
    	        for(var i = 0; i < clen; i++){
    	            if (i > 0) result += ',';
    	            result += this.nodeToString(children[i]);
    	        }
    	        result += ']';
    	    }
    	    return result + "}";
    	}
    };

  3. #3
    Ext User
    Join Date
    Mar 2008
    Posts
    34

    Default

    Thank you.
    I will try to do it immediately.

  4. #4

    Default

    Hello Animal,
    Well I am very new to Ext JS and also vry much new to this object based stuff in javascript. So can you guide me how to call XML serializer so that I can get XML string.
    Right now I have two trees and and I drop things from tree 1 to tree 2 now I have another button says SAVE. Now on click of that I want to save. But On CLick Event how do I call the XML serializer is the question.
    Eagerly w8in for someones reply.

  5. #5
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    Why not experiment with it in Firebug?

    You can type in expressions, instantiate objects, call methods on them and see what they do.

    Create a serializer, and call its methods passing what those methods need.

  6. #6

    Default

    Hello Animal,
    I am tryin all sort of things in Firebug and getting hold of it better and better each time I'm using it.
    Now buddy just the couple of questions: I have one js file named two-trees.js which has been picked up from the samples provided. And there is another js file where I have added the serializer classes which you have provided.
    Also in the page I have added one simple input type button and on its click event I am trying to create a serializer [The code for on click event is been written in the head section of the file]. But now when I mention tree2 which was created in the intial js file, it says undefined. Just help me how to do this?
    I tried writing something like this in Firebug, Firebug doesnt give any error [that means if nothings right atleast not everything is wrong]
    PHP Code:
    var getTree Ext.Tree;
    getTree.getUI(tree2);
    var 
    XMLSer Ext.XmlTreeSerializer(getTree);
    alert(XMLSer.toString()); 

  7. #7
    Sencha User JeffHowden's Avatar
    Join Date
    Mar 2007
    Location
    Forest Grove, OR
    Posts
    1,038

    Default

    Just a note that if you have Firebug available, use console.log instead of alert().
    Jeff Howden
    Ext JS - Support Team Volunteer
    [email protected]

  8. #8

    Default

    But can u guide me... the code which I am tryin is it makin any sense....

  9. #9
    Sencha User
    Join Date
    May 2008
    Posts
    19

    Default

    Quote Originally Posted by Animal View Post
    Use this class to create an XML representation, and post that.
    Thanks for posting this, Animal. Just a couple little changes like adding adding a colon and changing the constructor line that defines the defaultNodeFilter. I also commented out the section that manually adds the id attribute because it was getting double-added. Now it's working great

    Code:
    /*global Ext*/
    
    /**
     * @class Ext.tree.TreeSerializer
     * A base class for implementations which provide serialization of an
     * {@link Ext.tree.TreePanel}.
     * <p>
     * Implementations must provide a toString method which returns the serialized
     * representation of the tree.
     * 
     * @constructor
     * @param {TreePanel} tree
     * @param {Object} config
     */
    Ext.tree.TreeSerializer = function(tree, config){
        if (typeof this.toString !== 'function') {
        	throw 'Ext.tree.TreeSerializer implementation does not implement toString()';
        }
    	this.tree = tree;
    
    	if (this.attributeFilter) {
    		this.attributeFilter = this.attributeFilter.createInterceptor(this.defaultAttributeFilter);
    	} else {
    		this.attributeFilter = this.defaultAttributeFilter;
    	}
    	if (this.nodeFilter) {
    		this.nodeFilter = this.nodeFilter.createInterceptor(this.defaultNodeFilter);
    	} else {
    		this.nodeFilter = this.defaultNodeFilter;
    	}
    	
    	Ext.apply(this, config);
    
    };
    
    Ext.tree.TreeSerializer.prototype = {
    
    	/*
    	 * @cfg nodeFilter {Function} (optional) A function, which when passed the node, returns true or false to include
    	 * or exclude the node.
    	 */
    	 
    	/*
    	 * @cfg attributeFilter {Function} (optional) A function, which when passed an attribute name, and an attribute value,
    	 * returns true or false to include or exclude the attribute.
    	 */
    	 
    	/*
    	 * @cfg attributeMap {Array} (Optional) An associative array mapping Node attribute names to XML attribute names.
    	 */
    
    	/* @private
    	 * Array of node attributes to ignore.
    	 */
        standardAttributes: ["expanded", "allowDrag", "allowDrop", "disabled", "icon",
        "cls", "iconCls", "href", "hrefTarget", "qtip", "singleClickExpand", "uiProvider", "allowChildren", "expandable"],
        
    
    	/** @private
    	 * Default attribute filter.
    	 * Rejects functions and standard attributes.
    	 */
    	defaultAttributeFilter: function(attName, attValue) {
    		return	(typeof attValue != 'function') &&
    				(this.standardAttributes.indexOf(attName) == -1);
    	},
    
    	/** @private
    	 * Default node filter.
    	 * Accepts all nodes.
    	 */
    	defaultNodeFilter: function(node) {
    		return true;
    	}
    };
    
    /**
     * @class Ext.tree.XmlTreeSerializer
     * An implementation of Ext.tree.TreeSerializer which serializes an
     * {@link Ext.tree.TreePanel} to an XML string.
     */
    Ext.tree.XmlTreeSerializer = function(tree, config){
    	Ext.tree.XmlTreeSerializer.superclass.constructor.apply(this, arguments);
    };
    
    Ext.extend(Ext.tree.XmlTreeSerializer, Ext.tree.TreeSerializer, {
    	/**
    	 * Returns a string of XML that represents the tree
    	 * @return {String}
    	 */
    	toString: function(){
    		return '<?xml version="1.0"?><tree>' +
    			this.nodeToString(this.tree.getRootNode()) + '</tree>';
    	},
    
    	/**
    	 * Returns a string of XML that represents the node
    	 * @param {Object} node The node to serialize
    	 * @return {String}
    	 */
    	nodeToString: function(node){
    	    if (!this.nodeFilter(node)) {
    	        return '';
    	    }
    	    var result = '<node';
    	    
    	    /**
    	     *  This doesn't appear necessary. Since the iteration below will include id, 
    	     *  this block simply includes it twice
    	     
    	    if (this.attributeFilter("id", node.id)) {
    	        result += ' id="' + node.id + '"';
    	    }
    	    ***/
    
    //		Add all user-added attributes unless rejected by the attributeFilter.
    	    for(var key in node.attributes) {
    	        if (this.attributeFilter(key, node.attributes[key])) {
    		        result += ' ' + (this.attributeMap ? (this.attributeMap[key] || key) : key) + '="' + node.attributes[key] + '"';
    		    }
    	    }
    
    //		Add child nodes if any
    	    var children = node.childNodes;
    	    var clen = children.length;
    	    if(clen == 0){
    	        result += '/>';
    	    }else{
    	        result += '>';
    	        for(var i = 0; i < clen; i++){
    	            result += this.nodeToString(children[i]);
    	        }
    	        result += '</node>';
    	    }
    	    return result;
    	}
    
    });
    
    /**
     * @class Ext.tree.JsonTreeSerializer
     * An implementation of Ext.tree.TreeSerializer which serializes an
     * {@link Ext.tree.TreePanel} to a Json string.
     */
    Ext.tree.JsonTreeSerializer = function(tree, config){
    	Ext.tree.JsonTreeSerializer.superclass.constructor.apply(this, arguments);
    };
    
    Ext.extend(Ext.tree.JsonTreeSerializer, Ext.tree.TreeSerializer, {
    
    	/**
    	 * Returns a string of Json that represents the tree
    	 * @return {String}
    	 */
    	toString: function(){
    	      return this.nodeToString(this.tree.getRootNode());
    	},
    
    	/**
    	 * Returns a string of Json that represents the node
    	 * @param {Object} node The node to serialize
    	 */
    	nodeToString: function(node){
    //		Exclude nodes based on caller-supplied filtering function
    	    if (!this.nodeFilter(node)) {
    	        return '';
    	    }
    	    var c = false, result = "{";
    	    /** don't double-include id
    	    
    	    if (this.attributeFilter("id", node.id)) {
    	        result += '"id":"' + node.id + '"';
    	        c = true;
    	    }
    	    
    	    */
    
    //		Add all user-added attributes unless rejected by the attributeFilter.
    	    for(var key in node.attributes) {
    	        if (this.attributeFilter(key, node.attributes[key])) {
    		        if (c) { result += ','; }
    		        result += '"' + (this.attributeMap ? (this.attributeMap[key] || key) : key) + '":"' + node.attributes[key] + '"';
    		        c = true;
    		    }
    	    }
    	
    //		Add child nodes if any
    	    var children = node.childNodes;
    	    var clen = children.length;
    	    if(clen != 0){
    	        if (c) {result += ',';}
    	        result += '"children":[';
    	        for(var i = 0; i < clen; i++){
    	            if (i > 0) {result += ',';}
    	            result += this.nodeToString(children[i]);
    	        }
    	        result += ']';
    	    }
    	    return result + "}";
    	}
    });

    swapnilsarwe: That code you posted indicates to me you might have some real problems understanding javascript itself, not to mention the ExtJS framework. I think you want something more like this, assuming tree2 is already defined somewhere.

    Code:
    var XMLSer = Ext.tree.XmlTreeSerializer(tree2);
    alert(XMLSer.toString());

  10. #10
    Sencha User Animal's Avatar
    Join Date
    Mar 2007
    Location
    Bédoin/Nottingham
    Posts
    30,890

    Default

    I'm not surprised there could be a few mistakes in that. I probably fixed them in my app without updating the code in the original post.

    I've been hoping that Jack would use this code (or maybe improve it a lot then use it!) and add an XMLTreeSerializer to the core of Ext.

    IMHO, Trees with enabled drag/drop are input fields which need a method of serialization for submission to the server.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •