1. #1
    Sencha User
    Join Date
    Jan 2013
    Posts
    21
    Vote Rating
    1
    brian.scott@talgov.com is an unknown quantity at this point

      0  

    Default Unanswered: dataview.List + dynamic generation of text boxes for submission / model storage

    Unanswered: dataview.List + dynamic generation of text boxes for submission / model storage


    Hello friends -

    I'm working on a touch 2.1 project in SA2.

    What I really need to be able to do is iterate through a static list of items in a direct store, and render a radio/checkbox/number entry field for each child item in the list. I'm struggling on determining if this is possible with what I have set up, or indeed, with anything other than hand dragging / creating labels and textbox entry points for everything in my list, which would be a very cumbersome job.

    Currently I've got a direct store:

    Code:
    Ext.define('MyApp.store.inventoryListDataStore', {
        extend: 'Ext.data.Store',
    
    
        config: {
            data: [
                {
                    inventoryType: 'CFL',
                    inventoryItems: [
                        {
                            name: '9 W'
                        },
                        {
                            name: '14 W'
                        }
                    ]
                },
                {
                    inventoryType: 'Aeroators'
                }
            ],
            storeId: 'inventoryListDataStore',
            proxy: {
                type: 'direct',
                reader: {
                    type: 'json'
                }
            },
            fields: [
                {
                    name: 'inventoryType'
                },
                {
                    name: 'inventoryItems'
                }
            ]
        }
    });
    [Note: My eventual target list of inventory items is much longer]

    And a formplanel/dataview.List w/associated tpl:

    Code:
    {
                    xtype: 'formpanel',
                    hidden: true,
                    html: 'Am I showing the page I think I am?',
                    id: 'inventoryPanel',
                    itemId: 'inventoryPanel',
                    items: [
                        {
                            xtype: 'list',
                            docked: 'bottom',
                            height: 850,
                            id: 'inventoryList',
                            itemId: 'inventoryList',
                            scrollable: 'vertical',
                            emptyText: 'This store is empty.',
                            itemTpl: [
                                '<tpl for=".">',
                                '<div id="type">{inventoryType}</div>',
                                '    ',
                                '    <tpl for="inventoryItems">',
                                '        <div id="item{#}">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>{name}</div>',
                                '        ',
                                '    </tpl>',
                                '</tpl>',
                                '',
                                ''
                            ],
                            store: 'inventoryListDataStore',
                            itemHeight: 25,
                            refreshHeightOnUpdate: false
                        }
                    ]
                }
    This renders the list the way I'd like to see it, at least at a primitive level; but I really need the user to have a drop down box / text entry field so they could enter, '4' for 9 W CFL, and 20 for 14 W CFLs if that was the material left on the job. I can't figure out / find examples of syntax to render new entry boxes on the fly.

    Any insight is greatly appreciated!

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


    So within each row you want a form field?
    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
    Jan 2013
    Posts
    21
    Vote Rating
    1
    brian.scott@talgov.com is an unknown quantity at this point

      0  

    Default


    Hi Mitchel -

    I'd like a way to update values for each child. So, in my condensed data set, I'd like to render something like this:

    CFL
    9 W -- text box for entering number of 9W bulbs used.
    14 W -- text box for entering number of 14W bulbs used

    Repeat.

    I've got an eventual list of like 50 inventory children and about 15 parents right now. I'd like the user to get a page, be able to check off / enter the number of all types of inventory they used on the job, and hit submit. They must have the ability to fill in the entire dataset with one page load.

    I sort of have something set up that is working for me now, but is a bit clunky and I am DEFINITELY, open for a better way. Here is the code that I've been playing with lately.

    In the TPL, I am defining an onclick on an image to set the field of two hidden input fields; i.e.,

    Code:
     <tpl for=".">
      <div id="type">{inventoryType}</div>                          
        <tpl for="inventoryItems">
            {name} <img src="touch/resources/themes/images/default/pictos/arrow_up.png" height="20" width="20"    
                        onclick="var theHidden = Ext.getCmp('hiddenInventoryType');  theHidden.setHtml('{name}'); var theHiddenDirection = Ext.getCmp('hiddenIventoryDirection'); theHiddenDirection.setHtml('add');"                
                        />
                  &nbsp; 
                    <img src="touch/resources/themes/images/default/pictos/arrow_down.png" height="20" width="20"        
                        onclick="var theHidden = Ext.getCmp('hiddenInventoryType');  theHidden.setHtml('{name}'); var theHiddenDirection = Ext.getCmp('hiddenIventoryDirection'); theHiddenDirection.setHtml('subtract');"
                    />              
            <br>
        </tpl>
      </tpl>
    And then, on single tap, I parse the data back out. Clearly still a (very nasty) work in progress, but anyway:

    Code:
    var inventoryTypeValue = record.get("inventoryType"); 
    var inventoryItemNameValue = Ext.getCmp("hiddenInventoryType").getHtml(); 
    var inventoryItemOperation = Ext.getCmp("hiddenIventoryDirection").getHtml(); 
    
    
    // OK.  WE NOW KNOW:
    // THE CATEGORY OF INVENTORY ITEM WE WANT TO TOUCH. 
    // THE INVENTORY ITEM NAME THAT WE WANT TO TOUCH 
    // AND WE WANT TO ADD OR SUBTRACT ONE
    
    
    
    
    // SO, FIRST LETS TRY TO STORE THIS INFORMATION. 
    var inventoryUsedDataStore = Ext.data.StoreManager.lookup('inventoryUsedDataStore');
    
    
    // SET UP SOME VARIABLES TO ALLOW US TO FIGURE OUT IF NEED TO 
    // ADD OR APPEND TO A RECORD IN THE STORE. 
    var inventoryItemAlreadyExists = 'false';
    var existingInventoryItemId = 0; 
    
    
    for (key in inventoryUsedDataStore.data.items){
    
    
        // WE WILL EVALUATE BY HAND IF WE HAVE A MATCH ALREADY! 
        var theCurrentRecord = inventoryUsedDataStore.data.items[key]; 
    
    
        if (theCurrentRecord.get("inventoryType") == inventoryTypeValue &&
        theCurrentRecord.get("inventoryItemName") == inventoryItemNameValue){
    
    
            inventoryItemAlreadyExists = 'true';
            existingInventoryItemId = key; 
        }
    }
    
    
    
    
    if (inventoryItemAlreadyExists == 'false'){
        // THIS IS A BRAND NEW ADDITON.  SO JUST GO AHEAD AND ADD A VALUE.
        var numberOfExistingItems =  inventoryUsedDataStore.data.items.length;
        var newKey = numberOfExistingItems + 1; 
    
    
        var newInventoryUsedModel = Ext.create('inventoryUsedModel', {
            inventoryType: inventoryTypeValue,
            inventoryItemName: inventoryItemNameValue,
            amount: 1, 
        id: newKey}
        );
    
    
    
    
        inventoryUsedDataStore.add(newInventoryUsedModel);
    
    
    }
    
    
    
    
    if (inventoryItemAlreadyExists == 'true'){
        var theRecordToUpdate  = inventoryUsedDataStore.data.items[existingInventoryItemId];
        var theExistingAmount = theRecordToUpdate.get("amount"); 
    
    
        if (inventoryItemOperation == 'add'){
    
            var theNewAmount = theExistingAmount + 1; 
    
    
    
    
            // CREATE A NEW MODEL VALUE.  NOTE THE RE-USE OF INVENTORY ITEM ID.  
            var newInventoryUsedModel = Ext.create('inventoryUsedModel', {
                inventoryType: inventoryTypeValue,
                inventoryItemName: inventoryItemNameValue,
                amount: theNewAmount, 
            id: existingInventoryItemId}
            );
    
    
            // LETS NUKE OUR OLD VALUE
            inventoryUsedDataStore.data.removeAt(existingInventoryItemId); 
    
    
            // THEN ADD!
            inventoryUsedDataStore.add(newInventoryUsedModel);        
        }
        else if (inventoryItemOperation == 'subtract'){
    
            var theNewAmount = theExistingAmount - 1; 
    
    
            if (theNewAmount == 0){
                // FULL NUKE!
                console.log("Full removal determined"); 
    
    
                // LETS NUKE OUR  VALUE
                inventoryUsedDataStore.data.removeAt(existingInventoryItemId); 
    
    
            }
            else{
    
    
                console.log("subtraction update detected!");
    
    
                // CREATE A NEW MODEL VALUE.  NOTE THE RE-USE OF INVENTORY ITEM ID.  
                var newInventoryUsedModel = Ext.create('inventoryUsedModel', {
                    inventoryType: inventoryTypeValue,
                    inventoryItemName: inventoryItemNameValue,
                    amount: theNewAmount, 
                id: existingInventoryItemId}
                );
    
    
                // LETS NUKE OUR OLD VALUE
                inventoryUsedDataStore.data.removeAt(existingInventoryItemId); 
    
    
                // THEN ADD!
                inventoryUsedDataStore.add(newInventoryUsedModel); 
    
    
            }
    
    
            console.log("subtraction identified!");
        }
    }
    Ultimately, I know that this is a pretty hacky way of interacting with the data in the stores, but I had problems getting built in methods to really give me what I was expecting, so I trudged through it. Also, there are probably instances where the user will need to enter that they left 10 9W CFLs or whatever; I'd love to give them an option to enter that in instead of ten taps, but couldn't find the right combination of containers / data components to make it happen.

    It did not do me any good to try to create a new <div> for each child in my for .. tpl loop; the ontap even was always firing on the parent identifier (i.e., CFL) instead of the child (9W), so you'd get a screen that rendered three divs, but clicking any of them just fired for the top level parent.

    Any insight would be appreciated.

    Thanks!

    brian

Thread Participants: 1

Tags for this Thread