Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / docs / source / carousel.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 Ext.ns('Ext.ux');
16
17 Ext.ux.Carousel = Ext.extend(Ext.util.Observable, {
18     interval: 3,
19     transitionDuration: 1,
20     transitionType: 'carousel',
21     transitionEasing: 'easeOut',
22     itemSelector: 'img',
23     activeSlide: 0,
24     autoPlay: false,
25     showPlayButton: false,
26     pauseOnNavigate: false,
27     wrap: false,
28     freezeOnHover: false,
29     navigationOnHover: false,
30     hideNavigation: false,
31     width: null,
32     height: null,
33
34     constructor: function(elId, config) {
35         config = config || {};
36         Ext.apply(this, config);
37
38         Ext.ux.Carousel.superclass.constructor.call(this, config);
39
40         this.addEvents(
41             'beforeprev',
42             'prev',
43             'beforenext',
44             'next',
45             'change',
46             'play',
47             'pause',
48             'freeze',
49             'unfreeze'
50         );
51
52         this.el = Ext.get(elId);
53         this.slides = this.els = [];
54         
55         if(this.autoPlay || this.showPlayButton) {
56             this.wrap = true;
57         };
58
59         if(this.autoPlay && typeof config.showPlayButton === 'undefined') {
60             this.showPlayButton = true;
61         }
62
63         this.initMarkup();
64         this.initEvents();
65
66         if(this.carouselSize > 0) {
67             this.refresh();
68         }
69     },
70
71     initMarkup: function() {
72         var dh = Ext.DomHelper;
73         
74         this.carouselSize = 0;
75         var items = this.el.select(this.itemSelector);
76         this.els.container = dh.append(this.el, {cls: 'ux-carousel-container'}, true);
77         this.els.slidesWrap = dh.append(this.els.container, {cls: 'ux-carousel-slides-wrap'}, true);
78
79         this.els.navigation = dh.append(this.els.container, {cls: 'ux-carousel-nav'}, true).hide();
80         this.els.caption = dh.append(this.els.navigation, {tag: 'h2', cls: 'ux-carousel-caption'}, true);
81         this.els.navNext = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-next'}, true);
82         if(this.showPlayButton) {
83             this.els.navPlay = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-play'}, true)
84         }
85         this.els.navPrev = dh.append(this.els.navigation, {tag: 'a', href: '#', cls: 'ux-carousel-nav-prev'}, true);
86
87         // set the dimensions of the container
88         this.slideWidth = this.width || this.el.getWidth(true);
89         this.slideHeight = this.height || this.el.getHeight(true);
90         this.els.container.setStyle({
91             width: this.slideWidth + 'px',
92             height: this.slideHeight + 'px'
93         });
94
95         this.els.caption.setWidth((this.slideWidth - (this.els.navNext.getWidth()*2) - (this.showPlayButton ? this.els.navPlay.getWidth() : 0) - 20) + 'px')
96         
97         items.appendTo(this.els.slidesWrap).each(function(item) {
98             item = item.wrap({cls: 'ux-carousel-slide'});
99             this.slides.push(item);
100             item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px');
101         }, this);
102         this.carouselSize = this.slides.length;
103         if(this.navigationOnHover) {
104             this.els.navigation.setStyle('top', (-1*this.els.navigation.getHeight()) + 'px');
105         }
106         this.el.clip();
107     },
108
109     initEvents: function() {
110         this.els.navPrev.on('click', function(ev) {
111             ev.preventDefault();
112             var target = ev.getTarget();
113             target.blur();            
114             if(Ext.fly(target).hasClass('ux-carousel-nav-disabled')) return;
115             this.prev();
116         }, this);
117
118         this.els.navNext.on('click', function(ev) {
119             ev.preventDefault();
120             var target = ev.getTarget();
121             target.blur();
122             if(Ext.fly(target).hasClass('ux-carousel-nav-disabled')) return;
123             this.next();
124         }, this);
125
126         if(this.showPlayButton) {
127             this.els.navPlay.on('click', function(ev){
128                 ev.preventDefault();
129                 ev.getTarget().blur();
130                 if(this.playing) {
131                     this.pause();
132                 }
133                 else {
134                     this.play();
135                 }
136             }, this);
137         };
138
139         if(this.freezeOnHover) {
140             this.els.container.on('mouseenter', function(){
141                 if(this.playing) {
142                     this.fireEvent('freeze', this.slides[this.activeSlide]);
143                     Ext.TaskMgr.stop(this.playTask);
144                 }
145             }, this);
146             this.els.container.on('mouseleave', function(){
147                 if(this.playing) {
148                     this.fireEvent('unfreeze', this.slides[this.activeSlide]);
149                     Ext.TaskMgr.start(this.playTask);
150                 }
151             }, this, {buffer: (this.interval/2)*1000});
152         };
153
154         if(this.navigationOnHover) {
155             this.els.container.on('mouseenter', function(){
156                 if(!this.navigationShown) {
157                     this.navigationShown = true;
158                     this.els.navigation.stopFx(false).shift({
159                         y: this.els.container.getY(),
160                         duration: this.transitionDuration
161                     })
162                 }
163             }, this);
164
165             this.els.container.on('mouseleave', function(){
166                 if(this.navigationShown) {
167                     this.navigationShown = false;
168                     this.els.navigation.stopFx(false).shift({
169                         y: this.els.navigation.getHeight() - this.els.container.getY(),
170                         duration: this.transitionDuration
171                     })
172                 }
173             }, this);
174         }
175
176         if(this.interval && this.autoPlay) {
177             this.play();
178         };
179     },
180
181     prev: function() {
182         if (this.fireEvent('beforeprev') === false) {
183             return;
184         }
185         if(this.pauseOnNavigate) {
186             this.pause();
187         }
188         this.setSlide(this.activeSlide - 1);
189
190         this.fireEvent('prev', this.activeSlide);        
191         return this; 
192     },
193     
194     next: function() {
195         if(this.fireEvent('beforenext') === false) {
196             return;
197         }
198         if(this.pauseOnNavigate) {
199             this.pause();
200         }
201         this.setSlide(this.activeSlide + 1);
202
203         this.fireEvent('next', this.activeSlide);        
204         return this;         
205     },
206
207     play: function() {
208         if(!this.playing) {
209             this.playTask = this.playTask || {
210                 run: function() {
211                     this.playing = true;
212                     this.setSlide(this.activeSlide+1);
213                 },
214                 interval: this.interval*1000,
215                 scope: this
216             };
217             
218             this.playTaskBuffer = this.playTaskBuffer || new Ext.util.DelayedTask(function() {
219                 Ext.TaskMgr.start(this.playTask);
220             }, this);
221
222             this.playTaskBuffer.delay(this.interval*1000);
223             this.playing = true;
224             if(this.showPlayButton) {
225                 this.els.navPlay.addClass('ux-carousel-playing');
226             }
227             this.fireEvent('play');
228         }        
229         return this;
230     },
231
232     pause: function() {
233         if(this.playing) {
234             Ext.TaskMgr.stop(this.playTask);
235             this.playTaskBuffer.cancel();
236             this.playing = false;
237             if(this.showPlayButton) {
238                 this.els.navPlay.removeClass('ux-carousel-playing');
239             }
240             this.fireEvent('pause');
241         }        
242         return this;
243     },
244         
245     clear: function() {
246         this.els.slidesWrap.update('');
247         this.slides = [];
248         this.carouselSize = 0;
249         this.pause();
250         return this;
251     },
252     
253     add: function(el, refresh) {
254         var item = Ext.fly(el).appendTo(this.els.slidesWrap).wrap({cls: 'ux-carousel-slide'});
255         item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px');
256         this.slides.push(item);                        
257         if(refresh) {
258             this.refresh();
259         }        
260         return this;
261     },
262     
263     refresh: function() {
264         this.carouselSize = this.slides.length;
265         this.els.slidesWrap.setWidth((this.slideWidth * this.carouselSize) + 'px');
266         if(this.carouselSize > 0) {
267             if(!this.hideNavigation) this.els.navigation.show();
268             this.activeSlide = 0;
269             this.setSlide(0, true);
270         }                
271         return this;        
272     },
273     
274     setSlide: function(index, initial) {
275         if(!this.wrap && !this.slides[index]) {
276             return;
277         }
278         else if(this.wrap) {
279             if(index < 0) {
280                 index = this.carouselSize-1;
281             }
282             else if(index > this.carouselSize-1) {
283                 index = 0;
284             }
285         }
286         if(!this.slides[index]) {
287             return;
288         }
289
290         this.els.caption.update(this.slides[index].child(':first-child', true).title || '');
291         var offset = index * this.slideWidth;
292         if (!initial) {
293             switch (this.transitionType) {
294                 case 'fade':
295                     this.slides[index].setOpacity(0);
296                     this.slides[this.activeSlide].stopFx(false).fadeOut({
297                         duration: this.transitionDuration / 2,
298                         callback: function(){
299                             this.els.slidesWrap.setStyle('left', (-1 * offset) + 'px');
300                             this.slides[this.activeSlide].setOpacity(1);
301                             this.slides[index].fadeIn({
302                                 duration: this.transitionDuration / 2
303                             });
304                         },
305                         scope: this
306                     })
307                     break;
308
309                 default:
310                     var xNew = (-1 * offset) + this.els.container.getX();
311                     this.els.slidesWrap.stopFx(false);
312                     this.els.slidesWrap.shift({
313                         duration: this.transitionDuration,
314                         x: xNew,
315                         easing: this.transitionEasing
316                     });
317                     break;
318             }
319         }
320         else {
321             this.els.slidesWrap.setStyle('left', '0');
322         }
323
324         this.activeSlide = index;
325         this.updateNav();
326         this.fireEvent('change', this.slides[index], index);
327     },
328
329     updateNav: function() {
330         this.els.navPrev.removeClass('ux-carousel-nav-disabled');
331         this.els.navNext.removeClass('ux-carousel-nav-disabled');
332         if(!this.wrap) {
333             if(this.activeSlide === 0) {
334                 this.els.navPrev.addClass('ux-carousel-nav-disabled');
335             }
336             if(this.activeSlide === this.carouselSize-1) {
337                 this.els.navNext.addClass('ux-carousel-nav-disabled');
338             }
339         }
340     }
341 });</pre>    
342 </body>
343 </html>