1. #1
    Sencha User
    Join Date
    Apr 2012
    Location
    Cali, Colombia
    Posts
    4
    Vote Rating
    0
    laovejanegra is on a distinguished road

      0  

    Default Answered: Create DataItem in Dataview Sencha Touch 2

    Answered: Create DataItem in Dataview Sencha Touch 2


    I need create a dataview component with the following structure



    I learned how to create simple text component, but this structure is more difficult. I use this code, but is only the name field:

    Code:
    Ext.define('DEMO.view.product.ListItem', {
        extend: 'Ext.dataview.component.DataItem',
            xtype: 'product-list-item',
            config: {
              cls: 'product-list-item',
              dataMap: {
                  getName: {
                       setHtml: 'name'
                  }
             },
             name: {
                 cls: 'x-name',
                 flex: 1
             },
             layout: {
                  type: 'hbox',
                  align: 'left'
             }
        },
        applyName: function(config){
             return Ext.factory(config, Ext.Component, this.getName());
        },
        updateName: function(newName, oldName) {
             if (newName) {
                 this.add(newName);
             }
    
             if (oldName) {
                  this.remove(oldName);
             }
         }
    });
    Last edited by mitchellsimoens; 17 Apr 2012 at 11:02 AM. Reason: added [CODE] tags

  2. Objects passed in data item definition don 't has to be simple elements with a simple setter attached, on the pattern specified by you:


    Code:
    config: { 
    dataMap: { 
    getName: { 
    setHtml: 'name' 
    } 
    }, 
    name: { 
    cls: 'x-name', 
    flex: 1 
    }
    }


    If you look in the dataitem source code you see how mapping works:


    Code:
    for (componentName in dataMap) { 
    setterMap = dataMap[componentName]; 
    component = me[componentName](); 
    if (component) { 
    for (setterName in setterMap) { 
    if (component[setterName]) { 
    component[setterName](data[setterMap[setterName]]); 
    } } } }



    So instead of using setHtml method of a Component one could create a new component with setters for every property he needs.


    Code:
    Ext.define('MyProduct',{
    extend:'Ext.Contaier',
    xtype:'mycomponenttype',
    config:{
    name:null,
    image:null,
    quantity:null,
    items:[
    {xtype:'component', id:'name'},
    {xtype:'component', id:'image'}
    {xtype:'component', id:'quantity'}
    ]
    },
    setName:function(name)
    { 
    //update view element
    },
    setImage:function(image)
    {
    //update image element
    },
    setQuantity:function(image)
    {
    //update quantity
    }
    });

    Now you have a new type that has setters for your needs, mycomponenttype, that could have any layout or tpl you want.


    Now in you data item implementation you can set things like:
    Code:
    config: { 
    dataMap: { 
    getMyComp: { 
    setName: 'name',
    setImage:'image',
    setQuantity:'quantity'
    } 
    }, 
    myComp: { 
    xtype:'mycomponenttype'
    }
    
    
    }
    ,
    applyMyComp: function(config){
    return Ext.factory(config, MyProduct , this.getMyComp());
    }

    Of course this is not a working code, but I hope you get the idea


    If you don t have a large number of items, using a container instead of Dataview might be more handy.

  3. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,525
    Vote Rating
    871
    Answers
    3564
    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


    You should have the icon (the box image) docked to the left and the date docked to the right. The name can just be an item.
    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.

  4. #3
    Sencha User
    Join Date
    Apr 2012
    Location
    Cali, Colombia
    Posts
    4
    Vote Rating
    0
    laovejanegra is on a distinguished road

      0  

    Default


    My problem is I do not know how to create the items, because are 5 elements:
    1. The product image
    2. The label with text: 'Quantity'
    3. The input to enter the quantity
    4. The label with the number units(right)
    5. The label with the product price(right)


    I need help for create the structure.

  5. #4
    Sencha User bluehipy's Avatar
    Join Date
    Mar 2010
    Location
    Romania
    Posts
    609
    Vote Rating
    26
    Answers
    66
    bluehipy will become famous soon enough bluehipy will become famous soon enough

      1  

    Default


    Objects passed in data item definition don 't has to be simple elements with a simple setter attached, on the pattern specified by you:


    Code:
    config: { 
    dataMap: { 
    getName: { 
    setHtml: 'name' 
    } 
    }, 
    name: { 
    cls: 'x-name', 
    flex: 1 
    }
    }


    If you look in the dataitem source code you see how mapping works:


    Code:
    for (componentName in dataMap) { 
    setterMap = dataMap[componentName]; 
    component = me[componentName](); 
    if (component) { 
    for (setterName in setterMap) { 
    if (component[setterName]) { 
    component[setterName](data[setterMap[setterName]]); 
    } } } }



    So instead of using setHtml method of a Component one could create a new component with setters for every property he needs.


    Code:
    Ext.define('MyProduct',{
    extend:'Ext.Contaier',
    xtype:'mycomponenttype',
    config:{
    name:null,
    image:null,
    quantity:null,
    items:[
    {xtype:'component', id:'name'},
    {xtype:'component', id:'image'}
    {xtype:'component', id:'quantity'}
    ]
    },
    setName:function(name)
    { 
    //update view element
    },
    setImage:function(image)
    {
    //update image element
    },
    setQuantity:function(image)
    {
    //update quantity
    }
    });

    Now you have a new type that has setters for your needs, mycomponenttype, that could have any layout or tpl you want.


    Now in you data item implementation you can set things like:
    Code:
    config: { 
    dataMap: { 
    getMyComp: { 
    setName: 'name',
    setImage:'image',
    setQuantity:'quantity'
    } 
    }, 
    myComp: { 
    xtype:'mycomponenttype'
    }
    
    
    }
    ,
    applyMyComp: function(config){
    return Ext.factory(config, MyProduct , this.getMyComp());
    }

    Of course this is not a working code, but I hope you get the idea


    If you don t have a large number of items, using a container instead of Dataview might be more handy.

  6. #5
    Sencha Premium Member intellix's Avatar
    Join Date
    Mar 2012
    Location
    UK + Malta
    Posts
    263
    Vote Rating
    18
    Answers
    5
    intellix will become famous soon enough

      0  

    Default


    Thanks for the above bluehipy... but if you're looping through and creating this items then it moans that you shouldn't have more than one ID... with the above there will be many... I still don't know the proper way to grab items.

    I'm used to $('#id') and $('.class') but it seems Ext throws in this extra 'component' crap so I don't know what's supposed to be referenced with what. In all the examples everything is created with var blah = Ext.create(); but in Architect things aren't given a variable to grab

  7. #6
    Sencha User bluehipy's Avatar
    Join Date
    Mar 2010
    Location
    Romania
    Posts
    609
    Vote Rating
    26
    Answers
    66
    bluehipy will become famous soon enough bluehipy will become famous soon enough

      1  

    Default


    I don't understand your ID issues but,

    Sencha Touch 2 gives you nice ways to get what you want based on a query. I would say it goes one step further than jQuery and offers this service of query the dom, elements as well as the components.

    There is Ext.DomQuery which can be used, like jQuery, for DOM query:
    http://docs.sencha.com/touch/2-0/#!/...-method-select
    http://docs.sencha.com/touch/2-0/#!/api/Ext.DomQuery-method-selectNode
    PHP Code:
    var bodyDom Ext.DomQuery.selectNode('body');  //$('body')
    var paragraphsDomCollection Ext.DomQuery.select('p',bodyDom); //$('p',$('body'))

    var bodyEl Ext.get(body); //element
    paragraphsDomCollection bodyEl.query('p');  //array of dom
    var firstParagraph =  bodyEl.down('p'); //element
    firstParagraph.dom //dom :) 
    and there is Ext.ComponentQuery which can be used for component selection (starting from Container):
    http://docs.sencha.com/touch/2-0/#!/api/Ext.ComponentQuery-method-query

    PHP Code:
    var panels Ext.ComponentQuery.query('panel'); //array of Ext.Panel components
    var panel panels[0]; // Ext.Panel component 
    var buttons panel.query('button'); //array of Ext.Button components from inside the Ext.Panel component
    var firstButton panel.down('button'); //first Ext.Button component found in Ext.Panel component

    panel.el// Element

    panelDomContainer panel.el.down('div'); // dom, first div encapsulating the panel element conmtent
    panel.el.query('div'// array of dom, all the div elements beneath the panel's element's dom 

    As long as you make the distinction between Component, Element and DOM, you are safe but... read the documentation

  8. #7
    Sencha Premium Member intellix's Avatar
    Join Date
    Mar 2012
    Location
    UK + Malta
    Posts
    263
    Vote Rating
    18
    Answers
    5
    intellix will become famous soon enough

      0  

    Default


    Brilliant, lifesaver So I can do the above and then do the query selector inside each partial to grab and change the pieces I need to. I just figured what the dataMap is actually used for. I ended up without using it and then when it come to updating the rows it couldn't be done. Could only add new rows.

  9. #8
    Sencha Premium Member intellix's Avatar
    Join Date
    Mar 2012
    Location
    UK + Malta
    Posts
    263
    Vote Rating
    18
    Answers
    5
    intellix will become famous soon enough

      0  

    Default


    Was just having an issue with my nested store.

    If I update a value of my nested store, the 'updaterecord' event isn't fired. I couldn't figure out how to fireEvent('updaterecord') so instead I just update an item on the very top level to it's current value to make it recreate everything, like:

    Store:
    Code:
    eventDates: [{
     id: 1,
     time: '1231231232100',
     events: [
        {
            id: 1,
            name: 'Birthday bash!',
            timeStart: '1231231433200,
            performers: [
                {
                      id: 1,
                      name: 'Tupac',
                      age: 90 
                },
                {
                      id: 2,
                      name: 'Michael Jackson',
                      age: 70 
                },
            ]
        }
     ]
    }]
    If you change Michael Jackson as the performer, it doesn't know that something has changed so yeah, need to force it to look at the dataMap with something like:

    Code:
    Ext.Viewport.getActiveItem().getStore().getAt(0).set('time', Ext.Viewport.getActiveItem().getStore().getAt(0).get('time'));
    Been quite a rollercoaster ride... I'm so surprised that I'm the only person I can find that is printing a complex view for records. It seems like other users of the framework only ever make an application for a list of names of some sort :P

  10. #9
    Sencha User bluehipy's Avatar
    Join Date
    Mar 2010
    Location
    Romania
    Posts
    609
    Vote Rating
    26
    Answers
    66
    bluehipy will become famous soon enough bluehipy will become famous soon enough

      0  

    Default


    @intellix yep, you are the ONE and only


    How so ever, your probem is related on how you declared your model. If you have a complex member the parent will not feel that one of member properties have changed. Read about models associations.

  11. #10
    Sencha Premium Member intellix's Avatar
    Join Date
    Mar 2012
    Location
    UK + Malta
    Posts
    263
    Vote Rating
    18
    Answers
    5
    intellix will become famous soon enough

      0  

    Default


    Hmm, I'm a little confused then because I do have assocations setup and I believed them to have worked as well because if I run the following functions, I get information about their models automatically tied with a reference to the parent with parent_id (I've removed some of the crap)

    Ext.Viewport.getActiveItem().getStore()
    Code:
    _model:
    Code:
    $className: "App.model.Day"
    data: Object
      events: Array[1]
       [0]: {
          id: 1,
          day_id: 1,
          name: 'Birthday Bash!',
          people: Array[2]
       }
    eventsStore: Ext.apply.create.Class
      _model: $className: "App.model.Event"
    


    I trimmed alot of the crap, but I can see there are references to all of the models and the parent_id within the child.

    My models have 'Ext.data.HasManyAssociation' to the child. I have only one Store, which pulls in a nested JSON of days (and events, people etc). I just tried adding a 'BelongsToAssocation' as well but it didn't really do anything.

    The examples are a bit bare to do with Associations. It doesn't really explain the reason behind having both a HasManyAssociation AND the BelongsToAssociations