dijit/tree/ForestStoreModel.js

  • Provides:

    • dijit.tree.ForestStoreModel
  • dijit.tree.ForestStoreModel

    • type
      Function
    • chains:
      • dijit.tree.TreeStoreModel: (prototype)
      • dijit.tree.TreeStoreModel: (call)
    • example
      
      	{type:'continent'}
    • parameters:
      • params: (typeof )
    • source: [view]
      define("dijit/tree/ForestStoreModel", ["dojo", "dijit", "dijit/tree/TreeStoreModel"], function(dojo, dijit) {


      dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
       // summary:
       //  Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
       //  a.k.a. a store that has multiple "top level" items.
       //
       // description
       //  Use this class to wrap a dojo.data store, making all the items matching the specified query
       //  appear as children of a fabricated "root item". If no query is specified then all the
       //  items returned by fetch() on the underlying store become children of the root item.
       //  This class allows dijit.Tree to assume a single root item, even if the store doesn't have one.
       //
       //  When using this class the developer must override a number of methods according to their app and
       //  data, including:
       //   - onNewRootItem
       //   - onAddToRoot
       //   - onLeaveRoot
       //   - onNewItem
       //   - onSetItem


       // Parameters to constructor


       // rootId: String
       //  ID of fabricated root item
       rootId: "$root$",


       // rootLabel: String
       //  Label of fabricated root item
       rootLabel: "ROOT",


       // query: String
       //  Specifies the set of children of the root item.
       // example:
       // | {type:'continent'}
       query: null,


       // End of parameters to constructor


       constructor: function(params){
        // summary:
        //  Sets up variables, etc.
        // tags:
        //  private


        // Make dummy root item
        this.root = {
         store: this,
         root: true,
         id: params.rootId,
         label: params.rootLabel,
         children: params.rootChildren // optional param
        };
    • summary
      Sets up variables, etc.
  • dijit.tree.ForestStoreModel.rootId

    • summary
  • dijit.tree.ForestStoreModel.rootLabel

    • type
      String
    • summary
      Label of fabricated root item
  • dijit.tree.ForestStoreModel.query

    • type
      String
    • summary
      Specifies the set of children of the root item.
  • dijit.tree.ForestStoreModel.mayHaveChildren

    • type
      Function
    • parameters:
      • item: (typeof dojo.data.Item)
    • source: [view]
        return item === this.root || this.inherited(arguments);
    • summary
      Tells if an item has or may have children.  Implementing logic here
      avoids showing +/- expando icon for nodes that we know don't have children.
      (For efficiency reasons we may not want to check if an element actually
      has children until user clicks the expando node)
    • tags:
  • dijit.tree.ForestStoreModel.getChildren

    • type
      Function
    • parameters:
      • parentItem: (typeof dojo.data.Item)
      • callback: (typeof function(items))
      • onError: (typeof function)
    • source: [view]
        if(parentItem === this.root){
         if(this.root.children){
          // already loaded, just return
          callback(this.root.children);
         }else{
          this.store.fetch({
           query: this.query,
           onComplete: dojo.hitch(this, function(items){
            this.root.children = items;
            callback(items);
           }),
           onError: onError
          });
         }
        }else{
         this.inherited(arguments);
        }
    • summary
      Calls onComplete() with array of child items of given parent item, all loaded.
  • dijit.tree.ForestStoreModel.isItem

    • type
      Function
    • parameters:
      • something: (typeof anything)
    • source: [view]
        return (something === this.root) ? true : this.inherited(arguments);
    • summary
  • dijit.tree.ForestStoreModel.fetchItemByIdentity

    • type
      Function
    • parameters:
      • keywordArgs: (typeof object)
    • source: [view]
        if(keywordArgs.identity == this.root.id){
         var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
         if(keywordArgs.onItem){
          keywordArgs.onItem.call(scope, this.root);
         }
        }else{
         this.inherited(arguments);
        }
    • chains:
      • keywordArgs.onItem: (call)
    • summary
  • dijit.tree.ForestStoreModel.getIdentity

    • type
      Function
    • parameters:
      • item: (typeof item)
    • source: [view]
        return (item === this.root) ? this.root.id : this.inherited(arguments);
    • summary
  • dijit.tree.ForestStoreModel.getLabel

    • type
      Function
    • parameters:
      • item: (typeof item)
    • source: [view]
        return (item === this.root) ? this.root.label : this.inherited(arguments);
    • summary
  • dijit.tree.ForestStoreModel.newItem

    • type
      Function
    • parameters:
      • args: (typeof dojo.dnd.Item)
      • parent: (typeof Item)
      • insertIndex: (typeof int)
    • source: [view]
        if(parent === this.root){
         this.onNewRootItem(args);
         return this.store.newItem(args);
        }else{
         return this.inherited(arguments);
        }
    • summary
      Creates a new item.   See dojo.data.api.Write for details on args.
      Used in drag & drop when item from external source dropped onto tree.
  • dijit.tree.ForestStoreModel.onNewRootItem

    • type
      Function
    • parameters:
      • args: (typeof )
    • source: [view]
        // summary:
        //  User can override this method to modify a new element that's being
        //  added to the root of the tree, for example to add a flag like root=true
    • summary
      User can override this method to modify a new element that's being
      added to the root of the tree, for example to add a flag like root=true
  • dijit.tree.ForestStoreModel.pasteItem

    • type
      Function
    • parameters:
      • childItem: (typeof Item)
      • oldParentItem: (typeof Item)
      • newParentItem: (typeof Item)
      • bCopy: (typeof Boolean)
      • insertIndex: (typeof int)
    • source: [view]
        if(oldParentItem === this.root){
         if(!bCopy){
          // It's onLeaveRoot()'s responsibility to modify the item so it no longer matches
          // this.query... thus triggering an onChildrenChange() event to notify the Tree
          // that this element is no longer a child of the root node
          this.onLeaveRoot(childItem);
         }
        }
        dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
         oldParentItem === this.root ? null : oldParentItem,
         newParentItem === this.root ? null : newParentItem,
         bCopy,
         insertIndex
        );
        if(newParentItem === this.root){
         // It's onAddToRoot()'s responsibility to modify the item so it matches
         // this.query... thus triggering an onChildrenChange() event to notify the Tree
         // that this element is now a child of the root node
         this.onAddToRoot(childItem);
        }
    • summary
      Move or copy an item from one parent item to another.
      Used in drag & drop
    • chains:
      • dijit.tree.TreeStoreModel.prototype.pasteItem: (call)
  • dijit.tree.ForestStoreModel.onAddToRoot

    • type
      Function
    • parameters:
      • item: (typeof item)
    • source: [view]
        console.log(this, ": item ", item, " added to root");
    • summary
      Called when item added to root of tree; user must override this method
      to modify the item so that it matches the query for top level items
    • tags:
    • example
      
      	store.setValue(item, "root", true);
  • dijit.tree.ForestStoreModel.onLeaveRoot

    • type
      Function
    • parameters:
      • item: (typeof item)
    • source: [view]
        console.log(this, ": item ", item, " removed from root");
    • summary
      Called when item removed from root of tree; user must override this method
      to modify the item so it doesn't match the query for top level items
    • tags:
    • example
      
      	store.unsetAttribute(item, "root");
  • dijit.tree.ForestStoreModel._requeryTop

    • type
      Function
    • source: [view]
      define("dijit/tree/ForestStoreModel", ["dojo", "dijit", "dijit/tree/TreeStoreModel"], function(dojo, dijit) {


      dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
       // summary:
       //  Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
       //  a.k.a. a store that has multiple "top level" items.
       //
       // description
       //  Use this class to wrap a dojo.data store, making all the items matching the specified query
       //  appear as children of a fabricated "root item". If no query is specified then all the
       //  items returned by fetch() on the underlying store become children of the root item.
       //  This class allows dijit.Tree to assume a single root item, even if the store doesn't have one.
       //
       //  When using this class the developer must override a number of methods according to their app and
       //  data, including:
       //   - onNewRootItem
       //   - onAddToRoot
       //   - onLeaveRoot
       //   - onNewItem
       //   - onSetItem


       // Parameters to constructor


       // rootId: String
       //  ID of fabricated root item
       rootId: "$root$",


       // rootLabel: String
       //  Label of fabricated root item
       rootLabel: "ROOT",


       // query: String
       //  Specifies the set of children of the root item.
       // example:
       // | {type:'continent'}
       query: null,


       // End of parameters to constructor


       constructor: function(params){
        // summary:
        //  Sets up variables, etc.
        // tags:
        //  private


        // Make dummy root item
        this.root = {
         store: this,
         root: true,
         id: params.rootId,
         label: params.rootLabel,
         children: params.rootChildren // optional param
        };
       },


       // =======================================================================
       // Methods for traversing hierarchy


       mayHaveChildren: function(/*dojo.data.Item*/ item){
        // summary:
        //  Tells if an item has or may have children. Implementing logic here
        //  avoids showing +/- expando icon for nodes that we know don't have children.
        //  (For efficiency reasons we may not want to check if an element actually
        //  has children until user clicks the expando node)
        // tags:
        //  extension
        return item === this.root || this.inherited(arguments);
       },


       getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ callback, /*function*/ onError){
        // summary:
        //   Calls onComplete() with array of child items of given parent item, all loaded.
        if(parentItem === this.root){
         if(this.root.children){
          // already loaded, just return
          callback(this.root.children);
         }else{
          this.store.fetch({
           query: this.query,
           onComplete: dojo.hitch(this, function(items){
            this.root.children = items;
            callback(items);
           }),
           onError: onError
          });
         }
        }else{
         this.inherited(arguments);
        }
       },


       // =======================================================================
       // Inspecting items


       isItem: function(/* anything */ something){
        return (something === this.root) ? true : this.inherited(arguments);
       },


       fetchItemByIdentity: function(/* object */ keywordArgs){
        if(keywordArgs.identity == this.root.id){
         var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
         if(keywordArgs.onItem){
          keywordArgs.onItem.call(scope, this.root);
         }
        }else{
         this.inherited(arguments);
        }
       },


       getIdentity: function(/* item */ item){
        return (item === this.root) ? this.root.id : this.inherited(arguments);
       },


       getLabel: function(/* item */ item){
        return (item === this.root) ? this.root.label : this.inherited(arguments);
       },


       // =======================================================================
       // Write interface


       newItem: function(/* dojo.dnd.Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
        // summary:
        //  Creates a new item. See dojo.data.api.Write for details on args.
        //  Used in drag & drop when item from external source dropped onto tree.
        if(parent === this.root){
         this.onNewRootItem(args);
         return this.store.newItem(args);
        }else{
         return this.inherited(arguments);
        }
       },


       onNewRootItem: function(args){
        // summary:
        //  User can override this method to modify a new element that's being
        //  added to the root of the tree, for example to add a flag like root=true
       },


       pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
        // summary:
        //  Move or copy an item from one parent item to another.
        //  Used in drag & drop
        if(oldParentItem === this.root){
         if(!bCopy){
          // It's onLeaveRoot()'s responsibility to modify the item so it no longer matches
          // this.query... thus triggering an onChildrenChange() event to notify the Tree
          // that this element is no longer a child of the root node
          this.onLeaveRoot(childItem);
         }
        }
        dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
         oldParentItem === this.root ? null : oldParentItem,
         newParentItem === this.root ? null : newParentItem,
         bCopy,
         insertIndex
        );
        if(newParentItem === this.root){
         // It's onAddToRoot()'s responsibility to modify the item so it matches
         // this.query... thus triggering an onChildrenChange() event to notify the Tree
         // that this element is now a child of the root node
         this.onAddToRoot(childItem);
        }
       },


       // =======================================================================
       // Handling for top level children


       onAddToRoot: function(/* item */ item){
        // summary:
        //  Called when item added to root of tree; user must override this method
        //  to modify the item so that it matches the query for top level items
        // example:
        // | store.setValue(item, "root", true);
        // tags:
        //  extension
        console.log(this, ": item ", item, " added to root");
       },


       onLeaveRoot: function(/* item */ item){
        // summary:
        //  Called when item removed from root of tree; user must override this method
        //  to modify the item so it doesn't match the query for top level items
        // example:
        //  | store.unsetAttribute(item, "root");
        // tags:
        //  extension
        console.log(this, ": item ", item, " removed from root");
       },


       // =======================================================================
       // Events from data store


       _requeryTop: function(){
        // reruns the query for the children of the root node,
        // sending out an onSet notification if those children have changed
        var oldChildren = this.root.children || [];
        this.store.fetch({
         query: this.query,
         onComplete: dojo.hitch(this, function(newChildren){
          this.root.children = newChildren;


          // If the list of children or the order of children has changed...
          if(oldChildren.length != newChildren.length ||
           dojo.some(oldChildren, function(item, idx){ return newChildren[idx] != item;})){
           this.onChildrenChange(this.root, newChildren);
          }
         })
        });
    • summary
  • dijit.tree.ForestStoreModel.onNewItem

    • type
      Function
    • parameters:
      • item: (typeof dojo.data.Item)
      • parentInfo: (typeof Object)
    • source: [view]
        this._requeryTop();


        this.inherited(arguments);
    • summary
      Handler for when new items appear in the store.  Developers should override this
      method to be more efficient based on their app/data.
    • description
      Note that the default implementation requeries the top level items every time
      a new item is created, since any new item could be a top level item (even in
      addition to being a child of another item, since items can have multiple parents).
      
      If developers can detect which items are possible top level items (based on the item and the
      parentInfo parameters), they should override this method to only call _requeryTop() for top
      level items.  Often all top level items have parentInfo==null, but
      that will depend on which store you use and what your data is like.
    • tags:
  • dijit.tree.ForestStoreModel.onDeleteItem

    • type
      Function
    • parameters:
      • item: (typeof Object)
    • source: [view]
      define("dijit/tree/ForestStoreModel", ["dojo", "dijit", "dijit/tree/TreeStoreModel"], function(dojo, dijit) {


      dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
       // summary:
       //  Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
       //  a.k.a. a store that has multiple "top level" items.
       //
       // description
       //  Use this class to wrap a dojo.data store, making all the items matching the specified query
       //  appear as children of a fabricated "root item". If no query is specified then all the
       //  items returned by fetch() on the underlying store become children of the root item.
       //  This class allows dijit.Tree to assume a single root item, even if the store doesn't have one.
       //
       //  When using this class the developer must override a number of methods according to their app and
       //  data, including:
       //   - onNewRootItem
       //   - onAddToRoot
       //   - onLeaveRoot
       //   - onNewItem
       //   - onSetItem


       // Parameters to constructor


       // rootId: String
       //  ID of fabricated root item
       rootId: "$root$",


       // rootLabel: String
       //  Label of fabricated root item
       rootLabel: "ROOT",


       // query: String
       //  Specifies the set of children of the root item.
       // example:
       // | {type:'continent'}
       query: null,


       // End of parameters to constructor


       constructor: function(params){
        // summary:
        //  Sets up variables, etc.
        // tags:
        //  private


        // Make dummy root item
        this.root = {
         store: this,
         root: true,
         id: params.rootId,
         label: params.rootLabel,
         children: params.rootChildren // optional param
        };
       },


       // =======================================================================
       // Methods for traversing hierarchy


       mayHaveChildren: function(/*dojo.data.Item*/ item){
        // summary:
        //  Tells if an item has or may have children. Implementing logic here
        //  avoids showing +/- expando icon for nodes that we know don't have children.
        //  (For efficiency reasons we may not want to check if an element actually
        //  has children until user clicks the expando node)
        // tags:
        //  extension
        return item === this.root || this.inherited(arguments);
       },


       getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ callback, /*function*/ onError){
        // summary:
        //   Calls onComplete() with array of child items of given parent item, all loaded.
        if(parentItem === this.root){
         if(this.root.children){
          // already loaded, just return
          callback(this.root.children);
         }else{
          this.store.fetch({
           query: this.query,
           onComplete: dojo.hitch(this, function(items){
            this.root.children = items;
            callback(items);
           }),
           onError: onError
          });
         }
        }else{
         this.inherited(arguments);
        }
       },


       // =======================================================================
       // Inspecting items


       isItem: function(/* anything */ something){
        return (something === this.root) ? true : this.inherited(arguments);
       },


       fetchItemByIdentity: function(/* object */ keywordArgs){
        if(keywordArgs.identity == this.root.id){
         var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
         if(keywordArgs.onItem){
          keywordArgs.onItem.call(scope, this.root);
         }
        }else{
         this.inherited(arguments);
        }
       },


       getIdentity: function(/* item */ item){
        return (item === this.root) ? this.root.id : this.inherited(arguments);
       },


       getLabel: function(/* item */ item){
        return (item === this.root) ? this.root.label : this.inherited(arguments);
       },


       // =======================================================================
       // Write interface


       newItem: function(/* dojo.dnd.Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
        // summary:
        //  Creates a new item. See dojo.data.api.Write for details on args.
        //  Used in drag & drop when item from external source dropped onto tree.
        if(parent === this.root){
         this.onNewRootItem(args);
         return this.store.newItem(args);
        }else{
         return this.inherited(arguments);
        }
       },


       onNewRootItem: function(args){
        // summary:
        //  User can override this method to modify a new element that's being
        //  added to the root of the tree, for example to add a flag like root=true
       },


       pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem, /*Boolean*/ bCopy, /*int?*/ insertIndex){
        // summary:
        //  Move or copy an item from one parent item to another.
        //  Used in drag & drop
        if(oldParentItem === this.root){
         if(!bCopy){
          // It's onLeaveRoot()'s responsibility to modify the item so it no longer matches
          // this.query... thus triggering an onChildrenChange() event to notify the Tree
          // that this element is no longer a child of the root node
          this.onLeaveRoot(childItem);
         }
        }
        dijit.tree.TreeStoreModel.prototype.pasteItem.call(this, childItem,
         oldParentItem === this.root ? null : oldParentItem,
         newParentItem === this.root ? null : newParentItem,
         bCopy,
         insertIndex
        );
        if(newParentItem === this.root){
         // It's onAddToRoot()'s responsibility to modify the item so it matches
         // this.query... thus triggering an onChildrenChange() event to notify the Tree
         // that this element is now a child of the root node
         this.onAddToRoot(childItem);
        }
       },


       // =======================================================================
       // Handling for top level children


       onAddToRoot: function(/* item */ item){
        // summary:
        //  Called when item added to root of tree; user must override this method
        //  to modify the item so that it matches the query for top level items
        // example:
        // | store.setValue(item, "root", true);
        // tags:
        //  extension
        console.log(this, ": item ", item, " added to root");
       },


       onLeaveRoot: function(/* item */ item){
        // summary:
        //  Called when item removed from root of tree; user must override this method
        //  to modify the item so it doesn't match the query for top level items
        // example:
        //  | store.unsetAttribute(item, "root");
        // tags:
        //  extension
        console.log(this, ": item ", item, " removed from root");
       },


       // =======================================================================
       // Events from data store


       _requeryTop: function(){
        // reruns the query for the children of the root node,
        // sending out an onSet notification if those children have changed
        var oldChildren = this.root.children || [];
        this.store.fetch({
         query: this.query,
         onComplete: dojo.hitch(this, function(newChildren){
          this.root.children = newChildren;


          // If the list of children or the order of children has changed...
          if(oldChildren.length != newChildren.length ||
           dojo.some(oldChildren, function(item, idx){ return newChildren[idx] != item;})){
           this.onChildrenChange(this.root, newChildren);
          }
         })
        });
       },


       onNewItem: function(/* dojo.data.Item */ item, /* Object */ parentInfo){
        // summary:
        //  Handler for when new items appear in the store. Developers should override this
        //  method to be more efficient based on their app/data.
        // description:
        //  Note that the default implementation requeries the top level items every time
        //  a new item is created, since any new item could be a top level item (even in
        //  addition to being a child of another item, since items can have multiple parents).
        //
        //  If developers can detect which items are possible top level items (based on the item and the
        //  parentInfo parameters), they should override this method to only call _requeryTop() for top
        //  level items. Often all top level items have parentInfo==null, but
        //  that will depend on which store you use and what your data is like.
        // tags:
        //  extension
        this._requeryTop();


        this.inherited(arguments);
       },


       onDeleteItem: function(/*Object*/ item){
        // summary:
        //  Handler for delete notifications from underlying store


        // check if this was a child of root, and if so send notification that root's children
        // have changed
        if(dojo.indexOf(this.root.children, item) != -1){
         this._requeryTop();
        }


        this.inherited(arguments);
    • summary
  • dijit.tree.ForestStoreModel.onSetItem

    • type
      Function
    • parameters:
      • item: (typeof item)
      • attribute: (typeof attribute-name-string)
      • oldValue: (typeof object | array)
      • newValue: (typeof object | array)
    • source: [view]
        this._requeryTop();
        this.inherited(arguments);
    • summary
      Updates the tree view according to changes to an item in the data store.
      Developers should override this method to be more efficient based on their app/data.
    • description
      Handles updates to an item's children by calling onChildrenChange(), and
      other updates to an item by calling onChange().
      
      Also, any change to any item re-executes the query for the tree's top-level items,
      since this modified item may have started/stopped matching the query for top level items.
      
      If possible, developers should override this function to only call _requeryTop() when
      the change to the item has caused it to stop/start being a top level item in the tree.
    • tags:
  • dijit.tree.ForestStoreModel.root.children

    • summary
  • dijit.tree.ForestStoreModel.root

    • summary
  • dijit.tree

    • type
      Object
    • summary
  • dijit

    • type
      Object
    • summary