1. #1
    Sencha Premium Member TheStreet's Avatar
    Join Date
    Sep 2012
    Posts
    63
    Vote Rating
    0
    TheStreet is on a distinguished road

      0  

    Default Dynamic Carousel setActiveItem MVC trouble

    Dynamic Carousel setActiveItem MVC trouble


    Hi All,

    I'm having trouble getting the setActiveItem method to work how I need it to. This is my first time using Sencha Touch. I have built a few apps with Ext 3.1 and Ext 4.0 so I thought I had a good base to start on, but this particular problem giving me trouble.

    I have a container with Mitchell Simeons' ST2 Accordion docked left with several lists filled with data loaded from stores. On list item tap I fire a custom method in my controller to load the corresponding store and iterate through each record to build out an items array for a generic carousel view filled with a container that has a template for each carousel item. I then try to setActiveItem by id like I used to with Ext 4. What is happening is that it is setting the wrong item active, it set's the last item in the carousel active instead of the one I'm trying to send in.

    I tried using an id with type 'number, when that didn't work I tried converting the id to a string, when that didn't work I tried using Ext.getCmp(id). If someone can shed some light on what I need to do to get this working properly it would be much appreciated.

    I was able to, on init, set the active item using index 0, but my app needs more specificity than that.

    Code:

    Controller:
    Code:
    Ext.define('TheStreet.controller.News', {
        extend: 'Ext.app.Controller',
        requires: ['TheStreet.view.Article'],
        config: {
            refs: {
                newsMain         : 'newsmain',
                newsFeed         : 'newsfeed',
                newsMenu         : 'newsmenu',
                article          : 'article',
                articleCarousel  : '#articleCarousel',
                sectionTitle     : 'button[cls=x-section-title]',
                splash           : 'splash',
                sectionCarousel  : 'sectionCarousel'
            },
            control: {
                newsfeed: {
                    select          : 'onArticleTap',
                    selectionchange : 'onSelectionChange'
                },
                article: {
                    widthChange : 'newsWidthChanged',
                    viewready   : 'fillCarousel'
                },
                sectionTitle: {
                    tap: 'onSectionTitleTap'
                },
                articleCarousel: {
                    viewready: 'onNewsInitialize'
                }
            }
        },
    
    
        init: function() {
            // var me = this;
    
    
            // this.newsmenu    = this.getNewsMenu();
            // this.newsmain    = this.getNewsMain();
            // this.newsfeed    = this.getNewsFeed();
            // this.article     = this.getArticle();
            // this.articleCard = this.getArticleCard();
            // this.splashCard  = this.getSplashCard();
            console.log('News Controller Initialized');
    
    
        },
    
    
        newsWidthChanged: function(component, value, oldValue, eOpts) {
            console.log('changed: ', component);
        },
    
    
        launch: function() {
            // var topnews = this.getTopNews(),
            //     topNewsStore = Ext.getStore('TopNews');
            // console.log('topNews:', topnews);
            // console.log('topnews xtypes:', topnews.getXTypes());
        },
    
    
        onNewsInitialize: function() {
            var articleCarousel = this.getArticleCarousel();
            console.log('init carousel', articleCarousel);
            this.loadCurrentSectionArticles(articleCarousel, 'StockPicks', 0);
        },
    
    
        onArticleTap: function(selection, record, eOpts) {
            var newsmenu        = this.getNewsMenu(), 
                newsmain        = this.getNewsMain(),
                articleCarousel = this.getArticleCarousel(),
                sectionCarousel = this.getSectionCarousel(),
                article         = this.getArticle(),
                storeId         = record.stores[0].getStoreId(),
                recordId        = record.data.articleId;
    
    
            console.log('Selection');
            console.log('==========================');
            console.log(selection);
            console.log('Record');
            console.log('==========================');
            console.log(record);
            console.log('eOpts');
            console.log('==========================');
            console.log(eOpts);
    
    
            console.log('article component:',Ext.getCmp(recordId));
    
    
            console.log('store id', storeId);
            //newsmenu.deselectAllLists();
            //sectionCarousel.hide();
            this.loadCurrentSectionArticles(articleCarousel, storeId, recordId);
            console.log('items',articleCarousel.getItems());
    
    
            console.log('record id type', typeof(recordId));
            //articleCarousel.setActiveItem(recordId);
            console.log('active item',articleCarousel.getActiveItem());
        },
    
    
        onSectionTitleTap: function(btn) {
            console.log('Button Title', btn.config.text);
            var splash          = this.getSplash(),
                sectionCarousel = this.getSectionCarousel(),
                article         = this.getArticle(),
                //articleCard   = this.getArticleCard(),
                section         = btn.config.text.replace(/\s/g, '');
    
    
            console.log('section', section);
    
    
            article.hide();
            splash.setStore(section);
            sectionCarousel.show();
        },
    
    
        onSelectionChange: function(changed, records, eOpts) { 
            //console.log(changed, records, eOpts);
        },
    
    
        loadCurrentSectionArticles: function(carousel, store, item) {
            console.log('store passed', store);
            var store = Ext.getStore(store),
                storeData = store.getData(),
                items = [],
                initItem = item,
                changeItem = item.toString();
    
    
            console.log('store data', storeData);
            
            store.each(function(rec) {
                var recId = rec.data.articleId;
                items.push(Ext.create('TheStreet.view.Article', {
                    record: rec,
                    id: recId.toString()
                }));
            });
    
    
            console.log('setActiveItem type', typeof(initItem));
            console.log('activeItem passed', Ext.getCmp(changeItem));
    
    
            carousel.setItems(items);
            if (typeof(item) === 'number'){
                carousel.setActiveItem(initItem);
            } else {
                carousel.setActiveItem(Ext.getCmp(changeItem));
            }
            console.log('carousel items', carousel.getItems());
        }
    });
    Views:
    Code:
    Ext.define("TheStreet.view.Article", {   
        extend: 'Ext.Container',
        xtype: 'article',
    
    
        config: {
            //id: articleId,
            autoDestroy: true,
            cls: 'articletpl',
            layout: 'fit',
            scrollable: {
                direction: 'vertical',
                directionLock: true
            },
            tpl: new Ext.XTemplate(
                '<div class="sector">{sector}</div>',
                '<div class="headline">{headline}</div>',
                '<div class="byline">by {byLine}</div>',
                '<div class="postedOn">posted on {[this.formatDate(values.publishDate)]}</div>',
                '<div class="ticker">Ticker: {tickers}</div>',
                '<div class="body"><img class="largeThumb" src="{largeThumb}" alt="" />{body}</article>',
                {
                    // XTemplate configuration:
                    compiled: true,
                    formatDate: function(date){
                        var newDate = Ext.Date.parse(date, 'm-d-YTG:i'),
                            formattedDate = Ext.Date.format(newDate, 'F j,Y g:ia');
                        return formattedDate;
                    }
                }
            )
        }
    });
    
    Ext.define("TheStreet.view.ArticleCarousel", {   
        extend: 'Ext.Carousel',
        xtype: 'articleCarousel',
    
    
        requires: ['TheStreet.view.Article'],
    
    
        config: {
            autoDestroy: true,
            id: 'articleCarousel',
            items: []
            //layout: 'card',
            //hidden: true
        },
    
    
        initialize : function() {
            var me = this;
    
    
            me.on('painted', function() {
                me.fireEvent('viewready', me);
            }, null, { single : true });
    
    
            me.callParent();
        }
    });
    Please excuse all the console.logs, I was too lazy to remove them.

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,219
    Vote Rating
    859
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Is typeof(initItem) return string or number?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha Premium Member TheStreet's Avatar
    Join Date
    Sep 2012
    Posts
    63
    Vote Rating
    0
    TheStreet is on a distinguished road

      0  

    Default


    Right...I forgot to mention that that was the actual problem. No matter what I do it always seems to be a number. Which is why it's always treating it as an index.

  4. #4
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,219
    Vote Rating
    859
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    The actual id of the component is a string due to your toString() call on the record id but you are trying to make a component active that the id is a number therefore probably failing there as the type can make a difference..

    Like if you have

    Code:
    "1" === 1
    That will be false. If you have

    Code:
    "1" == 1
    That will be true
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  5. #5
    Sencha Premium Member TheStreet's Avatar
    Join Date
    Sep 2012
    Posts
    63
    Vote Rating
    0
    TheStreet is on a distinguished road

      0  

    Default


    Right...that is how Javascript works. Now that I fixed the typing issue by adding letters to the id I'm getting "Uncaught Error: [ERROR][Ext.Container#factoryItem] Invalid config, must be a valid config object ". I'm trying to understand how setActiveItem works. If it gets a number as a type it assumes it's an index? If it get's an object, it assumes it's a config object and tries to create a new card? How do I get it to just show a card that is already an item in the carousel?

  6. #6
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,219
    Vote Rating
    859
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Yes, best way to figure out how something works is to set a breakpoint and step into code. In the applyActiveItem method in Ext.Container, it checks the type of what you pass in. If it's a number, it does assume it's an index. If you pass a string it will try to find it via the id/itemId
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

Thread Participants: 1

Tags for this Thread