Search code examples
javascriptextjsextjs4

Marking a text field invalid from another text field's change event is undo'ed


Here's a function assigned to the change event of textfield in my controller:

checkFields: function (field, ov, nv, e) {

    switch (field.name) {

        case 'currentPassword':
        case 'newPassword':
        case 'confirmNewPassword':
            //set button state depending on form's element values...
            var form = Utils.getCmp('form[itemId=changePasswordForm]');
            var values = form.getForm().getValues();

            if (values.newPassword != values.confirmNewPassword) {
                this.changePwdButton().setDisabled(true);
                this.utils.getCmp('textfield[name=confirmNewPassword]').markInvalid(this.strings.Messages.str_ErrorPwdMatch);
                return false;
            }
            else {
                this.utils.getCmp('textfield[name=confirmNewPassword]').markInvalid(false);
            }

            if (!form.isValid()) {
                this.changePwdButton().setDisabled(true);
                return false;
            }

            this.changePwdButton().setDisabled(false);
            return true;
            break;

    }
}

When this is triggered by the 'newPassword' textfield, the block that marks the confirmNewPassword as invalid works OK but when it's triggered by the confirmNewPassword itself, it works, but then is undo'ed (mark as valid) when the function returns...

If I follow the call stack when triggered via confirmNewPassword the code eventually reaches this in the framework:

checkChange: function() {
    if (!this.suspendCheckChange) {
        var me = this,
            newVal = me.getValue(),
            oldVal = me.lastValue;
        if (!me.isEqual(newVal, oldVal) && !me.isDestroyed) {
            me.lastValue = newVal;
            me.fireEvent('change', me, newVal, oldVal);
            me.onChange(newVal, oldVal); //this line undos prevous markInvalid()
        }
    }
}

Any ideas why it does that ? Thanks.


Solution

  • This happens because of the onChange function, which calls the validate function, and this function calls the isValid function!

    onChange: function(newVal, oldVal) {
        if (this.validateOnChange) {
            this.validate();
        }
        this.checkDirty();
    },
    
    validate : function() {
        var me = this,
            isValid = me.isValid();
        if (isValid !== me.wasValid) {
            me.wasValid = isValid;
            me.fireEvent('validitychange', me, isValid);
        }
        return isValid;
    },
    
    isValid : function() {
        var me = this;
        return me.disabled || Ext.isEmpty(me.getErrors());
    },
    

    Your goal is, that the Change Pwd Btn is only enabled when both password fields have the same value! Therefore you should override the isValid function, instead of listening to the change event.

    By the way: Instead of using this var form = Utils.getCmp('form[itemId=changePasswordForm]'); you should use, var form = field.up('form[itemId=changePasswordForm]'); (Instead searching the whole DOM, you are starting at your element and just search upwards!)