source: Dev/trunk/src/client/dojox/mvc/ListController.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 7.3 KB
Line 
1define([
2        "dojo/_base/array",
3        "dojo/_base/lang",
4        "dojo/_base/declare",
5        "./ModelRefController"
6], function(array, lang, declare, ModelRefController){
7        function unwatchHandles(/*dojox/mvc/ListController*/ c){
8                // summary:
9                //              Unwatch model watch handles.
10
11                for(var s in {"_listModelWatchHandle": 1, "_tableModelWatchHandle": 1}){
12                        if(c[s]){
13                                c[s].unwatch();
14                                c[s] = null;
15                        }
16                }
17        }
18
19        function setRefInModel(/*dojox/mvc/ListController*/ ctrl, /*dojo/Stateful*/ old, /*dojo/Stateful*/ current){
20                // summary:
21                //              A function called when this controller gets newer value as the list data.
22
23                unwatchHandles(ctrl);
24                if(current && old !== current){
25                        if(current.watchElements){
26                                ctrl._listModelWatchHandle = current.watchElements(function(idx, removals, adds){
27                                        if(removals && adds){
28                                                var curIdx = ctrl.get("cursorIndex");
29                                                // If selected element is removed, make "no selection" state
30                                                if(removals && curIdx >= idx && curIdx < idx + removals.length){
31                                                        ctrl.set("cursorIndex", -1);
32                                                        return;
33                                                }
34                                                // If selected element is equal to or larger than the removals/adds point, update the selected index
35                                                if((removals.length || adds.length) && curIdx >= idx){
36                                                        ctrl.set(ctrl._refCursorProp, ctrl.get("cursor"));
37                                                }
38                                        }else{
39                                                // If there is a update to the whole array, update the selected index
40                                                ctrl.set(ctrl._refCursorProp, ctrl.get(ctrl._refCursorProp));
41                                        }
42                                });
43                        }else if(current.set && current.watch){
44                                if(ctrl.get("cursorIndex") < 0){ ctrl._set("cursorIndex", ""); }
45                                ctrl._tableModelWatchHandle = current.watch(function(name, old, current){
46                                        if(old !== current && name == ctrl.get("cursorIndex")){
47                                                ctrl.set(ctrl._refCursorProp, current);
48                                        }
49                                });
50                        }
51                }
52                ctrl._setCursorIndexAttr(ctrl.cursorIndex);
53        }
54
55        function setRefCursor(/*dojox/mvc/ListController*/ ctrl, /*dojo/Stateful*/ old, /*dojo/Stateful*/ current){
56                // summary:
57                //              A function called when this controller gets newer value as the data of current selection.
58                // description:
59                //              Finds the index associated with the given element, and updates cursorIndex property.
60
61                var model = ctrl[ctrl._refInModelProp];
62                if(!model){ return; }
63                if(old !== current){
64                        if(lang.isArray(model)){
65                                var foundIdx = array.indexOf(model, current);
66                                if(foundIdx < 0){
67                                        var targetIdx = ctrl.get("cursorIndex");
68                                        if(targetIdx >= 0 && targetIdx < model.length){
69                                                model.set(targetIdx, current);
70                                        }
71                                }else{
72                                        ctrl.set("cursorIndex", foundIdx);
73                                }
74                        }else{
75                                for(var s in model){
76                                        if(model[s] == current){
77                                                ctrl.set("cursorIndex", s);
78                                                return;
79                                        }
80                                }
81                                var targetIdx = ctrl.get("cursorIndex");
82                                if(targetIdx){
83                                        model.set(targetIdx, current);
84                                }
85                        }
86                }
87        }
88
89        return declare("dojox.mvc.ListController", ModelRefController, {
90                // summary:
91                //              A controller working with array model, managing its cursor.
92                //              NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
93                // example:
94                //              The text box changes its value every two seconds.
95                // |            <html>
96                // |                    <head>
97                // |                            <script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
98                // |                            <script type="text/javascript">
99                // |                                    require([
100                // |                                            "dojo/parser", "dijit/registry", "dojox/mvc/StatefulArray",
101                // |                                            "dijit/form/TextBox", "dojox/mvc/ListController", "dojo/domReady!"
102                // |                                    ], function(parser, registry, StatefulArray){
103                // |                                            var count = 0;
104                // |                                            model = new StatefulArray([{value: "First"}, {value: "Second"}, {value: "Third"}, {value: "Fourth"}, {value: "Fifth"}]);
105                // |                                            setInterval(function(){ registry.byId("ctrl").set("cursorIndex", ++count % 5); }, 2000);
106                // |                                            parser.parse();
107                // |                                    });
108                // |                            </script>
109                // |                    </head>
110                // |                    <body>
111                // |                            <script type="dojo/require">at: "dojox/mvc/at"</script>
112                // |                            <span id="ctrl" data-dojo-type="dojox/mvc/ListController" data-dojo-props="model: model"></span>
113                // |                            <input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at('widget:ctrl', 'value')">
114                // |                    </body>
115                // |            </html>
116
117                // idProperty: String
118                //              The property name in element in the model array, that works as its identifier.
119                idProperty: "uniqueId",
120
121                // cursorId: String
122                //              The ID of the selected element in the model array.
123                cursorId: null,
124
125                // cursorIndex: Number|String
126                //              The index of the selected element in the model.
127                cursorIndex: -1,
128
129                // cursor: dojo/Stateful
130                //              The selected element in the model array.
131                cursor: null,
132
133                // model: dojox/mvc/StatefulArray
134                //              The data model working as an array.
135                model: null,
136
137                // _listModelWatchHandle: Object
138                //              The watch handle of model, watching for array elements.
139                _listModelWatchHandle: null,
140
141                // _tableModelWatchHandle: Object
142                //              The watch handle of model.
143                _tableModelWatchHandle: null,
144
145                // _refCursorProp: String
146                //              The property name for the data model of the current selection.
147                _refCursorProp: "cursor",
148
149                // _refModelProp: String
150                //              The property name for the data model.
151                _refModelProp: "cursor",
152
153                destroy: function(){
154                        unwatchHandles(this);
155                        this.inherited(arguments);
156                },
157
158                set: function(/*String*/ name, /*Anything*/ value){
159                        // summary:
160                        //              Set a property to this.
161                        // name: String
162                        //              The property to set.
163                        // value: Anything
164                        //              The value to set in the property.
165
166                        var oldRefInCursor = this[this._refCursorProp];
167                        var oldRefInModel = this[this._refInModelProp];
168                        this.inherited(arguments);
169                        if(name == this._refCursorProp){
170                                setRefCursor(this, oldRefInCursor, value);
171                        }
172                        if(name == this._refInModelProp){
173                                setRefInModel(this, oldRefInModel, value);
174                        }
175                },
176
177                _setCursorIdAttr: function(/*String*/ value){
178                        // summary:
179                        //              Handler for calls to set("cursorId", val).
180                        // description:
181                        //              Finds the index associated with the given cursor ID, and updates cursorIndex property.
182
183                        var old = this.cursorId;
184                        this._set("cursorId", value);
185                        var model = this[this._refInModelProp];
186                        if(!model){ return; }
187                        if(old !== value){
188                                if(lang.isArray(model)){
189                                        for(var i = 0; i < model.length; i++){
190                                                if(model[i][this.idProperty] == value){
191                                                        this.set("cursorIndex", i);
192                                                        return;
193                                                }
194                                        }
195                                        this._set("cursorIndex", -1);
196                                }else{
197                                        for(var s in model){
198                                                if(model[s][this.idProperty] == value){
199                                                        this.set("cursorIndex", s);
200                                                        return;
201                                                }
202                                        }
203                                        this._set("cursorIndex", "");
204                                }
205                        }
206                },
207
208                _setCursorIndexAttr: function(/*Number*/ value){
209                        // summary:
210                        //              Handler for calls to set("cursorIndex", val).
211                        // description:
212                        //              Updates cursor, cursorId, cursorIndex properties internally and call watch callbacks for them.
213
214                        this._set("cursorIndex", value);
215                        if(!this[this._refInModelProp]){ return; }
216                        this.set(this._refCursorProp, this[this._refInModelProp][value]);
217                        this.set("cursorId", this[this._refInModelProp][value] && this[this._refInModelProp][value][this.idProperty]);
218                },
219
220                hasControllerProperty: function(/*String*/ name){
221                        // summary:
222                        //              Returns true if this controller itself owns the given property.
223                        // name: String
224                        //              The property name.
225
226                        return this.inherited(arguments) || name == this._refCursorProp;
227                }
228        });
229});
Note: See TracBrowser for help on using the repository browser.