source: Dev/trunk/src/client/qed-client/widgets/Selector.js @ 510

Last change on this file since 510 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: 8.2 KB
Line 
1define([
2    "../lib/object",
3    "./LineWithActionsWidget",
4    "dijit/_Container",
5    "dijit/_TemplatedMixin",
6    "dijit/_WidgetBase",
7    "dijit/_WidgetsInTemplateMixin",
8    "dijit/registry",
9    "dojo/_base/array",
10    "dojo/_base/declare",
11    "dojo/_base/event",
12    "dojo/_base/lang",
13    "dojo/dnd/Source",
14    "dojo/dom-class",
15    "dojo/dom-construct",
16    "dojo/fx",
17    "dojo/query",
18    "dojo/text!./templates/Selector.html"
19], function(objectFuns, LineWithActionsWidget, _Container, _TemplatedMixin, _WidgetBase, _WidgetsInTemplateMixin, registry, baseArray, declare, event, lang, Source, domClass, domConstruct, fx, query, templateString) {
20
21    function get(selector, item) {
22        if ( lang.isFunction(selector) ) {
23            return selector(item);
24        } else {
25            return item[selector || 'title'];
26        }
27    }
28   
29    return declare([_WidgetBase,_TemplatedMixin,_WidgetsInTemplateMixin,_Container],{
30        templateString: templateString,
31        baseClass: 'rftSelector',
32
33        title: "",
34        selectedActions: null,
35        itemActions: null,
36        itemTitle: 'title',
37        // main selector action: Object
38        //    title:
39        //    description:
40        //    icon:
41        dndType: null,
42
43        _source: null,
44        _folded: true,
45        _titleLine: null,
46        _selectorLine: null,
47        _selectedItem: null,
48
49        startup: function() {
50            if ( this._started ){ return; }
51            this.inherited(arguments);
52            domClass.add(this.selectedColorNode, "pending");
53
54            this._createTitleLine();
55            this._createSelectorLine();
56            if (this.dndType) {
57                this._createSource();
58            }
59
60            fx.wipeOut({
61                node: this.optionsNode
62            }).play();
63        },
64        _createTitleLine: function() {
65            var userActions =
66                    lang.isFunction(this.selectedActions) ?
67                    this.selectedActions() :
68                    this.selectedActions;
69
70            var actions = objectFuns.map(userActions||{},function(action,actionName){
71                return {
72                    callback: action.callback &&
73                              lang.hitch(this,this._onSelectedAction,
74                                         action.callback),
75                    properties: {
76                        blockButton: true,
77                        label: action.title || actionName,
78                        icon: action.icon,
79                        tooltip: action.description
80                    }
81
82                };
83            }, this);
84            this._titleLine = new LineWithActionsWidget({
85                title: this.title,
86                actions: actions
87            },this.titleNode);
88            this._titleLine.startup();
89        },
90        _createSelectorLine: function() {
91            this._selectorLine = new LineWithActionsWidget({
92                title: 'None',
93                actions: {
94                    "Toggle dropdown" : {
95                        callback: lang.hitch(this, this.onToggle),
96                        properties: {
97                            blockButton: true,
98                            showLabel: false,
99                            icon: "HalfArrowDown"
100                        }
101                    }
102                }
103            },this.selectedItemNode);
104            this._selectorLine.startup();
105            this.own(this._selectorLine.on('click',lang.hitch(this, 'onToggle')));
106        },
107        _createSource: function() {
108            this._source = new Source(this.optionsNode, {
109                singular: true,
110                delay: 5,
111                selfAccept: false,
112                copyOnly: true,
113                withHandles: this.withHandles,
114                creator: lang.hitch(this, "_createNode")
115            });
116        },
117        _onSelect: function(item, widget) {
118            this._selectedItem = item;
119            this.onToggle();
120            this._selectorLine.set("title", get(this.itemTitle,item));
121            baseArray.forEach(this.optionsNode.childNodes, function(node){
122                var line = registry.byNode(node);
123                if (line) {
124                    if (line === widget) {
125                        domClass.add(line.domNode, "inheritBgColor light");
126                    } else {
127                        domClass.remove(line.domNode, "inheritBgColor light");
128                    }
129                }
130            }, this);
131            this.onSelect(item);
132        },
133        _onSelectedAction: function(callback) {
134            if (this._selectedItem && callback) {
135                callback(this._selectedItem,this);
136            }
137        },
138
139        onToggle: function(evt) {
140            if (this._folded) {
141                var downArrowIcon = query(".rftBlockButton .rftIconHalfArrowDown", this._selectorLine.buttonsNode)[0];
142                if (downArrowIcon){
143                    domClass.replace(downArrowIcon, "rftIconHalfArrowUp", "rftIconHalfArrowDown");
144                }
145                fx.wipeIn({
146                    node: this.optionsNode
147                }).play();
148                this._folded = false;
149            } else {
150                var upArrowIcon = query(".rftBlockButton .rftIconHalfArrowUp", this._selectorLine.buttonsNode)[0];
151                if (upArrowIcon){
152                    domClass.replace(upArrowIcon, "rftIconHalfArrowDown", "rftIconHalfArrowUp");
153                }
154                fx.wipeOut({
155                    node: this.optionsNode
156                }).play();
157                this._folded = true;
158            }
159            if ( evt ) { event.stop(evt); }
160            return false;
161        },
162
163        addItem: function(item) {
164            if ( this._source ) {
165                this._source.insertNodes(false,[item]);
166            } else {
167                var node = this._createLineNode(item);
168                domConstruct.place(node, this.optionsNode, "last");
169            }
170        },
171        removeItem: function(item) {
172            var nodes = this._source ?
173                        this._source.getAllNodes() :
174                        this.optionsNode.childNodes;
175            baseArray.forEach(nodes, function(node) {
176                var widget = registry.byNode(node);
177                if ( widget && this.itemEquals ?
178                               this.itemEquals(widget.__item,item) :
179                               widget.__item === item ) {
180                    widget.destroyRecursive();
181                    if ( this._source ) { this._source.delItem(widget.id); }
182                }
183            }, this);
184        },
185        _createNode: function(item, hint) {
186            var node = hint === "avatar" ?
187                    this._createAvatarNode(item) : this._createLineNode(item);
188            return node && {
189                node: node,
190                data: lang.clone(item),
191                type: [this.dndType]
192            };
193        },
194        _createAvatarNode: function(item) {
195            return domConstruct.create("div",{
196                'class': 'dragAvatar',
197                innerHTML: get(this.itemTitle,item)
198            });
199        },
200        _createLineNode: function(item) {
201            var userActions =
202                    lang.isFunction(this.itemActions) ?
203                    this.itemActions(item) :
204                    this.itemActions;
205            var actions = objectFuns.map(userActions||{},function(action,actionName){
206                return {
207                    callback: action.callback &&
208                              lang.partial(action.callback,item,this),
209                    properties: {
210                        blockButton: false,
211                        showLabel: false,
212                        icon: action.icon + " black",
213                        tooltip: action.description
214                    }
215                };
216            }, this);
217            var w = new LineWithActionsWidget({
218                title: get(this.itemTitle,item),
219                actions: actions,
220                __item: item
221            });
222            w.startup();
223            this.own(w.on("click", lang.hitch(this, '_onSelect', item, w)));
224            return w.domNode;
225        },
226
227        onSelect: function(/*item*/) {},
228
229        destroy: function() {
230            if ( this._source ) { this._source.destroy(); }
231            this.inherited(arguments);
232        }
233    });
234});
Note: See TracBrowser for help on using the repository browser.