source: Dev/trunk/src/client/dojox/mobile/_EditableListMixin.js

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

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 7.4 KB
Line 
1// TODO: auto scroll?
2
3define([
4        "dojo/_base/array",
5        "dojo/_base/connect",
6        "dojo/_base/declare",
7        "dojo/_base/event",
8        "dojo/_base/window",
9        "dojo/dom-class",
10        "dojo/dom-geometry",
11        "dojo/dom-style",
12        "dojo/touch",
13        "dojo/dom-attr",
14        "dijit/registry",
15        "./ListItem"
16], function(array, connect, declare, event, win, domClass, domGeometry, domStyle, touch, domAttr, registry, ListItem){
17
18        // module:
19        //              dojox/mobile/EditableRoundRectList
20
21        return declare("dojox.mobile._EditableListMixin", null, {
22                // summary:
23                //              A rounded rectangle list.
24                // description:
25                //              EditableRoundRectList is a rounded rectangle list, which can be used to
26                //              display a group of items. Each item must be     a dojox/mobile/ListItem.
27
28                rightIconForEdit: "mblDomButtonGrayKnob",
29                deleteIconForEdit: "mblDomButtonRedCircleMinus",
30
31                // isEditing: Boolean
32                //              A read-only flag that indicates whether the widget is in the editing mode.
33                isEditing: false,
34
35                destroy: function(){
36                        // summary:
37                        //              Destroys the widget.
38                        if(this._blankItem){
39                                this._blankItem.destroy();
40                        }
41                        this.inherited(arguments);
42                },
43
44                _setupMoveItem: function(/*DomNode*/node){
45                        // tags:
46                        //              private
47                        domStyle.set(node, {
48                                width: domGeometry.getContentBox(node).w + "px",
49                                top: node.offsetTop + "px"
50                        });
51                        domClass.add(node, "mblListItemFloat");
52                },
53
54                _resetMoveItem: function(/*DomNode*/node){
55                        // tags:
56                        //              private
57                        this.defer(function(){ // iPhone needs setTimeout (via defer)
58                                domClass.remove(node, "mblListItemFloat");
59                                domStyle.set(node, {
60                                        width: "",
61                                        top: ""
62                                });
63                        });
64                },
65
66                _onClick: function(e){
67                        // summary:
68                        //              Internal handler for click events.
69                        // tags:
70                        //              private
71                        if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
72                        if(this.onClick(e) === false){ return; } // user's click action
73                        var item = registry.getEnclosingWidget(e.target);
74                        for(var n = e.target; n !== item.domNode; n = n.parentNode){
75                                if(n === item.deleteIconNode){
76                                        connect.publish("/dojox/mobile/deleteListItem", [item]);
77                                        this.onDeleteItem(item); //callback
78                                        break;
79                                }
80                        }
81                },
82
83                onClick: function(/*Event*/ /*===== e =====*/){
84                        // summary:
85                        //              User-defined function to handle clicks.
86                        // tags:
87                        //              callback
88                },
89
90                _onTouchStart: function(e){
91                        // tags:
92                        //              private
93                        if(this.getChildren().length <= 1){ return; }
94                        if(!this._blankItem){
95                                this._blankItem = new ListItem();
96                        }
97                        var item = this._movingItem = registry.getEnclosingWidget(e.target);
98                        this._startIndex = this.getIndexOfChild(item);
99                        var rightIconPressed = false;
100                        for(var n = e.target; n !== item.domNode; n = n.parentNode){
101                                if(n === item.rightIconNode){
102                                        rightIconPressed = true;
103                                        domAttr.set(item.rightIconNode, "aria-grabbed", "true");
104                                        domAttr.set(this.domNode, "aria-dropeffect", "move");
105                                        break;
106                                }
107                        }
108                        if(!rightIconPressed){ return; }
109                        var ref = item.getNextSibling();
110                        ref = ref ? ref.domNode : null;
111                        this.containerNode.insertBefore(this._blankItem.domNode, ref);
112                        this._setupMoveItem(item.domNode);
113                        this.containerNode.appendChild(item.domNode);
114
115                        if(!this._conn){
116                                this._conn = [
117                                        this.connect(this.domNode, touch.move, "_onTouchMove"),
118                                        this.connect(win.doc, touch.release, "_onTouchEnd")
119                                ];
120                        }
121                        this._pos = [];
122                        array.forEach(this.getChildren(), function(c, index){
123                                this._pos.push(domGeometry.position(c.domNode, true).y);
124                        }, this);
125                        this.touchStartY = e.touches ? e.touches[0].pageY : e.pageY;
126                        this._startTop = domGeometry.getMarginBox(item.domNode).t;
127                        event.stop(e);
128                },
129
130                _onTouchMove: function(e){
131                        // tags:
132                        //              private
133                        var y = e.touches ? e.touches[0].pageY : e.pageY;
134                        var index = this._pos.length - 1;
135                        for(var i = 1; i < this._pos.length; i++){
136                                if(y < this._pos[i]){
137                                        index = i - 1;
138                                        break;
139                                }
140                        }
141                        var item = this.getChildren()[index];
142                        var blank = this._blankItem;
143                        if(item !== blank){
144                                var p = item.domNode.parentNode;
145                                if(item.getIndexInParent() < blank.getIndexInParent()){
146                                        p.insertBefore(blank.domNode, item.domNode);
147                                }else{
148                                        p.insertBefore(item.domNode, blank.domNode);
149                                }
150                        }
151                        this._movingItem.domNode.style.top = this._startTop + (y - this.touchStartY) + "px";
152                },
153
154                _onTouchEnd: function(e){
155                        // tags:
156                        //              private
157                        var startIndex = this._startIndex;
158                        var endIndex = this.getIndexOfChild(this._blankItem);
159                                               
160                        var ref = this._blankItem.getNextSibling();
161                        ref = ref ? ref.domNode : null;
162                        if(ref === null){
163                                //If the item is droped at the end of the list the endIndex is wrong
164                                endIndex--;
165                        }
166                        this.containerNode.insertBefore(this._movingItem.domNode, ref);
167                        this.containerNode.removeChild(this._blankItem.domNode);
168                        this._resetMoveItem(this._movingItem.domNode);
169
170                        array.forEach(this._conn, connect.disconnect);
171                        this._conn = null;
172                       
173                        this.onMoveItem(this._movingItem, startIndex, endIndex); //callback
174                       
175                        domAttr.set(this._movingItem.rightIconNode, "aria-grabbed", "false");
176                        domAttr.remove(this.domNode, "aria-dropeffect");
177                },
178
179                startEdit: function(){
180                        // summary:
181                        //              Starts the editing.
182                        this.isEditing = true;
183                        domClass.add(this.domNode, "mblEditableRoundRectList");
184                        array.forEach(this.getChildren(), function(child){
185                                if(!child.deleteIconNode){
186                                        child.set("rightIcon", this.rightIconForEdit);
187                                        if(child.rightIconNode){
188                                                domAttr.set(child.rightIconNode, "role", "button");
189                                                domAttr.set(child.rightIconNode, "aria-grabbed", "false");
190                                        }
191                                        child.set("deleteIcon", this.deleteIconForEdit);
192                                        child.deleteIconNode.tabIndex = child.tabIndex;
193                                        if(child.deleteIconNode){
194                                                domAttr.set(child.deleteIconNode, "role", "button");
195                                        }
196                                }
197                                child.rightIconNode.style.display = "";
198                                child.deleteIconNode.style.display = "";
199                                if(typeof child.rightIconNode.style.msTouchAction != "undefined"){
200                                        child.rightIconNode.style.msTouchAction = "none";
201                                }
202                        }, this);
203                        if(!this._handles){
204                                this._handles = [
205                                        this.connect(this.domNode, touch.press, "_onTouchStart"),
206                                        this.connect(this.domNode, "onclick", "_onClick"),
207                                        this.connect(this.domNode, "onkeydown", "_onClick") // for desktop browsers
208                                ];
209                        }
210                       
211                        this.onStartEdit(); // callback
212                },
213
214                endEdit: function(){
215                        // summary:
216                        //              Ends the editing.
217                        domClass.remove(this.domNode, "mblEditableRoundRectList");
218                        array.forEach(this.getChildren(), function(child){
219                                child.rightIconNode.style.display = "none";
220                                child.deleteIconNode.style.display = "none";
221                                if(typeof child.rightIconNode.style.msTouchAction != "undefined"){
222                                        child.rightIconNode.style.msTouchAction = "auto";
223                                }
224                        });
225                        if(this._handles){
226                                array.forEach(this._handles, this.disconnect, this);
227                                this._handles = null;
228                        }
229                        this.isEditing = false;
230                       
231                        this.onEndEdit(); // callback
232                },
233               
234               
235                onDeleteItem: function(/*Widget*/item){
236                        // summary:
237                        //              Stub function to connect to from your application.
238                        // description:
239                        //              This function is called when a user clicks the delete
240                        //              button.
241                        //              You have to provide that function or subscribe to /dojox/mobile/deleteListItem,
242                        //              otherwise the delete button will have no-effect.
243                       
244                },
245               
246                onMoveItem: function(/*Widget*/item, /*int*/from, /*int*/to){
247                        // summary:
248                        //              Stub function to connect to from your application.
249                },
250
251                onStartEdit: function(){
252                        // summary:
253                        //              Stub function to connect to from your application.
254                },
255
256                onEndEdit: function(){
257                        // summary:
258                        //              Stub function to connect to from your application.
259                }
260
261
262        });
263});
Note: See TracBrowser for help on using the repository browser.