1 | define([ |
---|
2 | "./Selector", |
---|
3 | "dijit/layout/ContentPane", |
---|
4 | "dijit/layout/TabContainer", |
---|
5 | "dojo/_base/array", |
---|
6 | "dojo/_base/declare", |
---|
7 | "dojo/_base/lang", |
---|
8 | "dojo/_base/window", |
---|
9 | "dojo/when", |
---|
10 | "dojox/widget/Standby" |
---|
11 | ], function(Selector, ContentPane, TabContainer, array, declare, lang, win, when, Standby) { |
---|
12 | return declare([TabContainer],{ |
---|
13 | tabPosition: 'left-h', |
---|
14 | |
---|
15 | // interface the client must implement |
---|
16 | getCategories: function(){ return []; }, |
---|
17 | getCategoryName: function(category){ return ""; }, |
---|
18 | getCategoryCount: function(category){ return 0; }, |
---|
19 | getTopics: function(category){ return []; }, |
---|
20 | getTopicName: function(topic){ return "";}, |
---|
21 | getTopicCount: function(topic){ return 0; }, |
---|
22 | getItems: function(category,topic){ return []; }, |
---|
23 | getItemName: function(item){ return ""; }, |
---|
24 | getItemActions: function(item){ return {}; }, // {name:{'callback'(item,sel),'icon','description'}} |
---|
25 | getSelectedItemActions: function(){ return {}; }, // {name:{'callback'(item,sel),'icon','description'}} |
---|
26 | areItemsEqual: function(i1,i2){ return i1 === i2; }, |
---|
27 | |
---|
28 | dndType: "", |
---|
29 | |
---|
30 | _dataMap: null, |
---|
31 | _busyCount: 0, |
---|
32 | constructor: function() { |
---|
33 | this._dataMap = {}; |
---|
34 | }, |
---|
35 | startup: function() { |
---|
36 | if ( this._started ){ return; } |
---|
37 | this.inherited(arguments); |
---|
38 | this._busyWidget = new Standby({ |
---|
39 | target: this.domNode, |
---|
40 | duration: 200 |
---|
41 | }).placeAt(win.body()); |
---|
42 | this._busyWidget.startup(); |
---|
43 | this.watch("selectedChildWidget",lang.hitch(this,'_handleChangeTab')); |
---|
44 | when(this.getCategories()) |
---|
45 | .then(lang.hitch(this,'_addCategories')); |
---|
46 | }, |
---|
47 | _addCategories: function(categories) { |
---|
48 | array.forEach(categories, function(category) { |
---|
49 | this._addCategory(category); |
---|
50 | }, this); |
---|
51 | }, |
---|
52 | _handleChangeTab: function(name,oldTab,newTab) { |
---|
53 | this._fillCategory(newTab.__category); |
---|
54 | }, |
---|
55 | _addCategory: function(category) { |
---|
56 | var name = this.getCategoryName(category); |
---|
57 | var count = this.getCategoryCount(category); |
---|
58 | if (this._dataMap[name] === undefined) { |
---|
59 | var tab = new ContentPane({ |
---|
60 | __category: category, |
---|
61 | title: (name||'[No category]')+(count&&' ('+count+')') |
---|
62 | }); |
---|
63 | tab.startup(); |
---|
64 | this._dataMap[name] = { |
---|
65 | _widget: tab |
---|
66 | }; |
---|
67 | this.addChild(tab); |
---|
68 | } |
---|
69 | }, |
---|
70 | _fillCategory: function(category) { |
---|
71 | var name = this.getCategoryName(category); |
---|
72 | var map = this._dataMap[name]; |
---|
73 | if (!map._filled) { |
---|
74 | this._busy(); |
---|
75 | map._filled = true; |
---|
76 | when(this.getTopics(category)) |
---|
77 | .then(lang.hitch(this,'_addTopicsToCategory',category)) |
---|
78 | .always(lang.hitch(this,'_done')); |
---|
79 | } |
---|
80 | }, |
---|
81 | _addTopicsToCategory: function(category,topics) { |
---|
82 | array.forEach(topics, function(topic) { |
---|
83 | var cname = this.getCategoryName(category); |
---|
84 | var tname = this.getTopicName(topic); |
---|
85 | this._addTopicToCategory(category,topic); |
---|
86 | }, this); |
---|
87 | }, |
---|
88 | _addTopicToCategory: function(category,topic) { |
---|
89 | var map = this._dataMap[this.getCategoryName(category)]; |
---|
90 | var name = this.getTopicName(topic); |
---|
91 | var count = this.getTopicCount(topic); |
---|
92 | if (map[name] === undefined) { |
---|
93 | var w = new Selector({ |
---|
94 | __category: category, |
---|
95 | __topic: topic, |
---|
96 | dndType: this.dndType, |
---|
97 | title: (name||'[No topic]')+(count&&" ("+count+")"), |
---|
98 | selectedActions: lang.hitch(this,'getSelectedItemActions'), |
---|
99 | itemActions: lang.hitch(this,'getItemActions'), |
---|
100 | itemTitle: lang.hitch(this,'getItemName'), |
---|
101 | itemEquals: lang.hitch(this,'areItemsEqual') |
---|
102 | }).placeAt(map._widget.containerNode); |
---|
103 | w.startup(); |
---|
104 | map[name] = { |
---|
105 | _widget: w |
---|
106 | }; |
---|
107 | this._fillTopicInCategory(category,topic); |
---|
108 | } |
---|
109 | }, |
---|
110 | _fillTopicInCategory: function(category,topic) { |
---|
111 | var map = this._dataMap[this.getCategoryName(category)][this.getTopicName(topic)]; |
---|
112 | if (!map._filled) { |
---|
113 | map._filled = true; |
---|
114 | this._busy(); |
---|
115 | when(this.getItems(category,topic)) |
---|
116 | .then(lang.hitch(this,function(items){ |
---|
117 | array.forEach(items,map._widget.addItem,map._widget); |
---|
118 | })).always(lang.hitch(this,'_done')); |
---|
119 | } |
---|
120 | }, |
---|
121 | removeItem: function(item) { |
---|
122 | var cmap = this._dataMap; |
---|
123 | for ( var cat in cmap ) { |
---|
124 | if ( cmap.hasOwnProperty(cat) ) { |
---|
125 | var tmap = cmap[cat]; |
---|
126 | for ( var top in tmap ) { |
---|
127 | if ( tmap.hasOwnProperty(top) ) { |
---|
128 | var widget = tmap[top]._widget; |
---|
129 | if ( widget ) { widget.removeItem(item); } |
---|
130 | } |
---|
131 | } |
---|
132 | } |
---|
133 | } |
---|
134 | }, |
---|
135 | _busy: function() { |
---|
136 | if ( this._busyCount === 0 ) { |
---|
137 | this._busyWidget.show(); |
---|
138 | } |
---|
139 | this._busyCount++; |
---|
140 | }, |
---|
141 | _done: function() { |
---|
142 | if ( this._busyCount > 0 ) { |
---|
143 | this._busyCount--; |
---|
144 | if ( this._busyCount === 0 ) { |
---|
145 | this._busyWidget.hide(); |
---|
146 | } |
---|
147 | } else { |
---|
148 | console.warn('_done() was called more times than _busy().'); |
---|
149 | } |
---|
150 | }, |
---|
151 | destroy: function() { |
---|
152 | this._busyWidget.destroyRecursive(); |
---|
153 | this.inherited(arguments); |
---|
154 | } |
---|
155 | }); |
---|
156 | }); |
---|