1
votes

I'm trying to make a list with -/+ buttons. Each item on a list will have this pair of buttons. I'm trying to add listeners to the button elements (actually they are Divs) but with minimum luck so far.

What I've done so far is catch the 'beforerender' event of the list, loop through all the list elements and add a click listener for each item on the list. But the problem is that when I navigate out, to another screen/panel and the back in the list, the beforerender event is not thrown. So the listeners for the new list items are not registered.

I've tried to make a workaround and force the list to be refreshed on each 'beforeactivate' event of the panel. But this causes the list to refresh for 4-5 times (don't know why).

I must be going the wrong way on this one... Maybe the solution is a custom component but the documentation on custom components is quite poor.

1

1 Answers

1
votes

Ok, I've found the solution, for anyone having the same problem:

I caught the activate and beforeactivate event of the Panel and I retrieve a reference to the list by using an id on the list, (eg: lstProducts) and then getting it by this.down('#productsList');.

UPDATE

Here is the template for the list, along with the list and the method that setups the listeners.

The template for the list

    productsTemplate = new Ext.XTemplate(
            '<tpl for=".">' +
                '<table width="100%" cellpadding="0" cellspacing="0"><tr>' +
                '<td>' +
                '<div class="product">{Name}</div>' +
                '</td>' +
                '<td rowspan="2" width="10%" align="right">' +
                '<table cellpadding="0" cellspacing="0">' +
                '<tr><td><div class="btn btnOrder minus" id="btnRemove{#}" > - </div></td> ' +
                '<td><input type="text" disabled id="pr-{Id}" value="0" class="productQuantity"/> </td>' +
                '<td><div class="btn btnOrder plus" id="btnAdd{#}"> + </div></td></tr></table> ' +
                '</td></tr><tr><td>' +
                '<table class="orderExtra"><tr>' +
                '<td class="sideOrderIcon" id="prSideOrderIcon-{Id}">&nbsp;</td>' +
                '<td valign="middle"><input type="text" disabled id="prSideOrder-{Id}" value="0" class="extraQuantity"/></td>' +
                '<td class="extraIcon" id="prExtraIcon-{Id}">&nbsp;</td>' +
                '<td><input type="text" disabled id="prExtra-{Id}" value="0" class="extraQuantity"/></td>' +
                '<td class="price">{Price} €</td>' +
                '</tr></table>' +
                '</td></tr>' +
                '</table>' +
                '</tpl>'
        );

The list itself and the action listeners setup at activate of the view.

productsList = new Ext.List({
            store:this.store,
            scope:this,
            refreshed:false,
            id:'productsList',
            disableSelection:true,
            itemTpl:productsTemplate })

Ext.apply(this, {
            layout:'fit',
            scroll:'vertical',
            items:[productsList],
            listeners:{
                activate:this.setupQuantityActionListeners
            }

At some other part of the code put the below method.

setupQuantityActionListeners:function () {
    var panel = this.down('#productsList');
    // loop all the list items to add listeners to the buttons
    panel.all.elements.forEach(function (item, index) {
        //get the button references
        var btnAdd = Ext.get('btnAdd' + (index + 1));
        var btnRemove = Ext.get('btnRemove' + (index + 1));
        //get the product model
        var product = app.stores.Products.getAt(index);
        var tbxQuantity = Ext.get('pr-' + product.data.Id);
        //get the running quantity
        if (tbxQuantity)
            var quantity = tbxQuantity.getValue();
        //add - remove quantity
        if (btnAdd) {
            btnAdd.on('click', function () {
                tbxQuantity.dom.value = ++quantity;
                Ext.dispatch({
                    controller:'Orders',
                    action:'addOrderItem',
                    product:product,
                    quantity:quantity
                })
            })
        }
        if (btnRemove) {
            btnRemove.on('click', function () {
                if (quantity > 0) {
                    tbxQuantity.dom.value = --quantity;
                    Ext.dispatch({
                        controller:'Orders',
                        action:'addOrderItem',
                        product:product,
                        quantity:quantity
                    })
                }
            })
        }
    });
}

Be very careful with the scoping in general. If you want to get something from the view and you try to get it at a component listener method, you must set scope:this to that component, so as to get a reference of the view when inside the listener method of the component.

Hope it helps