]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/scrollview/scrollview-paginator.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / scrollview / scrollview-paginator.js
1 /*
2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
5 version: 3.3.0
6 build: 3167
7 */
8 YUI.add('scrollview-paginator', function(Y) {
9
10 /**
11  * Provides a plugin, which adds pagination support to ScrollView instances
12  *
13  * @module scrollview-paginator
14  */
15
16 var UI = Y.ScrollView.UI_SRC,
17     INDEX = "index",
18     SCROLL_X = "scrollX",
19     TOTAL = "total",
20     BOUNDING_BOX = "boundingBox",
21     CONTENT_BOX = "contentBox";
22
23 /**
24  * Scrollview plugin that adds support for paging
25  *
26  * @class ScrollViewPaginator
27  * @namespace Plugin
28  * @extends Plugin.Base 
29  * @constructor
30  */
31 function PaginatorPlugin() {
32     PaginatorPlugin.superclass.constructor.apply(this, arguments);
33 }
34
35 /**
36  * The identity of the plugin
37  *
38  * @property ScrollViewPaginator.NAME
39  * @type String
40  * @default 'paginatorPlugin'
41  * @static
42  */
43 PaginatorPlugin.NAME = 'pluginScrollViewPaginator';
44
45 /**
46  * The namespace on which the plugin will reside
47  *
48  * @property ScrollViewPaginator.NS
49  * @type String
50  * @default 'pages'
51  * @static
52  */
53 PaginatorPlugin.NS = 'pages';
54
55 /**
56  * The default attribute configuration for the plugin
57  *
58  * @property ScrollViewPaginator.ATTRS
59  * @type Object
60  * @static
61  */
62 PaginatorPlugin.ATTRS = {
63
64     /**
65      * CSS selector for a page inside the scrollview. The scrollview
66      * will snap to the closest page.
67      *
68      * @attribute selector
69      * @type {String}
70      */
71     selector: {
72         value: null
73     },
74     
75     /**
76      * The active page number for a paged scrollview
77      *
78      * @attribute index
79      * @type {Number}
80      * @default 0
81      */
82     index: {
83         value: 0
84     },
85     
86     /**
87      * The total number of pages
88      *
89      * @attribute total
90      * @type {Number}
91      * @default 0
92      */
93     total: {
94         value: 0
95     }
96 };
97
98 Y.extend(PaginatorPlugin, Y.Plugin.Base, {
99
100     /**
101      * Designated initializer
102      *
103      * @method initializer
104      */
105     initializer: function() {
106         var host,
107             paginator = this; // kweight
108
109         host = paginator._host = paginator.get('host');
110
111         paginator.beforeHostMethod('_flickFrame', paginator._flickFrame);
112         paginator.afterHostMethod('_uiDimensionsChange', paginator._calcOffsets);
113         paginator.afterHostEvent('scrollEnd', paginator._scrollEnded);
114         paginator.afterHostEvent('render', paginator._afterRender);
115
116         paginator.after('indexChange', paginator._afterIndexChange);
117     },
118
119     /**
120      * Calculate the page boundary offsets
121      * 
122      * @method _calcOffsets
123      * @protected
124      */
125     _calcOffsets : function() {
126         var host = this._host,
127             cb = host.get(CONTENT_BOX),
128             bb = host.get(BOUNDING_BOX),
129             pageSelector = this.get("selector"),
130             pages,
131             offsets;
132
133         // Pre-calculate min/max values for each page
134         pages = pageSelector ? cb.all(pageSelector) : cb.get("children");
135
136         this.set(TOTAL, pages.size());
137
138         this._pgOff = offsets = pages.get("offsetLeft");
139         offsets.push(host._scrollWidth - bb.get("offsetWidth"));
140     },
141
142     /**
143      * Executed to respond to the flick event, by over-riding the default flickFrame animation. 
144      * This is needed to determine if the next or prev page should be activated.
145      *
146      * @method _flickFrame
147      * @protected
148      */
149     _flickFrame: function() {
150         var host = this._host,
151             velocity = host._currentVelocity,
152
153             inc = velocity < 0,
154
155             pageIndex = this.get(INDEX),
156             pageCount = this.get(TOTAL);
157
158         if (velocity) {
159
160             if (inc && pageIndex < pageCount-1) {
161                 this.set(INDEX, pageIndex+1);
162             } else if (!inc && pageIndex > 0) {
163                 this.set(INDEX, pageIndex-1);
164             }
165         }
166
167         return this._prevent;
168     },
169
170     /**
171      * After host render handler
172      *
173      * @method _afterRender
174      * @protected
175      */
176     _afterRender: function(e) {
177         var host = this._host;
178         host.get("boundingBox").addClass(host.getClassName("paged"));
179     },
180
181     /**
182      * scrollEnd handler detects if a page needs to change
183      *
184      * @method _scrollEnded
185      * @param {Event.Facade}
186      * @protected
187      */
188      _scrollEnded: function(e) {
189          var host = this._host,
190              pageIndex = this.get(INDEX),
191              pageCount = this.get(TOTAL);
192
193
194          if(e.onGestureMoveEnd && !host._flicking) {
195              if(host._scrolledHalfway) {
196                  if(host._scrolledForward && pageIndex < pageCount-1) {
197                      this.set(INDEX, pageIndex+1);
198                  } else if (pageIndex > 0) {
199                      this.set(INDEX, pageIndex-1);
200                  } else {
201                      this.snapToCurrent();
202                  }
203              } else {
204                  this.snapToCurrent();
205              }
206          }
207
208          host._flicking = false;
209      },
210
211     /**
212      * index attr change handler
213      *
214      * @method _afterIndexChange
215      * @protected
216      */
217     _afterIndexChange: function(e) {
218         if(e.src !== UI) {
219             this._uiIndex(e.newVal);
220         }
221     },
222     
223     /**
224      * Update the UI based on the current page index
225      *
226      * @method _uiIndex
227      * @protected
228      */
229     _uiIndex: function(index) {
230         this.scrollTo(index, 350, 'ease-out');
231     },
232
233     /**
234      * Scroll to the next page in the scrollview, with animation
235      *
236      * @method next
237      */
238     next: function() {
239         var index = this.get(INDEX);  
240         if(index < this.get(TOTAL)-1) {
241             this.set(INDEX, index+1);
242         }
243     },
244     
245     /**
246      * Scroll to the previous page in the scrollview, with animation
247      *
248      * @method prev
249      */
250     prev: function() {
251         var index = this.get(INDEX);
252         if(index > 0) {
253             this.set(INDEX, index-1);
254         }
255     },
256     
257     /**
258      * Scroll to a given page in the scrollview, with animation.
259      *
260      * @method scrollTo
261      * @param index {Number} The index of the page to scroll to
262      * @param duration {Number} The number of ms the animation should last
263      * @param easing {String} The timing function to use in the animation
264      */
265     scrollTo: function(index, duration, easing) {
266         var host = this._host,
267             x = host.get(SCROLL_X);
268
269         if(host._scrollsHorizontal) {
270             x = this._pgOff[index];
271
272             host.set(SCROLL_X, x, {
273                 duration: duration,
274                 easing: easing
275             });
276         }
277     },
278     
279     /**
280      * Snaps the scrollview to the currently selected page
281      *
282      * @method snapToCurrent
283      */
284     snapToCurrent: function() {
285         var host = this._host;
286
287         host._killTimer();
288
289
290         host.set(SCROLL_X, this._pgOff[this.get(INDEX)], {
291             duration: 300,
292             easing: 'ease-out'
293         });
294     },
295
296     _prevent: new Y.Do.Prevent()
297
298 });
299
300 Y.namespace('Plugin').ScrollViewPaginator = PaginatorPlugin;
301
302
303 }, '3.3.0' ,{requires:['plugin']});