1. #1
    Sencha User
    Join Date
    Jun 2012
    Posts
    23
    Vote Rating
    1
    danrosshoward is on a distinguished road

      0  

    Default XML Nested List Example

    XML Nested List Example


    I'm sure there is a better way to post this information, but the is the best way I know of for now... so, buckle up and hang on for an extremely long post.

    I needed to use a nested list, based on XML data, but could not get it to work with Sencha Touch's nested list, so I rolled my own. Please improve it in any way you can.

    The basic ingredients for this recipe are:
    • an xml file
    • a navigation view
    • one high level view (used as default in navigation view)
    • several lower level views
    • one high level store
    • several 'temporary' stores
    • several associated models
    • several 'temporary store' models
    For the sake of simplicity, I did not use any controllers. Instead, I just used listeners.

    Here are the files. There are 15 of them to make a three-tiered nested list.

    app.js
    HTML Code:
    Ext.application({
        name: 'nestedXMLexample',
        requires: [
            'Ext.data.Store'
        ],
        views: [
            'TheNavigationView',
            'HigherLevelListView',
            'LowestTempListView',
            'MiddleTempListView'
                ],
        models: [
            'TopLevelModel',
            'LowestLevelModel',
            'MiddleLevelModel',
            'MiddleTemporaryStoreModel',
            'LowestTemporaryStoreModel'
        ],
        stores: [
            'AssociatedModelsStore',
            'MiddleTemporaryStore',
            'LowestTemporaryStore'
        ],    
    
        launch: function() {
    
            // Initialize the main view 
            Ext.Viewport.add(Ext.create('nestedXMLexample.view.TheNavigationView'));
        },
    });
    index.html
    HTML Code:
    <!DOCTYPE HTML>
    <html manifest="" lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>nestedXMLexample</title>
        <style type="text/css">
             /**
             * Example of an initial loading indicator.
             * It is recommended to keep this as minimal as possible to provide instant feedback
             * while other resources are still being loaded for the first time
             */
            html, body {
                height: 100%;
                background-color: #1985D0
            }
            #appLoadingIndicator {
                position: absolute;
                top: 50%;
                margin-top: -15px;
                text-align: center;
                width: 100%;
                height: 30px;
                -webkit-animation-name: appLoadingIndicator;
                -webkit-animation-duration: 0.5s;
                -webkit-animation-iteration-count: infinite;
                -webkit-animation-direction: linear;
            }
    
            #appLoadingIndicator > * {
                background-color: #FFFFFF;
                display: inline-block;
                height: 30px;
                -webkit-border-radius: 15px;
                margin: 0 5px;
                width: 30px;
                opacity: 0.8;
            }
    
            @-webkit-keyframes appLoadingIndicator{
                0% {
                    opacity: 0.8
                }
                50% {
                    opacity: 0
                }
                100% {
                    opacity: 0.8
                }
            }
        </style>
        <!-- The line below must be kept intact for Sencha Command to build your application -->
        <script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>
    </head>
    <body>
        <div id="appLoadingIndicator">
            <div></div>
            <div></div>
            <div></div>
        </div></body>
    </html>
    structuredSampleXML.xml
    HTML Code:
    <TopAlphaGrouper>
        <TopAlphaItem TopAlphaItemAttributeOne="A">
            <RomanGrouper>
                <RomanItem RomanItemAttributeOne="I">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="a"/>
                    </LowerAlphaGrouper>
                </RomanItem>
                <RomanItem RomanItemAttributeOne="II">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="a"/>
                        <LowerAlphaItem LowerAlphaAttribute="b"/>
                     </LowerAlphaGrouper>
                </RomanItem>
                <RomanItem RomanItemAttributeOne="III">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="a"/>
                        <LowerAlphaItem LowerAlphaAttribute="b"/>
                        <LowerAlphaItem LowerAlphaAttribute="c"/>
                    </LowerAlphaGrouper>
                </RomanItem>
                            <RomanItem RomanItemAttributeOne="IV">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="a"/>
                        <LowerAlphaItem LowerAlphaAttribute="b"/>
                        <LowerAlphaItem LowerAlphaAttribute="c"/>
                        <LowerAlphaItem LowerAlphaAttribute="d"/>
                    </LowerAlphaGrouper>
                </RomanItem>
            </RomanGrouper>
        </TopAlphaItem>
        <TopAlphaItem TopAlphaItemAttributeOne="B">
            <RomanGrouper>
                <RomanItem RomanItemAttributeOne="X">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="z"/>
                        <LowerAlphaItem LowerAlphaAttribute="y"/>
                        <LowerAlphaItem LowerAlphaAttribute="x"/>
                        <LowerAlphaItem LowerAlphaAttribute="j"/>
                    </LowerAlphaGrouper>
                </RomanItem>
                <RomanItem RomanItemAttributeOne="II">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="a"/>
                        <LowerAlphaItem LowerAlphaAttribute="b"/>
                        <LowerAlphaItem LowerAlphaAttribute="c"/>
                        <LowerAlphaItem LowerAlphaAttribute="d"/>
                    </LowerAlphaGrouper>
                </RomanItem>
            </RomanGrouper>
        </TopAlphaItem>
        <TopAlphaItem TopAlphaItemAttributeOne="C"/>
        <TopAlphaItem TopAlphaItemAttributeOne="D">
            <RomanGrouper>
                <RomanItem RomanItemAttributeOne="XLII">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="alpha"/>
                        <LowerAlphaItem LowerAlphaAttribute="beta"/>
                        <LowerAlphaItem LowerAlphaAttribute="gamma"/>
                        <LowerAlphaItem LowerAlphaAttribute="delta"/>
                    </LowerAlphaGrouper>
                </RomanItem>
                <RomanItem RomanItemAttributeOne="MMXII">
                    <LowerAlphaGrouper>
                        <LowerAlphaItem LowerAlphaAttribute="This"/>
                        <LowerAlphaItem LowerAlphaAttribute="is"/>
                        <LowerAlphaItem LowerAlphaAttribute="the"/>
                        <LowerAlphaItem LowerAlphaAttribute="current"/>
                        <LowerAlphaItem LowerAlphaAttribute="year"/>
                    </LowerAlphaGrouper>
                </RomanItem>
            </RomanGrouper>
        </TopAlphaItem>
        <TopAlphaItem TopAlphaItemAttributeOne="E"/>
    </TopAlphaGrouper>
    TheNavigationView.js
    HTML Code:
    Ext.define('nestedXMLexample.view.TheNavigationView', {
        extend: 'Ext.navigation.View',
        id: 'theNavigationViewId',
        xtype: 'theNavigationViewXtype',
        title: 'Navigation View Title',
        requires: [
            'nestedXMLexample.view.HigherLevelListView',
            'nestedXMLexample.view.MiddleTempListView',
            'nestedXMLexample.view.LowestTempListView'
        ],
            config: {
            items: [{
                xtype:'higherLevelListXtype',
            }],
                listeners: {
            back: function(){
                console.log('back tapped');
                console.log(this.getActiveItem().getStore());
                var tempStore=Ext.getStore('middleTemporaryStoreId');
                var lowTempStore=Ext.getStore('lowestMiddleTemporaryStoreId')
                if(this.getActiveItem().getStore()==tempStore){
                    lowTempStore.setData("");
                }
                else{
                tempStore.setData("");
                }
                console.log('store emptied');
            }
        }
        } 
    });
    HigherLevelListView.js
    HTML Code:
    Ext.define("nestedXMLexample.view.HigherLevelListView", {
        extend: 'Ext.List',
        xtype: 'higherLevelListXtype',
        config: {
            fullscreen: true,
            store: 'associatedModelsStoreId',
            scrollable: true,
            itemTpl: new Ext.XTemplate(
                '<tpl for==".">
                    '<tpl if="TopAlphaItemAttributeOne==\'A\'"><div>{TopAlphaItemAttributeOne}</div><div style="color:red"><small> {TopLevelListOfChildren}</small></div></tpl>'+
                   '<tpl if="TopAlphaItemAttributeOne!=\'A\'"><div>{TopAlphaItemAttributeOne}</div><div style="color:green"><small> {TopLevelListOfChildren}</small></div></tpl>'+
                '</tpl>'
            ),
            listeners: {
                itemtap: function(list, index, element, record){
                    console.log('item tapped in main view');
                    var assocModelStore=Ext.getStore('associatedModelsStoreId');
                    var tempStore=Ext.getStore('middleTemporaryStoreId');
                    
                    assocModelStore.each(function(placeHolderForTopAlphaItem){
                    var listOfChildren="";      
        if(placeHolderForTopAlphaItem.get('TopAlphaItemAttributeOne')==record.get('TopAlphaItemAttributeOne')){
                            placeHolderForTopAlphaItem.RomanGrouper().each(function(RomanItem){
                                RomanItem.LowerAlphaGrouper().each(function(LowerAlphaItem){
                                    listOfChildren+=LowerAlphaItem.get('LowerAlphaAttribute')+" ";
                                })
                                if(listOfChildren!=""){
                                    listOfChildren=listOfChildren.slice(0,-1);
                                }
                                tempStore.add({
                                    parentItemReference: placeHolderForTopAlphaItem.get('TopAlphaItemAttributeOne'),
                                    tempFieldOne: RomanItem.get('RomanItemAttributeOne'),
                                    listOfChildItems: listOfChildren                     
                                });            
                                         console.log(placeHolderForTopAlphaItem.get('TopAlphaItemAttributeOne')+
                                    " "+
                                    RomanItem.get('RomanItemAttributeOne')+
                                    " "+
                                    listOfChildren);
                                    listOfChildren="";
                            });
                        }
                    });
                    console.log(record.get('TopLevelListOfChildren'));
                    if(record.get('TopLevelListOfChildren')!=""){
                    this.getParent().push({
                        xtype: 'middleTempListViewXtype',
                        title: 'temp List'
    
                    });
                    }
                }
            }
        }
    });
    MiddleTempListView.js
    HTML Code:
    Ext.define("nestedXMLexample.view.MiddleTempListView", {
        extend: 'Ext.List',
        xtype: 'middleTempListViewXtype',
        config: {
            fullscreen: true,
            store: 'middleTemporaryStoreId',
            scrollable: true,
            itemTpl: new Ext.XTemplate(
                    '<div>{tempFieldOne}</div><div style="color:orange"><small>{listOfChildItems}</small></div>'
    
            ),
            listeners: {
                itemtap: function(list, index, element, record){
                    console.log('item tapped in MiddleTempListView');
                    console.log(element);
                    console.log(record);
                    var assocModelStore=Ext.getStore('associatedModelsStoreId');
                    var lowestTempStore=Ext.getStore('lowestMiddleTemporaryStoreId');
                                    assocModelStore.each(function(placeHolderForTopAlphaItem){
                        placeHolderForTopAlphaItem.RomanGrouper().each(function(RomanItem){
                            RomanItem.LowerAlphaGrouper().each(function(LowerAlphaItem){
                                if(
                                    placeHolderForTopAlphaItem.get('TopAlphaItemAttributeOne')
                                    ==
                                    record.get('parentItemReference')
                                    &&
                                    RomanItem.get('RomanItemAttributeOne')
                                    ==
                                    record.get('tempFieldOne')){
                                        lowestTempStore.add({
                                            grandparentItemReference: record.get('parentItemReference'),
                                            parentItemReference: record.get('tempFieldOne'),
                                            lowestTempFieldOne: LowerAlphaItem.get('LowerAlphaAttribute')
                                        })
                                    console.log(LowerAlphaItem.get('LowerAlphaAttribute'));
                                }
                            })
                        })
                     })
                    lowestTempStore.each(function(s){
                        console.log(s.get('grandparentItemReference'));
    
                    })
                    this.getParent().push({
                        xtype: 'lowestMiddleTempListViewXtype',
                        title: 'did it'
                    })
                }
            }
         }
    });
    LowestLevelTempListView.js
    HTML Code:
    Ext.define("nestedXMLexample.view.LowestTempListView", {
        extend: 'Ext.List',
        xtype: 'lowestMiddleTempListViewXtype',
        config: {
            fullscreen: true,
            store: 'lowestMiddleTemporaryStoreId',
            scrollable: true,
            itemTpl: new Ext.XTemplate(
                    '{lowestTempFieldOne}'
            )
        }
    });
    TopLevelModel.js
    HTML Code:
    Ext.define('nestedXMLexample.model.TopLevelModel', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                {name: 'TopAlphaItemAttributeOne', mapping:'@TopAlphaItemAttributeOne'},
                'TopLevelListOfChildren'
            ],
            hasMany: [
                {model: 'nestedXMLexample.model.MiddleLevelModel', name: 'RomanGrouper', associationKey: 'RomanGrouper'}
            ]
        }
    });
    MiddleLevelModel.js
    HTML Code:
    Ext.define('nestedXMLexample.model.MiddleLevelModel', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                {name: 'RomanItemAttributeOne', mapping:'@RomanItemAttributeOne'},
            ],
            hasMany:[
                {model: 'nestedXMLexample.model.LowestLevelModel', name: 'LowerAlphaGrouper', associationKey: 'LowerAlphaGrouper'}
            ],
            belongsTo: 'nestedXMLexample.model.TopLevelModel',
                     proxy: {
                        reader: {
                           type: 'xml',
                           record: 'RomanItem'
                       }
                    }
        }
    });
    LowestLevelModel.js
    HTML Code:
    Ext.define('nestedXMLexample.model.LowestLevelModel', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                {name: 'LowerAlphaAttribute', mapping:'@LowerAlphaAttribute'}
            ],
            belongsTo: 'nestedXMLexample.model.MiddleLevelModel',
           proxy: {
                reader: {
                    type: 'xml',
                    record: 'LowerAlphaItem'
                }
            }
        }
    });
    MiddleTemporaryStoreModel.js
    HTML Code:
    Ext.define('nestedXMLexample.model.MiddleTemporaryStoreModel', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                'parentItemReference',
                 {name: 'tempFieldOne', type: 'string'},
                'listOfChildItems'
            ]
        }
    });
    LowestTemporaryStoreModel.js
    HTML Code:
    Ext.define('nestedXMLexample.model.LowestTemporaryStoreModel', {
        extend: 'Ext.data.Model',
        config: {
            fields: [
                'grandparentItemReference',
                'parentItemReference',
                 {name: 'lowestTempFieldOne', type: 'string'}
            ]
        }
    });
    AssociatedModelsStore.js
    HTML Code:
    Ext.define('nestedXMLexample.store.AssociatedModelsStore',{
        extend: 'Ext.data.Store',
        config: {
            storeId: 'associatedModelsStoreId',
            model: 'nestedXMLexample.model.TopLevelModel',
            autoLoad: true,
            defaultrootProperty: 'TopAlphaItem',
            proxy: {
                type: 'ajax',
                url : 'structuredSampleXML.xml',
                reader: {
                    type: 'xml',
                    record: 'TopAlphaItem'
                }
            },
            listeners:{
                load: (function(placeHolder){
                    placeHolder.each(function(placeHolderForTopAlphaItem){
                        
                        var collectorString="";
                        placeHolderForTopAlphaItem.RomanGrouper().each(function(RomanItem){
                                                    collectorString+=RomanItem.get('RomanItemAttributeOne')+" ";
                                                });
                        if(collectorString!=""){
                            collectorString=collectorString.slice(0,-1);
                        }
                        placeHolderForTopAlphaItem.set('TopLevelListOfChildren', collectorString);
                    });
                })
            }
        }
    }); 
    MiddleTemporaryStore.js
    HTML Code:
    Ext.define('nestedXMLexample.store.MiddleTemporaryStore',{
        extend: 'Ext.data.Store',
        config: {
            storeId: 'middleTemporaryStoreId',
            model: 'nestedXMLexample.model.MiddleTemporaryStoreModel',
            }
        }); 
    LowestTemporaryStore.js
    HTML Code:
    Ext.define('nestedXMLexample.store.LowestTemporaryStore',{
        extend: 'Ext.data.Store',
        config: {
            storeId: 'lowestMiddleTemporaryStoreId',
            model: 'nestedXMLexample.model.LowestTemporaryStoreModel',
            }
        }); 

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    36,754
    Vote Rating
    828
    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


    Usually when posted examples, you should try to keep it simple. So to improve upon yours, I would just have the NestedList, store, model and the XML.
    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 User
    Join Date
    Jun 2012
    Posts
    23
    Vote Rating
    1
    danrosshoward is on a distinguished road

      1  

    Default


    Thanks, Mitchell. I posted all of the code to make the example work, because I was a total noob just a little while ago, and really benefited from full examples that I could see in action. I should probably have put all of the code somewhere else, like github, but haven't tried doing something like that yet.

    This isn't really a nested list, which I'm sure is obvious to you. It is a navigation view that behaves like a nested list. There is probably a better way to get a nested list to consume xml, but this is the only way I could get it to work.

    Is there a better way?

    I also included the ability to display information from the next level down in the current level of the nested list. I was trying to build an example that works like the nested list example by Drew Neil shown here:
    http://vimeo.com/20580117


  4. #4
    Sencha User
    Join Date
    Aug 2012
    Posts
    1
    Vote Rating
    0
    00cmm is on a distinguished road

      0  

    Default Thanks for the complete example.

    Thanks for the complete example.


    Quote Originally Posted by danrosshoward View Post
    Thanks, Mitchell. I posted all of the code to make the example work, because I was a total noob just a little while ago, and really benefited from full examples that I could see in action. I should probably have put all of the code somewhere else, like github, but haven't tried doing something like that yet.
    I really appreciated this being a complete example. I am a total noob right now and this really helped me, even though it wasn't "best practice", it was the best thing for me right now.

    Thanks again.

  5. #5
    Sencha User
    Join Date
    Jun 2012
    Posts
    23
    Vote Rating
    1
    danrosshoward is on a distinguished road

      0  

    Default


    My pleasure. Thanks for your feedback.

Thread Participants: 2

Tags for this Thread

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi