source: Dev/trunk/src/client/qed-client/widgets/TabbedBrowser.js @ 529

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