Changeset 14142

Show
Ignore:
Timestamp:
06/25/08 06:03:43 (5 months ago)
Author:
doughays
Message:

Fixes #4437. Creates a parsing regexp for ValidationTextBox? widgets that matches valid subsets in order to mask validation errors during data entry that are only due to partial input.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • dijit/trunk/form/ValidationTextBox.js

    r12927 r14142  
    7676                }, 
    7777 
     78                _isValidSubset: function(){ 
     79                        // summary: 
     80                        //      Returns true if the value is either already valid or could be made valid by appending characters. 
     81                        return this.textbox.value.search(this._partialre) == 0; 
     82                }, 
     83 
    7884                isValid: function(/*Boolean*/ isFocused){ 
    7985                        // summary: Need to over-ride with your own validation code in subclasses 
     
    96102                }, 
    97103 
     104                _maskValidSubsetError: false, 
    98105                validate: function(/*Boolean*/ isFocused){ 
    99106                        // summary: 
     
    103110                        var message = ""; 
    104111                        var isValid = this.isValid(isFocused); 
     112                        if(isValid){ this._maskValidSubsetError = true; } 
     113                        var isValidSubset = !isValid && isFocused && this._isValidSubset(); 
    105114                        var isEmpty = this._isEmpty(this.textbox.value); 
    106                         this.state = (isValid || (!this._hasBeenBlurred && isEmpty)) ? "" : "Error"; 
     115                        this.state = (isValid || (!this._hasBeenBlurred && isEmpty) || isValidSubset) ? "" : "Error"; 
     116                        if(this.state == "Error"){ this._maskValidSubsetError = false; } 
    107117                        this._setStateClass(); 
    108118                        dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true"); 
     
    111121                                        message = this.getPromptMessage(true); 
    112122                                } 
    113                                 if(!message && this.state == "Error"){ 
     123                                if(!message && (this.state == "Error" || (isValidSubset && !this._maskValidSubsetError))){ 
    114124                                        message = this.getErrorMessage(true); 
    115125                                } 
     
    156166                        var p = this.regExpGen(this.constraints); 
    157167                        this.regExp = p; 
     168                        var partialre = ""; 
     169                        // parse the regexp and produce a new regexp that matches valid subsets 
     170                        // if the regexp is .* then there's no use in matching subsets since everything is valid 
     171                        if(p != ".*"){ this.regExp.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g, 
     172                                function (re){ 
     173                                        switch(re.charAt(0)){ 
     174                                                case '{': 
     175                                                case '+': 
     176                                                case '?': 
     177                                                case '*': 
     178                                                case '^': 
     179                                                case '$': 
     180                                                case '|': 
     181                                                case '(': partialre += re; break; 
     182                                                case ")": partialre += "|$)"; break; 
     183                                                 default: partialre += "(?:"+re+"|$)"; break; 
     184                                        } 
     185                                } 
     186                        );} 
     187                        try{ // this is needed for now since the above regexp parsing needs more test verification 
     188                                "".search(partialre); 
     189                        }catch(e){ // should never be here unless the original RE is bad or the parsing is bad 
     190                                partialre = this.regExp; 
     191                                console.debug('RegExp error in ' + this.declaredClass + ': ' + this.regExp); 
     192                        } // should never be here unless the original RE is bad or the parsing is bad 
     193                        this._partialre = "^(?:" + partialre + ")$"; 
    158194                } 
    159195        } 
     
    264300                }, 
    265301 
     302                _isDefinitelyOutOfRange: function(){ 
     303                        // summary: 
     304                        //      Returns true if the value is out of range and will remain 
     305                        //      out of range even if the user types more characters 
     306                        var val = this.getValue(); 
     307                        var isTooLittle = false; 
     308                        var isTooMuch = false; 
     309                        if("min" in this.constraints){ 
     310                                var min = this.constraints.min; 
     311                                val = this.compare(val, ((typeof min == "number") && min >= 0)? 0 : min); 
     312                                isTooLittle = (typeof val == "number") && val < 0; 
     313                        } 
     314                        if("max" in this.constraints){ 
     315                                var max = this.constraints.max; 
     316                                val = this.compare(val, ((typeof max != "number") || max > 0)? max : 0); 
     317                                isTooMuch = (typeof val == "number") && val > 0; 
     318                        } 
     319                        return isTooLittle || isTooMuch; 
     320                }, 
     321 
     322                _isValidSubset: function(){ 
     323                        return this.inherited(arguments) && !this._isDefinitelyOutOfRange(); 
     324                }, 
     325 
    266326                isValid: function(/*Boolean*/ isFocused){ 
    267327                        return this.inherited(arguments) &&