source: Dev/branches/rest-dojo-ui/client/dojox/mobile/SpinWheelSlot.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 9.4 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/window",
4        "dojo/dom-class",
5        "dojo/dom-construct",
6        "dijit/_Contained",
7        "dijit/_WidgetBase",
8        "./_ScrollableMixin"
9], function(declare, win, domClass, domConstruct, Contained, WidgetBase, ScrollableMixin){
10
11/*=====
12        var Contained = dijit._Contained;
13        var WidgetBase = dijit._WidgetBase;
14        var ScrollableMixin = dojox.mobile._ScrollableMixin;
15=====*/
16
17        // module:
18        //              dojox/mobile/SpinWheelSlot
19        // summary:
20        //              A slot of a SpinWheel.
21
22        return declare("dojox.mobile.SpinWheelSlot", [WidgetBase, Contained, ScrollableMixin], {
23                // summary:
24                //              A slot of a SpinWheel.
25                // description:
26                //              SpinWheelSlot is a slot that is placed in the SpinWheel widget.
27
28                // items: Array
29                //              An array of array of key-label paris.
30                //              (e.g. [[0,"Jan"],[1,"Feb"],...] ) If key values for each label
31                //              are not necessary, labels can be used instead.
32                items: [],
33
34                // labels: Array
35                //              An array of labels to be displayed on the slot.
36                //              (e.g. ["Jan","Feb",...] ) This is a simplified version of the
37                //              items property.
38                labels: [],
39
40                // labelFrom: Number
41                //              The start value of display values of the slot. This parameter is
42                //              especially useful when slot has serial values.
43                labelFrom: 0,
44
45                // labelTo: Number
46                //              The end value of display values of the slot.
47                labelTo: 0,
48
49                // value: String
50                //              The initial value of the slot.
51                value: "",
52
53                /* internal properties */       
54                maxSpeed: 500,
55                minItems: 15,
56                centerPos: 0,
57                scrollBar: false,
58                constraint: false,
59                allowNestedScrolls: false,
60                androidWorkaroud: false, // disable workaround in SpinWheel
61
62                buildRendering: function(){
63                        this.inherited(arguments);
64                        domClass.add(this.domNode, "mblSpinWheelSlot");
65
66                        var i, j, idx;
67                        if(this.labelFrom !== this.labelTo){
68                                this.labels = [];
69                                for(i = this.labelFrom, idx = 0; i <= this.labelTo; i++, idx++){
70                                        this.labels[idx] = String(i);
71                                }
72                        }
73                        if(this.labels.length > 0){
74                                this.items = [];
75                                for(i = 0; i < this.labels.length; i++){
76                                        this.items.push([i, this.labels[i]]);
77                                }
78                        }
79
80                        this.containerNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotContainer"});
81                        this.containerNode.style.height
82                                = (win.global.innerHeight||win.doc.documentElement.clientHeight) * 2 + "px"; // must bigger than the screen
83                        this.panelNodes = [];
84                        for(var k = 0; k < 3; k++){
85                                this.panelNodes[k] = domConstruct.create("DIV", {className:"mblSpinWheelSlotPanel"});
86                                var len = this.items.length;
87                                var n = Math.ceil(this.minItems / len);
88                                for(j = 0; j < n; j++){
89                                        for(i = 0; i < len; i++){
90                                                domConstruct.create("DIV", {
91                                                        className: "mblSpinWheelSlotLabel",
92                                                        name: this.items[i][0],
93                                                        innerHTML: this._cv ? this._cv(this.items[i][1]) : this.items[i][1]
94                                                }, this.panelNodes[k]);
95                                        }
96                                }
97                                this.containerNode.appendChild(this.panelNodes[k]);
98                        }
99                        this.domNode.appendChild(this.containerNode);
100                        this.touchNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotTouch"}, this.domNode);
101                        this.setSelectable(this.domNode, false);
102                },
103       
104                startup: function(){
105                        this.inherited(arguments);
106                        this.centerPos = this.getParent().centerPos;
107                        var items = this.panelNodes[1].childNodes;
108                        this._itemHeight = items[0].offsetHeight;
109                        this.adjust();
110                },
111       
112                adjust: function(){
113                        // summary:
114                        //              Adjusts the position of slot panels.
115                        var items = this.panelNodes[1].childNodes;
116                        var adjustY;
117                        for(var i = 0, len = items.length; i < len; i++){
118                                var item = items[i];
119                                if(item.offsetTop <= this.centerPos && this.centerPos < item.offsetTop + item.offsetHeight){
120                                        adjustY = this.centerPos - (item.offsetTop + Math.round(item.offsetHeight/2));
121                                        break;
122                                }
123                        }
124                        var h = this.panelNodes[0].offsetHeight;
125                        this.panelNodes[0].style.top = -h + adjustY + "px";
126                        this.panelNodes[1].style.top = adjustY + "px";
127                        this.panelNodes[2].style.top = h + adjustY + "px";
128                },
129       
130                setInitialValue: function(){
131                        // summary:
132                        //              Sets the initial value using this.value or the first item.
133                        if(this.items.length > 0){
134                                var val = (this.value !== "") ? this.value : this.items[0][1];
135                                this.setValue(val);
136                        }
137                },
138       
139                getCenterPanel: function(){
140                        // summary:
141                        //              Gets a panel that contains the currently selected item.
142                        var pos = this.getPos();
143                        for(var i = 0, len = this.panelNodes.length; i < len; i++){
144                                var top = pos.y + this.panelNodes[i].offsetTop;
145                                if(top <= this.centerPos && this.centerPos < top + this.panelNodes[i].offsetHeight){
146                                        return this.panelNodes[i];
147                                }
148                        }
149                        return null;
150                },
151       
152                setColor: function(/*String*/value){
153                        // summary:
154                        //              Sets the color of the specified item as blue.
155                        for(var i = 0, len = this.panelNodes.length; i < len; i++){
156                                var items = this.panelNodes[i].childNodes;
157                                for(var j = 0; j < items.length; j++){
158                                        if(items[j].innerHTML === String(value)){
159                                                domClass.add(items[j], "mblSpinWheelSlotLabelBlue");
160                                        }else{
161                                                domClass.remove(items[j], "mblSpinWheelSlotLabelBlue");
162                                        }
163                                }
164                        }
165                },
166       
167                disableValues: function(/*Array*/values){
168                        // summary:
169                        //              Makes the specified items grayed out.
170                        for(var i = 0, len = this.panelNodes.length; i < len; i++){
171                                var items = this.panelNodes[i].childNodes;
172                                for(var j = 0; j < items.length; j++){
173                                        domClass.remove(items[j], "mblSpinWheelSlotLabelGray");
174                                        for(var k = 0; k < values.length; k++){
175                                                if(items[j].innerHTML === String(values[k])){
176                                                        domClass.add(items[j], "mblSpinWheelSlotLabelGray");
177                                                        break;
178                                                }
179                                        }
180                                }
181                        }
182                },
183       
184                getCenterItem: function(){
185                        // summary:
186                        //              Gets the currently selected item.
187                        var pos = this.getPos();
188                        var centerPanel = this.getCenterPanel();
189                        if(centerPanel){
190                                var top = pos.y + centerPanel.offsetTop;
191                                var items = centerPanel.childNodes;
192                                for(var i = 0, len = items.length; i < len; i++){
193                                        if(top + items[i].offsetTop <= this.centerPos && this.centerPos < top + items[i].offsetTop + items[i].offsetHeight){
194                                                return items[i];
195                                        }
196                                }
197                        }
198                        return null;
199       
200                },
201       
202                getValue: function(){
203                        // summary:
204                        //              Gets the currently selected value.
205                        var item = this.getCenterItem();
206                        return (item && item.innerHTML);
207                },
208       
209                getKey: function(){
210                        // summary:
211                        //              Gets the key for the currently selected value.
212                        return this.getCenterItem().getAttribute("name");
213                },
214       
215                setValue: function(newValue){
216                        // summary:
217                        //              Sets the newValue to this slot.
218                        var idx0, idx1;
219                        var curValue = this.getValue();
220                        if(!curValue){
221                                this._penddingValue = newValue;
222                                return;
223                        }
224                        this._penddingValue = undefined;
225                        var n = this.items.length;
226                        for(var i = 0; i < n; i++){
227                                if(this.items[i][1] === String(curValue)){
228                                        idx0 = i;
229                                }
230                                if(this.items[i][1] === String(newValue)){
231                                        idx1 = i;
232                                }
233                                if(idx0 !== undefined && idx1 !== undefined){
234                                        break;
235                                }
236                        }
237                        var d = idx1 - (idx0 || 0);
238                        var m;
239                        if(d > 0){
240                                m = (d < n - d) ? -d : n - d;
241                        }else{
242                                m = (-d < n + d) ? -d : -(n + d);
243                        }
244                        var to = this.getPos();
245                        to.y += m * this._itemHeight;
246                        this.slideTo(to, 1);
247                },
248       
249                getSpeed: function(){
250                        // summary:
251                        //              Overrides dojox.mobile.scrollable.getSpeed().
252                        var y = 0, n = this._time.length;
253                        var delta = (new Date()).getTime() - this.startTime - this._time[n - 1];
254                        if(n >= 2 && delta < 200){
255                                var dy = this._posY[n - 1] - this._posY[(n - 6) >= 0 ? n - 6 : 0];
256                                var dt = this._time[n - 1] - this._time[(n - 6) >= 0 ? n - 6 : 0];
257                                y = this.calcSpeed(dy, dt);
258                        }
259                        return {x:0, y:y};
260                },
261
262                calcSpeed: function(/*Number*/d, /*Number*/t){
263                        // summary:
264                        //              Overrides dojox.mobile.scrollable.calcSpeed().
265                        var speed = this.inherited(arguments);
266                        if(!speed){ return 0; }
267                        var v = Math.abs(speed);
268                        var ret = speed;
269                        if(v > this.maxSpeed){
270                                ret = this.maxSpeed*(speed/v);
271                        }
272                        return ret;
273                },
274       
275                adjustDestination: function(to, pos){
276                        // summary:
277                        //              Overrides dojox.mobile.scrollable.adjustDestination().
278                        var h = this._itemHeight;
279                        var j = to.y + Math.round(h/2);
280                        var a = Math.abs(j);
281                        var r = j >= 0 ? j % h : j % h + h;
282                        to.y = j - r;
283                },
284       
285                resize: function(e){
286                        if(this._penddingValue){
287                                this.setValue(this._penddingValue);
288                        }
289                },
290
291                slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
292                        // summary:
293                        //              Overrides dojox.mobile.scrollable.slideTo().
294                        var pos = this.getPos();
295                        var top = pos.y + this.panelNodes[1].offsetTop;
296                        var bottom = top + this.panelNodes[1].offsetHeight;
297                        var vh = this.domNode.parentNode.offsetHeight;
298                        var t;
299                        if(pos.y < to.y){ // going down
300                                if(bottom > vh){
301                                        // move up the bottom panel
302                                        t = this.panelNodes[2];
303                                        t.style.top = this.panelNodes[0].offsetTop - this.panelNodes[0].offsetHeight + "px";
304                                        this.panelNodes[2] = this.panelNodes[1];
305                                        this.panelNodes[1] = this.panelNodes[0];
306                                        this.panelNodes[0] = t;
307                                }
308                        }else if(pos.y > to.y){ // going up
309                                if(top < 0){
310                                        // move down the top panel
311                                        t = this.panelNodes[0];
312                                        t.style.top = this.panelNodes[2].offsetTop + this.panelNodes[2].offsetHeight + "px";
313                                        this.panelNodes[0] = this.panelNodes[1];
314                                        this.panelNodes[1] = this.panelNodes[2];
315                                        this.panelNodes[2] = t;
316                                }
317                        }
318                        if(!this._initialized){
319                                duration = 0; // to reduce flickers at start-up especially on android
320                                this._initialized = true;
321                        }else if(Math.abs(this._speed.y) < 40){
322                                duration = 0.2;
323                        }
324                        this.inherited(arguments, [to, duration, easing]); // 2nd arg is to avoid excessive optimization by closure compiler
325                }
326        });
327});
Note: See TracBrowser for help on using the repository browser.