1. #11
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,135
    Vote Rating
    322
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    It can be a problem particular to my page... A conflicting css... Do you have an idea?

  2. #12
    Ext User
    Join Date
    Jun 2008
    Posts
    9
    Vote Rating
    0
    alex-t.de is on a distinguished road

      0  

    Default


    Quote Originally Posted by jsakalos View Post
    I don't care too much about MU. For example, if user tries to move a branch to a node that has been deleted by another user he/she gets error message. Then he can reload the tree.
    Hi!

    I'm also working on a LiveTree, as I'd call it. When I was planing the application wich use this tree, I realised pretty early that you have to look after using by multiple users. I think every kind of application should do so, when more than one user at a time is able to access the UI which allows to change common data.

    Imagine you don't care about this problem, one worst case could be: You spend a lot of time by editing the content of an item from the tree. When you try to save your changes, an error message appears "Sorry, but the item you were editing no longer exists." Another user deleted your item just a minute before.

    Another problem could be when you and another user are doing a lot of small changes (like renaming of items) at the same time. Then you could get a lot of error messages, and that would be confusing or at least annoying.


    Some of the tricky problems about LiveTrees are:
    • Check every x seconds for changes on server side. If there are some changes do an UI update.
    • When you are editing an item, then this (and the parents) should be blocked from deleting or moving by other users. This block should be done every z seconds, so the server can detect your disconnection from the network.

    My LiveTree loads data on-demand from a RoR-backend. The update algo should look like this:
    1. Every x seconds call the update controller on the server side and send the ids of items you already loaded in the tree. The controller should check for all kinds of updates and note the all parent_ids of the modified items. Some optimization is needed to prevent from double updates.
    2. The UI controller on the client should say all the items with id equals parent_id that they have to update their children items.

    At the moment I'm working on a prototype of this. I hope, that the user experience will be ok.

    Let me say something about the motivation behind this solution. First of all it's quite hard to implement all kind of UI update operations like 'removing a subtree', 'updating item attributes', 'adding a subtree' and 'adding a sibling item'. I've decided to go the lazy way because of some reasons, for instance pressure of time. So I try to parent item and reassure the selected item is visible. One problem is the delay of the lazy loading tree and especially the animation, wich I hope to be able to disable.

    Think about these ideas. Maybe it is not to difficult to implement something like this. But every error message that can be prevented is soft of a bug. Reduce messages like "This item doesn't exist any longer", user don't like them.

  3. #13
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,135
    Vote Rating
    322
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Well, we host 1000+ clients (each has his own trees) so only bandwidth overhead connected with checking/locking is not worth the effort to handle the situation that can happen very, very rarely.

    Of course, YMMV.

    Post an example when you're done with it anyway.

  4. #14
    Ext User
    Join Date
    Jun 2008
    Posts
    9
    Vote Rating
    0
    alex-t.de is on a distinguished road

      0  

    Default


    Quote Originally Posted by jsakalos View Post
    Well, we host 1000+ clients (each has his own trees) ...
    If the users don't share one tree with each other, but every one has its own, then there is no multi user problem.

    In my avg cases there are 10+ users working on the tree structure at the same time. So I really need a more conflict-less situation.


    Quote Originally Posted by jsakalos View Post
    Post an example when you're done with it anyway.
    I'll do so, but that can take some weeks. I've make a ToDo for a post.

  5. #15
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,135
    Vote Rating
    322
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Just to clarify: 1 client = one company = many users, sorry for not being percise.

  6. #16
    Sencha User
    Join Date
    Dec 2008
    Location
    Mainz
    Posts
    241
    Vote Rating
    1
    crp_spaeth is on a distinguished road

      0  

    Post LiveTree

    LiveTree


    Hey Alex,

    I would not extend the Tree it self since the Updating thing should be placed into the TreeLoader...

    I wrote a small "SyncableTreeLoader" that i think does exactly what you need!
    You can use it as you use the normal Treeloader. If you want to ask the tree for an update just call the requestData with a third parameter (update) true.

    I think the Code is selfexplaining ...



    PHP Code:
    Ext.ns('Ext''Ext.ux''Ext.ux.tree');

    /**
     
     * @class Ext.ux.tree.SyncableTreeLoader
     * @extends Ext.tree.TreeLoader
     * 
     * 
     * A SyncableTreeLoader provides the same functionality as its Baseclass (Ext.tree.Treeloader) plus the 
     * possibility of lazy updating an existing Structure of TreeNodes from a specified Url.
     * 
     * The response must be a JavaScript Object definition whose Members are (by default) "deleted", "updated", "added"
     * 
     * "deleted" contains a simple Javascript Array definition of the TreeNode-Id that should be deleted
     * 
     * "updated" contains a JavasScript Array defintion contaioning the Object definition of the updated 
     * TreeNodes with its new attribute properties
     * 
     * "added" contains a JavaScript Array of definition containing the Object definition of the treeNodes 
     * that should get Added to the Tree. Cause the Tree needs to know where to insert/append the TreeNode, 
     * the definition of the Node needs to contain an Attribute with the Id of its Parentnode "Parentnode" 
     * and Optional its Presilbing. 
     * 
     * A possible Response looks like this:

     * <pre><code>
    {
        "deleted" : ['nodeId123'],
        "updated" : [{
            "leaf" : false,
            "id" : "nodeId342",
            "children" : [{
                    "leaf" : false,
                    "id" : "node12314",
                    "children" : [],
                    "attr" : {
                        "preSilbing_id" : null,
                        "parent_id" : "nodeId342",
                        "Dokumente"    : "0",
                        "leaf" : false,
                        "text" : "childs text"
                    }
                }
            ],
            "attr" : {
                "parent_id" : "parentNodeId",
                "preSilbing_id" : null,
                "text" : "Node Text",
                "leaf" : false
            }
        }],
        "added" : [{
            "leaf" : false,
            "id" : "nodeId555",
            "children" : [{
                    "leaf" : false,
                    "id" : "node12314",
                    "children" : [],
                    "attr" : {
                        "preSilbing_id" : null,
                        "parent_id" : "nodeId342",
                        "Dokumente"    : "0",
                        "leaf" : false,
                        "text" : "childs text"
                    }
                }
            ],
            "attr" : {
                "parent_id" : "RootNodeID",
                "preSilbing_id" : "FirstChildsId",
                "text" : "Node Text",
                "leaf" : false
            }]
    }
    </code></pre>
     * @author Martin Spaeth
     * @copyright (c) 2008, by Martin Spaeth
     */
    Ext.ux.tree.SyncableTreeLoader Ext.extendExt.tree.TreeLoader, {
       
        
    /**
         * @cfg {string} updateParamName  
         * Parametername for the requesttype
         */
        
    updateParamName'request',
        
        
    /**
         * @cfg {string} updateParamValue  
         * value of the Parameter to show the server that this is an updaterequest
         */
        
    updateParamValue'update',
        
        
    /**
         * @cfg {String} updatedName 
         * Name of the array containing the nodes that should get updateted
         */
        
    updatedName'updated',
        
        
    /** 
         * @cfg {String} deletedName 
         * Name of the array containing the Id's of the nodes that should get deleted
         */
        
    deletedName'deleted',
        
        
    /** 
         * @cfg {String} addedName 
         * Name of the array containing the nodes that should get added
         */
        
    addedName'added',
        
        
    /**
         * @cfg {String} parentIDAttr 
         * name of the attribute containing the parentId of a node
         */
        
    parentIDAttr'parentIdAttr',
        
    /**
         * @cfg {String} preSilbAttr 
         * name of the attribute containing the preSilbingId of a node 
         */
        
    preSilbAttr'preSilbingIdAttr',
        
        
    clearOnLoad true,
        
        
    /**
        * @cfg tree {Ext.tree.Tree} the Tree this Treeloader is instantiated for
        */
        
    treeundefined,
        
        
    /**
         * Create a String containing all needed Request Parameters
         * @param {Ext.tree.TreeNode} node
         * @param {boolean} update
         * @return {String} Parameterstring for a Request z.b. node=432&updete=true
         */
        
    getParams: function(nodeupdate){
            var 
    buf = [], bp this.baseParams;
            for(var 
    key in bp){
                if(
    typeof bp[key] != "function"){
                    
    buf.push(encodeURIComponent(key), "="encodeURIComponent(bp[key]), "&");
                }
            }
            
    buf.push("node="encodeURIComponent(node.id));
            if(
    update){
                
    // adding the updateparameter
                
    buf.push("&"+this.updateParamName+"="encodeURIComponent(this.updateParamValue));
            }
            return 
    buf.join("");
        },

        
        
    /**
         * RequestData Function with the possibility to fire an updaterequest
         * @param {Ext.tree.TreeNode} node the Node for wicht the data should be requested
         * @param {function} callback a callbackfunction
         * @param {boolean} update is it an updaterequest
         */
        
    requestData : function(nodecallbackupdate){
            if(
    this.fireEvent("beforeload"thisnodecallback) !== false){
                
    this.transId Ext.Ajax.request({
                    
    updateupdate,
                    
    method:this.requestMethod,
                    
    urlthis.dataUrl || this.url,
                    
    successthis.handleResponse,
                    
    failurethis.handleFailure,
                    
    scopethis,
                    
    argument: {callbackcallbacknodenode},
                    
    paramsthis.getParams(nodeupdate)
                });
            }else{
                
    // if the load is cancelled, make sure we notify
                // the node that we are done
                
    if(typeof callback == "function"){
                    
    callback();
                }
            }
        },

        
    /**
         * the function that processes the Response an handles all the Update logic
         * @param {Object} response from the Server
         * @param {Ext.tree.TreeNode} node The Node the Response is for
         * @param {function} callback
         */
        
    processResponse : function(responsenodecallback){
        
            var 
    json response.responseText;
            var 
    update response.options.update;
            var 
    tree node.getOwnerTree();
            
            try {
                var 
    = eval("("+json+")");
                
    // is the response part of an update request?
                
    if(update){
                    
                    
    // delete Nodes 
                    
    var del o[this.deletedName];
                    if(
    del && del.length){
                        for(var 
    0del.length ii++){
                            var 
    delNodeId del[i];
                            
    tree.getNodeById(delNodeId).remove();
                        }
                    }
                    
                    
    // Add all Nodes from the added Array Responsed by the server
                    
    var added o[this.addedName];
                    if(
    added && added.length){
                        for(var 
    i1 0added.length i1i1++){
                            var 
    addedNode added[i1];
                            
                            
    /**
                             * @type Ext.tree.TreeNode
                             */
                            
    var parent tree.getNodeById(addedNode.attr[this.parentIDAttr]);
                            var 
    preSilbing tree.getNodeById(addedNode.attr[this.preSilbAttr]);
                            
                            
    parent.beginUpdate();
                            
    // Append the Node to the Parent or Insert it after the presilbing. 
                            
    if(!preSilbing){
                                
    parent.appendChild(this.createNode(addedNode));    
                            } else {
                                
    parent.insertBefore(this.createNode(addedNode), preSilbing.nextSibling);
                            }
                            
                            
    parent.endUpdate();
                        }
                    }
                    
                    
    // Update all the nodes the Update array contains
                    
    var updated o[this.updatedName];
                    if(
    updated && updated.length){
                        for(var 
    i2 0updated.length i2i2++){
                            var 
    updatedNode updated[i2];
                            
                            
    /**
                             * @type Ext.tree.TreeNode 
                             */
                            
    var toUpdate tree.getNodeById(updatedNode.id);
                            
                            
    toUpdate.beginUpdate();
                            
    // toUpdate.updateNode(updatedNode);
                            
                            // update should only handle the attributes of a node nor the children
                            
    if(updateNode.children) {
                                
    delete updateNode.children;
                            }
                            
                            
    Ext.apply(toUpdateupdateNode);
                            
                            
                            
    // update the text of the node
                            
    if(updateNode.text){
                                
    toUpdate.setText(updateNode.text);
                            } 
                            
                            
    // replace the Icon
                            
    if(updateNode.iconCls){
                                
    Ext.fly(toUpdate.getUI().getIconEl()).replaceClass(oldIconClsupdateNode.iconCls);
                                
    toUpdate.iconCls updateNode.iconCls;    
                            }
                            
                            
    // replace the quicktip 
                            
    if(updateNode.qtip) {
                                var 
    ui toUpdate.getUI();
                                if(
    ui.textNode.setAttributeNS){
                                       
    ui.textNode.setAttributeNS("ext""qtip"updateNode.qtip);
                                       if(
    updateNode.qtipTitle){
                                           
    ui.textNode.setAttributeNS("ext""qtitle"updateNode.qtipTitle);
                                       }
                                   }else{
                                       
    ui.textNode.setAttribute("ext:qtip"updateNode.qtip);
                                       if(
    updateNode.qtipTitle){
                                           
    ui.textNode.setAttribute("ext:qtitle"updateNode.qtipTitle);
                                       }
                                   } 
                            }
                            
                            
    toUpdate.endUpdate();
                        }
                    }
                    
                    if(
    typeof callback == "function"){
                        
    callback(thisnode);
                    }
                }
                else {
                    
    node.beginUpdate();
                    for(var 
    0len o.lengthleni++){
                        var 
    this.createNode(o[i]);
                        if(
    n){
                            
    node.appendChild(n);
                        }
                    }
                    
    node.endUpdate();
                    if(
    typeof callback == "function"){
                        
    callback(thisnode);
                    }
                }
                
            }catch(
    e){
                
    this.handleFailure(response);
            }
        }  
    }); 

  7. #17
    Sencha User
    Join Date
    Dec 2008
    Location
    Mainz
    Posts
    241
    Vote Rating
    1
    crp_spaeth is on a distinguished road

      0  

    Default new Thread

    new Thread


    I just pasted my extension into a new Thread

    http://extjs.com/forum/showthread.ph...378#post285378

  8. #18
    Ext User
    Join Date
    Feb 2009
    Posts
    2
    Vote Rating
    0
    Simon1101 is on a distinguished road

      0  

    Default php classes

    php classes


    Hi jsakalos,

    i'd like to have a look at the php-classes required by process-request.php. Is that possible?

    btw, very nice remote-tree ;-)

    Simon

  9. #19
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,135
    Vote Rating
    322
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Sorry, server side is proprietary.

  10. #20
    Ext User
    Join Date
    Feb 2009
    Posts
    2
    Vote Rating
    0
    Simon1101 is on a distinguished road

      0  

    Default No Problem

    No Problem


    no problem, thanks anyway!

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar