0
votes

I have two components in my form which are "Source" and "Destination". And I want to give an option to change the order of those 2 components when clicked on "Swap" button. Is this achievable in Extjs form ..? https://fiddle.sencha.com/#view/editor&fiddle/3ej6

3
Do you want to swap the values in the comboboxes, or you want to swap the comboboxes' order itself? - aaandri98
@AndreaRighi, Not the values Righi, combo boxes order itself. It is similar to google source and destination swap. like we can change order source-destination or destination-source - Sahas
did you check if the new solution? - aaandri98
Hi @AndreaRighi, Yes this is working as expected, but I don't know its a good idea to depend on index. it works if form is having less number of components, But what if I had form with lot of data - Sahas

3 Answers

0
votes

I attach here one possible solution: I removed both the fields and added them again with right indices.

listeners: {
  click: function(){
    const panel = this.up('panel');

    const sourceForm = panel.query('combo[reference=source]');
    const destinationForm = panel.query('combo[reference=destination]');

    panel.remove(sourceForm)
    panel.remove(destinationForm)

    panel.insert(0, destinationForm)
    panel.insert(1, sourceForm)
  }
}

Here the link to working Fiddle.

---- EDIT -----

This is the new snippet to adapt the fiddle to your comment:

const panel = this.up('panel');

const sourceForm = panel.query('combo[reference=source]');
const destinationForm = panel.query('combo[reference=destination]');

const sourceIndex = panel.items.items.indexOf(sourceForm[0])

panel.remove(sourceForm)
panel.remove(destinationForm)

panel.insert(sourceIndex, destinationForm)
panel.insert(sourceIndex === 0 ? 1 : 0, sourceForm)

The working fiddle can be found at the same old link.

0
votes

Different approach can be found here:

https://fiddle.sencha.com/#view/editor&fiddle/3em7

  let combo1 = Ext.create({
            xtype: 'combo',
            name: 'source',
            fieldLabel: 'source',
            reference: 'source',
            displayField: 'name',
            valueField: 'abbr',
            store: [{
                abbr: 'AL',
                name: 'Alabama'
            }, {
                abbr: 'AK',
                name: 'Alaska'
            }, {
                abbr: 'AZ',
                name: 'Arizona'
            }, {
                xtype: 'button',

            }],
            allowBlank: false // requires a non-empty value
        })

        let combo2 = Ext.create({
            xtype: 'combo',
            name: 'source1',
            fieldLabel: 'dest',
            reference: 'source1',
            displayField: 'name',
            valueField: 'abbr',
            //hidden: true,
            store: [{
                abbr: 'AL',
                name: 'Alabama'
            }, {
                abbr: 'AK',
                name: 'Alaska'
            }, {
                abbr: 'AZ',
                name: 'Arizona'
            }, {
                xtype: 'button',

            }],
            allowBlank: false // requires a non-empty value
        })

        let items = [combo1, combo2];

        let wrapper = Ext.create({
            xtype: 'container',
            layout: 'vbox',
            items: items
        })

        Ext.create('Ext.form.Panel', {
            title: 'Contact Info',
            width: 300,
            bodyPadding: 10,
            renderTo: Ext.getBody(),
            items: [wrapper, {
                xtype: 'button',
                text: "Swap",
               handler:(b)=> {
                   wrapper.removeAll(false);
                   wrapper.add(items.reverse());
               }
            }]
        });

Technically, as far as i remember, items within a (container) component are managed using a mixed collection.

https://docs.sencha.com/extjs/6.5.3/classic/Ext.util.MixedCollection.html

You can try to change the order there and refresh the view.

0
votes

I guess we missed the CSS only solution.

You can use ordinal-group to swap items. Just add a class, which adds a higher group number to the first combobox.

listeners: {
    click: function () {
        let view = this.up(),
            sourceComp = view.down('combo[reference=source]');

        sourceComp.toggleCls('box-reverse')
    }
}

.box-reverse {
    -webkit-box-ordinal-group: 3!important;
}

Here is your fiddle