View Full Version : Ext.ux.touch.InfiniteCarousel v3.0b1

24 Mar 2011, 8:38 AM
I have had an Infinite Carousel since the beginning days of Sencha Touch but no one really said anything about it. Took a look at my GitHub repo and saw that a bunch of people were looking at it. So I rewrote it today to work with Sencha Touch 1.1.0. It has a new name (from Ext.ux.InfiniteCarousel to my naming convention Ext.ux.touch.InfiniteCarousel), a new license (from GPL v3 to MIT) and it lost a little wait (about 40 lines).

GitHub: https://github.com/mitchellsimoens/Ext.ux.touch.InfiniteCarousel
Demo: http://www.simoens.org/Sencha-Projects/demos/

One thing I want to do is make it be able to wrap around. So when you get to the end, it will start adding the first items to the end.

Check out this post for update on version 3.0b1: http://www.sencha.com/forum/showthread.php?127923-Ext.ux.touch.InfiniteCarousel-v3.0b1&p=592077&viewfull=1#post592077

24 Mar 2011, 10:21 AM
Hey Mitchell, I sent you a private message... don't know if you were notified. :)

28 Mar 2011, 2:05 PM
Hey mitchell.

I don't know if you already found this but if the store has less records than the number of cards that the Carousel is preconfigured to load (5 in this case), the code inside the 'createCardCmp' function breaks because the 'get' method can't be called on undefined records.

I added this inside the initComponent function:

