LP#1350371 PO name on create w/ dupe detect
[working/Evergreen.git] / Open-ILS / web / js / dojo / openils / widget / FilteringTreeSelect.js
1 /* EXAMPLES:
2
3 <input jsId='ftree' dojoType="openils.widget.FilteringTreeSelect" searchAttr='shortname' labelAttr='shortname' tree='myTree'/>
4
5 --- OR --
6
7 var tree = new openils.widget.FilteringTreeSelect(null, parentDiv);
8 tree.searchAttr = 'shortname';
9 tree.labelAttr = 'shortname';
10 tree.parentField = 'parent_ou';
11 tree1.tree = fieldmapper.aou.globalOrgTree;
12 tree1.startup();
13
14 */
15
16 if(!dojo._hasResource["openils.widget.FilteringTreeSelect"]){
17     dojo.provide("openils.widget.FilteringTreeSelect");
18     dojo.require("dijit.form.FilteringSelect");
19     dojo.require("dojo.data.ItemFileWriteStore");
20
21     dojo.declare(
22         "openils.widget.FilteringTreeSelect", [dijit.form.FilteringSelect], {
23
24             defaultPad : 10,
25             parentField : 'parent',
26             labelAttr : 'name',
27             childField : 'children',
28             disableQuery : null,
29             tree : null,
30
31             construct : function(args) {
32                 if (args && args.dijitArgs && args.dijitArgs.onChange) {
33                     dojo.connect(this, 'onChange', args.dijitArgs.onChange);
34                 }
35             },
36
37             startup : function() {
38                 this.tree = (typeof this.tree == 'string') ? 
39                         dojox.jsonPath.query(window, '$.' + this.tree, {evalType:"RESULT"}) : this.tree;
40                 if(!this.tree) {
41                     console.log("openils.widget.FilteringTreeSelect: Tree needed!");
42                     return;
43                 }
44                 if(!dojo.isArray(this.tree)) this.tree = [this.tree];
45                 this.className = this.tree[0].classname;
46                 this.dataList = [];
47                 var self = this;
48                 dojo.forEach(this.tree, function(node) { self._makeNodeList(node); });
49                 if(this.dataList.length > 0) {
50                     var storeData = fieldmapper[this.className].initStoreData();
51                     storeData.items = this.dataList;
52                     this.store = new dojo.data.ItemFileWriteStore({data:storeData});
53                 }
54                 this.inherited(arguments);
55
56                 if(this.dataList.length > 0 && this.disableQuery)  
57                     this._setDisabled();
58             },
59
60             _setDisabled : function() {
61
62                 // tag disabled items
63                 this.store.fetch({
64                     query : this.disableQuery,
65                     onItem : function(item) { item._disabled = 'true'; }
66                 });
67
68                 // disallow selecting of disabled items
69                 var self = this;
70                 dojo.connect(this, 'onChange', 
71                     function(ident) { 
72                         if(!ident) return;
73                         self.store.fetchItemByIdentity({
74                             identity : ident,
75                             onItem : function(item) {
76                                 if(item._disabled == 'true')
77                                     self.attr('value', '');
78                             }
79                         });
80                     }
81                 );
82             },
83
84             // Compile the tree down to a depth-first list of dojo data items
85             _makeNodeList : function(node, depth) {
86                 if(!depth) depth = 0;
87                 var storeItem = node.toStoreItem();
88                 storeItem._depth = depth++;
89                 this.dataList.push(storeItem);
90
91                 for(var i in node[this.childField]()) 
92                     this._makeNodeList(node[this.childField]()[i], depth);
93             },
94
95             // For each item, find the depth at display time by searching up the tree.
96             _getMenuLabelFromItem : function(item) {
97
98                 var style = 'padding-left:'+ (item._depth * this.defaultPad) +'px;';
99
100                 if(item._disabled == 'true') // TODO: external CSS
101                     style += 'background-color:#CCC;cursor:wait'; 
102
103                 return {
104                     html: true,
105                     label: '<div style="'+style+'">' + this.store.getValue(item, this.labelAttr) + '</div>'
106                 }
107             },
108         }
109     );
110 }