Question

I want to dynamically show and hide fields in a form according to the items selected in a multiselect combobox (tagfield).

Each item selected in the combobox has several associated hidden form fields (to be show).

The fields have the property "hidden:true";

I can show the fields, but I can not hide them when i delete the items from the combobox field or de tagfield.

listeners:{ 

    select:function( combo, records, eOpts) {

            var combo = Ext.ComponentQuery.query('#combo')[0];

            var field = Ext.ComponentQuery.query('#A')[0];                      

            var field1 =Ext.ComponentQuery.query('#B')[0];                      

            var field2 =Ext.ComponentQuery.query('#C')[0];


            var records = combo.getValue();

              console.log(records);

            for (var i = 0, count = records.length; i < count; i++) {

                    switch(records[i]) {

                    case 'itemone':

                        if(field.isHidden()) {
                            field.show();                   
                                }
                        else { 
                             field.hide();
                                }
                    break;

                    case 'itemtwo':

                        if(field1.isHidden()) {
                            field1.show();                  
                                }
                        else { 
                             field1.hide();
                                }                                       
                    break;

                    case 'itemthree':

                        if(field2.isHidden()) {
                            field2.show();                  
                                }
                        else { 
                             field2.hide();
                                }       
                    break;  
                } 
            }
        }
}

console.log(records) provides the following result:

Show:

["itemone"]

["itemone", "itemtwo" ]

["itemone", "itemtwo", "itemthree"]

Hide:

["itemone", "itemtwo"]

["itemone"]

Can you give me, please, suggestions to correct the code.

Note: sorry for the next post previously in the wrong place

I tried to implement your sugestions, but without success (beginners difficulties).

My code:

 listeners:{ 

  select:function( combo, records, eOpts) {

    var combo = Ext.ComponentQuery.query('#combo')[0];

    var fields = Ext.ComponentQuery.query('[autoHideTag]');

    var records = combo.getValue();

      console.log(records);

    for (var i = 0, count = records.length; i < count; i++) {

            fields.setVisible(records.indexOf(fields.autoHideTag) !== -1 ); 

            switch(records[i]) {

            case 'itemone':

                if(field.isHidden()) {
                    field.show();                   
                        }
                else { 
                     field.hide();
                        }
            break;

            case 'itemtwo':

                if(field1.isHidden()) {
                    field1.show();                  
                        }
                else { 
                     field1.hide();
                        }                                       
            break;

            case 'itemthree':

                if(field2.isHidden()) {
                    field2.show();                  
                        }
                else { 
                     field2.hide();
                        }       
            break;  
        } 
    }
  }
} 

Firebug says:

TypeError: fields.setVisible is not a function

Can you help with more suggestions, please.

Merci.

Was it helpful?

Solution

Indeed, your code has a logical flaw. You make all field visible, but when you then remove the 3rd tag, what happens? You loop on currently selected tags in the combo, and as you show it, you have ["itemone", "itemtwo"], no "itemthree" in there. So your last case, the one that could hide the 3rd field is note executed. And so on for the second and first tag.

What I would do instead is looping through each field, show it if the tag is selected and hide it if it isn't. You can use records.indexOf('itemone') !== -1 for example, to test if the tag is selected.

Another tip, I would use a custom property with a distinctive name for the fields, allowing both to simplify the component query, and mindlessly knowing the tag to test against the selected ones.

Here's what I mean... If you define your fields this way:

{
    xtype: 'textfield'
    ,autoHideTag: 'itemone' // custom marker
}

You can them get all the fields in one query:

// select all components with property autoHideTag resolving to something truthy
var fields = Ext.ComponentQuery.query('[autoHideTag]');

You can make the query more specific if you want and if applicable, something like "textfield[autoHideTag]" or "field[autoHideTag]".

And, finally, you'll know the tag to test for this field:

// setting a component visible or hidden when it is already the case has no side-effect
field.setVisible( records.indexOf(field.autoHideTag) !== -1 );

Voilà. Have fun with Ext!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top