2 Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
8 YUI.add('scrollview-paginator', function(Y) {
11 * Provides a plugin, which adds pagination support to ScrollView instances
13 * @module scrollview-paginator
16 var UI = Y.ScrollView.UI_SRC,
20 BOUNDING_BOX = "boundingBox",
21 CONTENT_BOX = "contentBox";
24 * Scrollview plugin that adds support for paging
26 * @class ScrollViewPaginator
28 * @extends Plugin.Base
31 function PaginatorPlugin() {
32 PaginatorPlugin.superclass.constructor.apply(this, arguments);
36 * The identity of the plugin
38 * @property ScrollViewPaginator.NAME
40 * @default 'paginatorPlugin'
43 PaginatorPlugin.NAME = 'pluginScrollViewPaginator';
46 * The namespace on which the plugin will reside
48 * @property ScrollViewPaginator.NS
53 PaginatorPlugin.NS = 'pages';
56 * The default attribute configuration for the plugin
58 * @property ScrollViewPaginator.ATTRS
62 PaginatorPlugin.ATTRS = {
65 * CSS selector for a page inside the scrollview. The scrollview
66 * will snap to the closest page.
76 * The active page number for a paged scrollview
87 * The total number of pages
98 Y.extend(PaginatorPlugin, Y.Plugin.Base, {
101 * Designated initializer
103 * @method initializer
105 initializer: function() {
107 paginator = this; // kweight
109 host = paginator._host = paginator.get('host');
111 paginator.beforeHostMethod('_flickFrame', paginator._flickFrame);
112 paginator.afterHostMethod('_uiDimensionsChange', paginator._calcOffsets);
113 paginator.afterHostEvent('scrollEnd', paginator._scrollEnded);
114 paginator.afterHostEvent('render', paginator._afterRender);
116 paginator.after('indexChange', paginator._afterIndexChange);
120 * Calculate the page boundary offsets
122 * @method _calcOffsets
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"),
133 // Pre-calculate min/max values for each page
134 pages = pageSelector ? cb.all(pageSelector) : cb.get("children");
136 this.set(TOTAL, pages.size());
138 this._pgOff = offsets = pages.get("offsetLeft");
139 offsets.push(host._scrollWidth - bb.get("offsetWidth"));
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.
146 * @method _flickFrame
149 _flickFrame: function() {
150 var host = this._host,
151 velocity = host._currentVelocity,
155 pageIndex = this.get(INDEX),
156 pageCount = this.get(TOTAL);
160 if (inc && pageIndex < pageCount-1) {
161 this.set(INDEX, pageIndex+1);
162 } else if (!inc && pageIndex > 0) {
163 this.set(INDEX, pageIndex-1);
167 return this._prevent;
171 * After host render handler
173 * @method _afterRender
176 _afterRender: function(e) {
177 var host = this._host;
178 host.get("boundingBox").addClass(host.getClassName("paged"));
182 * scrollEnd handler detects if a page needs to change
184 * @method _scrollEnded
185 * @param {Event.Facade}
188 _scrollEnded: function(e) {
189 var host = this._host,
190 pageIndex = this.get(INDEX),
191 pageCount = this.get(TOTAL);
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);
201 this.snapToCurrent();
204 this.snapToCurrent();
208 host._flicking = false;
212 * index attr change handler
214 * @method _afterIndexChange
217 _afterIndexChange: function(e) {
219 this._uiIndex(e.newVal);
224 * Update the UI based on the current page index
229 _uiIndex: function(index) {
230 this.scrollTo(index, 350, 'ease-out');
234 * Scroll to the next page in the scrollview, with animation
239 var index = this.get(INDEX);
240 if(index < this.get(TOTAL)-1) {
241 this.set(INDEX, index+1);
246 * Scroll to the previous page in the scrollview, with animation
251 var index = this.get(INDEX);
253 this.set(INDEX, index-1);
258 * Scroll to a given page in the scrollview, with animation.
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
265 scrollTo: function(index, duration, easing) {
266 var host = this._host,
267 x = host.get(SCROLL_X);
269 if(host._scrollsHorizontal) {
270 x = this._pgOff[index];
272 host.set(SCROLL_X, x, {
280 * Snaps the scrollview to the currently selected page
282 * @method snapToCurrent
284 snapToCurrent: function() {
285 var host = this._host;
290 host.set(SCROLL_X, this._pgOff[this.get(INDEX)], {
296 _prevent: new Y.Do.Prevent()
300 Y.namespace('Plugin').ScrollViewPaginator = PaginatorPlugin;
303 }, '3.3.0' ,{requires:['plugin']});