initComponent: function() {
var me = this;

me.on( "beforecardswitch", me.onBeforeCardSwitching, me );
me.on( "cardswitch", me.onCardSwitching, me );
me.store.on( "datachanged", me.onDataChanged, me );


if(me.numCards > me.store.getCount()) {
me.numCards = me.store.getCount();

if (me.store.getCount() > 0) {

16 Apr 2011, 10:13 AM
Just rewrote this totally again today. Added some new features:

numPages config. This is the number of pages to show at one time. (Default is 3)
allowWrap config. If set to true (default is true), will wrap around if at end or beginning.
cmpField config. This is the field in the Model that will hold the JSON that is the Component config. (Default is 'cmp')

I rethought how to get the Components and even though the code has increased, I believe to be much more robust and efficient.

Hope you love all the comments also! What I want to still get to is handle Store data change. I will get this, but thinking best thing way to handle it.

20 Apr 2011, 11:50 AM
Here's one for you ... how would I tweek this code to wait for the store to load ? Right now you can't create a 'stub' for the carousel until the store is completely loaded.



20 Apr 2011, 12:02 PM
Here's one for you ... how would I tweek this code to wait for the store to load ? Right now you can't create a 'stub' for the carousel until the store is completely loaded.



Once I get the datachanged event wired in, it should then build the items.

What I will be doing is remove all cards and remake the cards based on the store's data then. So when I remake the items, this should add the cards if the store wasn't loaded when the Carousel was instantiated.

20 Apr 2011, 2:52 PM
I've modified your code a bit - and it works perfectly (waiting for store to load) however I cannot set the active item :-( Care to look and see what I'm missing ?


Ext.apply(me, {
defaultType : 'panel', //in case xtype is not specified in cmpField of Model instance
items : [] // me.buildItems()

me.supr().initComponent.call(me); //call the superclass to not break Ext.Carousel

store.on('load', function() {
var items = this.add(this.buildItems());

Ext.iterate(items, function(item) {
if (item.makeActive) {
this.getLayout().setActiveItem(i); //make this item active
delete item.makeActive; //remove unneeded property on Component

}, this );

However the setActiveItem(i) is bombing with an error of "result expression 'newCard.el' [undefined] is not an object" the the sencha-touch.js file (onBeforeCardSwitch method)

Brian Tuohy
29 Apr 2011, 9:23 AM
Mitchell . . . Kudos . . . learned a lot from this Example . . . thanks keep up the good work!

2 May 2011, 5:29 AM
I had a couple minutes to include the handling of the store datachange event. It's up on GitHub now. Worked for my simple testing but didn't have a whole lot of time. It loads the static data into the Store after 2 seconds (prob need masking to show that it's loading the store). You can set activePage to any index and in my test it worked perfectly!

Brian Tuohy
3 May 2011, 2:38 PM

I have tried for a week to get my feed to populate the CMP field. If I can get some ideas how to do this I would be very appreciative. I have got the feed populating a EXT.Panel but I can not get it to populate the Carousel . . .

<script type="text/javascript">

tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: true,
onReady: function() {

var header = new Ext.Toolbar({
dock : 'top',
html: '<img src="/mobile/test/infinante/graphics/logo.png" width="320" height="52" />',
height: '52px'


var bar = new Ext.TabBar({
dock : 'bottom',
ui : 'dark',
pack: 'center',

items: [
text: 'Home',
iconCls: 'home',
text: 'Search',
iconCls: 'search',

text: 'Settings',
iconCls: 'settings',

text: 'More',
iconCls: 'more',


var timeline = new Ext.Component({
tpl: [
'<tpl for=".">',
'<div class="tweet">',
'<div class="avatar"><img src="{largeImageUrl}" /></div>',
'<div class="tweet-content">',
'<h2>Status: {status}</h2>',
'<h2>Sold Out: {isSoldOut}</h2>',
'<div><a href="{dealUrl}">Get Offer!</a></div>',


url: 'http://api.groupon.com/v2/deals.json',
callbackKey: 'callback',
params: {
client_id: 'xxxx3b721677c9997xxxx12743097702d3f0cxxxx',
show: 'all',

callback: function(data) {
var tweetList = data.deals;
timeline.update(tweetList); // Update the tweets in timeline



Ext.regModel('Pages', {
fields : [ 'cmp' ]

var store = new Ext.data.Store({
model : 'Pages',
loadStaticData: function() {
var data = [
{ cmp : '{ "xtype" : "panel", "html" : tweetList }' }, //xtype defaults to panel
{ cmp : '{ "xtype" : "panel", "html" : "Page Index : 2" }' },
{ cmp : '{ "xtype" : "panel", "html" : "Page Index : 3" }' },
{ cmp : '{ "xtype" : "panel", "html" : "Page Index : 4" }' },
{ cmp : '{ "xtype" : "panel", "html" : "Page Index : 5" }' }


new Ext.ux.touch.InfiniteCarousel({
dockedItems: [bar, header],
fullscreen: true,
scroll: 'vertical',
store: store

setTimeout(function() {
}, 1000);


5 May 2011, 1:53 AM

A suggestion about InifiniteCarousel.
The component is intersting, but I submit a suggestion that I might improve it.

I have a List (with disclosure) presenting messages of user. When user clicks on disclosure icon, he goes to the details of message. I will want to add a carousel for details message, so he can see other messages without return to list.
I could use your control as it, but I thinnk that it will not be optimized. Because I will need to fill the items array with as much panels that there are messages.
A alternative could be to define the config as it :
- store : contains records to display in the carousel
- items : only one component to update with the current record in store. This component should have a template defined, and it will be updated when the carousel is switched :


20 May 2011, 5:55 PM
Right now you can't create a 'stub' for the carousel until the store is completely loaded.

24 May 2011, 8:08 AM
Hello, i have a question. This infinite carousel only render as a fullscreen: true?
I fail to make it render into a panel.
I can put two carousel on the same panel?
This should pop up when I click in a thumbnail, and show an image gallery.
The last part is ready (the image gallery) but I cant render the carousel into a float panel.

24 May 2011, 11:49 AM
Thanks, but I can do it, if someone needs, I leave the code:

function renderCarousel (w, h) {

car = new Ext.ux.touch.InfiniteCarousel({
store : store,
style : 'background-color: #FFF; color:black;',
bodyBorder : '0',
bodyMargin : 0,
bodyPadding : '0px',
width : w,
height : h,
centered : true,
enterAnimation : 'pop',
exitAnimation : 'pop',
hideOnMaskTap : true,
floating : true,
modal : true



Thanks ...