Providing visual cue for invalid form fields on inactive tab panels

Ext Class: 
Form fields

Ext does a great job of providing visual cues when form fields are invalid, eg

Form field validation

But what happens if your form field is on an inactive tab panel? The visual cue can't be seen yet the form won't submit.

This is where the Ext.Fx come in handy.

By overriding the default markInvalid field functio, we can do a search through it's parents to find if it is on a tab panel.

If it is on a tab panel we can highlight the tab strip element using an Ext.Fx, I prefer to use frame with a red color for a consistent visual cue.

The override is as follows

    markInvalid : function(msg){
        if(!this.rendered || this.preventMark){
            return;
        }
        this.el.addClass(this.invalidClass);
        msg = msg || this.invalidText;
        switch(this.msgTarget){
            case 'qtip':
                this.el.dom.qtip = msg;
                this.el.dom.qclass = 'x-form-invalid-tip';
                if(Ext.QuickTips){
                    Ext.QuickTips.enable();
                }
                break;
            
            case 'title':
                this.el.dom.title = msg;
                break;
            
            case 'under':
                if(!this.errorEl){
                    var elp = this.el.findParent('.x-form-element', 5, true);
                    this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
                    this.errorEl.setWidth(elp.getWidth(true)-20);
                }
                this.errorEl.update(msg);
                Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
                break;
            case 'side':
                if(!this.errorIcon){
                    var elp = this.el.findParent('.x-form-element', 5, true);
                    this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
                }
                this.alignErrorIcon();
                this.errorIcon.dom.qtip = msg;
                this.errorIcon.dom.qclass = 'x-form-invalid-tip';
                this.errorIcon.show();
                this.on('resize', this.alignErrorIcon, this);
            break;
        
            default:
                var t = Ext.getDom(this.msgTarget);
                t.innerHTML = msg;
                t.style.display = this.msgDisplay;
            break;
        }
        var pp;
        var tp = this.findParentBy(function(p, c){
            if(p.isXType('tabpanel')){
                return true;
            }
            pp = p;
        });
        if(!Ext.isEmpty(pp,false) && !Ext.isEmpty(tp,false)){
            var e = tp.getTabEl(pp);
            if(!Ext.isEmpty(e)) {
                Ext.fly(e).frame("ff0000");
            }
        }
        this.fireEvent('invalid', this, msg);
    }

 

The key bit here is 

        var pp;
var tp = this.findParentBy(function(p, c){
if(p.isXType('tabpanel')){
return true;
}
pp = p;
});
if(!Ext.isEmpty(pp,false) && !Ext.isEmpty(tp,false)){
var e = tp.getTabEl(pp);
if(!Ext.isEmpty(e)) {
Ext.fly(e).frame("ff0000");
}

What this does is search through the field's parents to find one of xtype tabpanel (ie a tab panel). If it finds one it then finds the tab strip element for the parent tab and frames it with a red border like so:

A visual cue for inactive tabs

Thanks for this it really helped point me in the right direction! I had two problems that didn't fit my needs. 1) Seemed like a bit to much code. 2) I don't want it applied to all fields everywhere. So I adapted yours so that t attaches to the event instead. This seems like as good a place as any to offer this alternative. Thanks again.
var highLightTab = function() {
    // loop the fields
    Ext.each(this.form.items.items, function(item) {
        
        var tabPanel;
        var parentTabPanel = this.findParentBy(function(p, c) {
            if(p.isXType('tabpanel')) {
                return true;   
            }
            tabPanel = p;
        });
        
        // attach to the invalid event
        item.on('invalid', function() {
            if(!Ext.isEmpty(parentTabPanel,false) && !Ext.isEmpty(tabPanel,false)){
                var tabEl = parentTabPanel.getTabEl(tabPanel);
                if(tabEl) {
                    Ext.fly(tabEl).frame("ff0000");
                }
            }
        }, item);
    });
};

formpanel.on('render', highLightTab, formpanel, {single: true});

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can use Markdown syntax to format and style the text. Also see Markdown Extra for tables, footnotes, and more.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
two times equals four
Solve this math question and enter the solution with digits. E.g. for "two plus four = ?" enter "6".