source: Dev/trunk/src/client/qed-client/widgets/ListWidget.js

Last change on this file was 525, checked in by hendrikvanantwerpen, 11 years ago
  • Allow empty subcodes.
  • Use HTTPResult exclusively on server (no more q).
  • Set readonly & disabled on ourselves as well in _ComplexValueMixin
  • Split server into several modules.
  • Check codes on the variable level, not question level.
  • We can add modules in design documents now.
File size: 6.9 KB
Line 
1define([
2    "./_ComplexValueMixin",
3    "dijit/_WidgetBase",
4    "dijit/registry",
5    "dojo/_base/array",
6    "dojo/_base/declare",
7    "dojo/_base/event",
8    "dojo/_base/lang",
9    "dojo/dnd/Source",
10    "dojo/dnd/common",
11    "dojo/dom-construct",
12    "dojo/on"
13], function(_ComplexValueMixin, _WidgetBase, registry, array, declare, event, lang, Source, dnd, domConstruct, on) {
14    return declare([_WidgetBase,_ComplexValueMixin],{
15        multiple: true,
16        type: "text",
17        /* container : dojo/dnd/Container or subclass
18         * determine which container to use for the list
19         */
20        container: Source,
21        _restoreParams: null,
22        _onChangeActive: false,
23        _onChangeHandle: null,
24        _fromDrop: true,
25        buildRendering: function() {
26            this.inherited(arguments);
27
28            var sourceParams = {};
29            var paramsToInherit = [
30                "singular",
31                "creator",
32                "skipForm",
33                "dropParent",
34                "isSource",
35                "autoSync",
36                "copyOnly",
37                "delay",
38                "horizontal",
39                "selfCopy",
40                "selfAccept",
41                "withHandles",
42                "generateText"
43            ];
44            array.forEach(paramsToInherit, function(param){
45                if ( typeof this[param] !== "undefined" ) {
46                    sourceParams[param] = this[param];
47                }
48            },this);
49            lang.mixin(sourceParams, {
50                accept: [this.type],
51                creator: lang.hitch(this,"creator"),
52                dropParent: this.containerNode
53            });
54            this.source = new this.container(this.domNode,sourceParams);
55            this._restoreParams = {
56                accept: this.source.accept,
57                selfAccept: this.source.selfAccept,
58                selfCopy: this.source.selfCopy,
59                isSource: this.source.isSource
60            };
61            this.own(this.source.on('Drop',
62                                    lang.hitch(this,'_handleDrop')));
63        },
64        creator: function(item, hint) {
65            var id = dnd.getUniqueId();
66            var nodeOrWidget = null;
67            if ( hint === "avatar" ) {
68                if ( this.createAvatar ) {
69                    nodeOrWidget = this.createAvatar(id,item);
70                } else {
71                    return this.source.defaultCreator(item, hint);
72                }
73            } else {
74                if ( this.createListElement ) {
75                    nodeOrWidget =
76                        this.createListElement(id,item,this._fromDrop);
77                } else {
78                    return this.source.defaultCreator(item, hint);
79                }
80            }
81            if ( nodeOrWidget.on ) {
82                this.connectChildsChanges(nodeOrWidget);
83            }
84            var node = nodeOrWidget.domNode ?
85                       nodeOrWidget.domNode :
86                       nodeOrWidget;
87            if ( hint !== "avatar" && node.id !== id ) {
88                console.warn("Node id '%s' not equal to generated id '%s'. Is this intended?", node.id, id);
89            }
90            return {
91                data: item,
92                type: [this.type],
93                node: node
94            };
95        },
96        createAvatar: null, /*function(id,item){},*/
97        createListElement: null, /* function(id,item,fromDrop){},*/
98        _getValueAttr: function() {
99            return array.map(
100                this.source.getAllNodes(),
101                lang.hitch(this,function(node){
102                    var widget = registry.byNode(node);
103                    if ( widget && 'value' in widget ) {
104                        return widget.get('value');
105                    } else {
106                        return this.source.getItem(node.id).data;
107                    }
108                }));
109        },
110        _setValueAttr: function(value,priorityChange) {
111            this.clear();
112            this._setValueInternal(value || [], priorityChange);
113            this.appendItems(this.value);
114        },
115        _setReadOnlyAttr: function() {
116            this.inherited(arguments);
117            this._updateSource();
118        },
119        _setDisabledAttr: function() {
120            this.inherited(arguments);
121            this._updateSource();
122        },
123        _updateSource: function() {
124            if ( this.disabled || this.readOnly ) {
125                this.source.accept = [];
126                this.source.selfAccept = false;
127                this.source.selfCopy = false;
128                this.source.isSource = false;
129            } else {
130                lang.mixin(this.source,this._restoreParams);
131            }
132        },
133        getChildren: function() {
134            return array.filter(
135                array.map(this.source.getAllNodes(), function(node){
136                    return registry.byNode(node);
137                }),
138                function(widget){ return widget !== null; });
139        },
140        _getDescendantFormWidgets: function() {
141            return array.filter(
142                this.getChildren(),
143                function(child){ return 'value' in child; });
144        },
145
146        appendItems: function(items,forceEvent) {
147            this._fromDrop = false;
148            this.source.insertNodes(false,items);
149            this._setValueInternal(
150                this.get('value'),
151                forceEvent === true ? true : null);
152            this._fromDrop = true;
153        },
154        appendItem: function(item,forceEvent) {
155            this._fromDrop = false;
156            this.source.insertNodes(false,[item]);
157            this._setValueInternal(
158                this.get('value'),
159                forceEvent === true ? true : null);
160            this._fromDrop = true;
161        },
162        removeItem: function(key,forceEvent) {
163            array.forEach(
164                array.filter(this.source.getAllNodes(), function(node){
165                    return node.id === key;
166                }),
167                lang.hitch(this, "_destroyNodeOrWidget"));
168            this.source.delItem(key);
169            this._setValueInternal(
170                this.get('value'),
171                forceEvent === true ? true : null);
172        },
173        clear: function(forceEvent) {
174            array.forEach(this.source.getAllNodes(),
175                          lang.hitch(this, "_destroyNodeOrWidget"));
176            this.source.clearItems();
177            this._setValueInternal(
178                this.get('value'),
179                forceEvent === true ? true : null);
180        },
181        _destroyNodeOrWidget: function(node) {
182            var widget = registry.byNode(node);
183            if ( widget ) {
184                widget.destroyRecursive();
185            } else {
186                domConstruct.destroy(node);
187            }
188        },
189        destroy: function() {
190            this.source.destroy();
191            this.inherited(arguments);
192        },
193        _handleDrop: function() {
194            this._setValueInternal(this.get('value'));
195        }
196    });
197});
Note: See TracBrowser for help on using the repository browser.