Browse Source

Added simple optional masks, or you can see it as clearing out optional masks on the tail when the input looses focus.
thx to Ross Hadden & Gilles van den Hoven for the code & idea

Robin Herbots 14 years ago
parent
commit
d32b6d3176
2 changed files with 173 additions and 64 deletions
  1. 132 56
      README
  2. 41 8
      jquery.inputmask.js

+ 132 - 56
README

@@ -6,125 +6,152 @@ A definition can have a cardinality and have multiple prevalidators.
 
 Example of some new definitions:
 
-                'd': { //day
-
-                    "validator": "0[1-9]|[12][0-9]|3[01]",
-
-                    "cardinality": 2,
-
-                    "prevalidator": [{ "validator": "[0-3]", "cardinality": 1}]
-
-                },
-
-                'm': { //month
-
-                    "validator": "0[1-9]|1[012]",
-
-                    "cardinality": 2,
-
-                    "prevalidator": [{ "validator": "[01]", "cardinality": 1}]
-
-                },
-
-                'y': { //year
-
-                    "validator": "(19|20)\\d\\d",
-
-                    "cardinality": 4,
-
-                    "prevalidator": [
-
-                        { "validator": "[12]", "cardinality": 1 },
-
-                        { "validator": "(19|20)", "cardinality": 2 },
-
-                        { "validator": "(19|20)\\d", "cardinality": 3 }
-
-                        ]
-
+```javascript
+     'm': { //month
+        validator: function(chrs, buffer) {
+            var dayValue = buffer.join('').substr(0, 3);
+            return $.inputmask.defaults.aliases['dd/mm/yyyy'].regex.month.test(dayValue + chrs);
+        },
+        cardinality: 2,
+        prevalidator: [{ validator: "[01]", cardinality: 1}]
+    },
+    'y': { //year
+        validator: function(chrs, buffer) {
+            if ($.inputmask.defaults.aliases['dd/mm/yyyy'].regex.year.test(chrs)) {
+                var dayMonthValue = buffer.join('').substr(0, 6);
+                if (dayMonthValue != "29/02/")
+                    return true;
+                else {
+                    var year = parseInt(chrs);  //detect leap year
+                    if (year % 4 == 0)
+                        if (year % 100 == 0)
+                        if (year % 400 == 0)
+                        return true;
+                    else return false;
+                    else return true;
+                    else return false;
                 }
+            } else return false;
+        },
+        cardinality: 4,
+        prevalidator: [
+            { validator: "[12]", cardinality: 1 },
+            { validator: "(19|20)", cardinality: 2 },
+            { validator: "(19|20)\\d", cardinality: 3 }
+            ]
+    }
+},
+insertMode: false
+```
 
 These allow for a finer date validation then 99/99/9999 which also allows 33/33/3333 for example.  
 In the jquery.inputmask.extentions.js you find a full date input validation which takes days, months & leap years into account.
 
-Also extra features like mask-repetitions (greedy and non-gready) are included.  In the examples you will find more about them.
+Also extra features like mask-repetitions (greedy and non-gready) and many other additions are included.  In the examples you will find more about them.
 
 
 Usage:
 
-Include the js-files
+Include the js-files:
 
+```html
 <script src="jquery.js" type="text/javascript"></script>
 <script src="jquery.inputmask.js" type="text/javascript"></script>
+<script src="jquery.inputmask.extentions.js" type="text/javascript"></script>
+```
 
 Define your masks:
 
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("d/m/y");  //direct mask
    $("#phone").inputmask("mask", {"mask": "(999) 999-9999"}); //specifying fn & options
    $("#tin").inputmask({"mask": "99-9999999"}); //specifying options only
 });
+```
 
-Extra options:
+## Extra options:
 
-change the placeholder
+### change the placeholder
 
+
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("d/m/y",{ "placeholder": "*" });
 });
+```
 
 or a multi-char placeholder
 
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("d/m/y",{ "placeholder": "dd/mm/yyyy" });
 });
+```
 
-execute a function when the mask is completed
+### execute a function when the mask is completed, incomplete or cleared
 
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("d/m/y",{ "oncomplete": function(){ alert('inputmask complete'); } });
+   $("#date").inputmask("d/m/y",{ "onincomplete": function(){ alert('inputmask incomplete'); } });
+   $("#date").inputmask("d/m/y",{ "oncleared": function(){ alert('inputmask cleared'); } });
 });
+```
 
-mask repeat function
+### mask repeat function
 
+```javascript
 $(document).ready(function(){
    $("#number").inputmask({ "mask": "9", "repeat": 10 });  // ~ mask "9999999999"
 });
+```
 
-mask non-greedy repeat function
+### mask non-greedy repeat function
 
+```javascript
 $(document).ready(function(){
    $("#number").inputmask({ "mask": "9", "repeat": 10, "greedy": false });  // ~ mask "9" or mask "99" or ... mask "9999999999"
 });
+```
 
-get the unmaskedvalue
+### get the unmaskedvalue
 
+```javascript
 $(document).ready(function(){
    $("#number").inputmask('unmaskedvalue');
 });
+```
 
-set a value and apply mask
+### set a value and apply mask
 
+```javascript
 $(document).ready(function(){
    $("#number").inputmask('setvalue', 12345); 
 });
+```
 
 when the option patch_eval is set to true the same can be done with the traditionnal jquery.val function
 
+```javascript
 $(document).ready(function(){
    $("#number").val(12345); 
 });
+```
 
 with the autoUnmaskoption you can change the return of $.fn.val  to unmaskedvalue or the maskedvalue
 
+```javascript
 $(document).ready(function(){
    	$('#<%= tbDate.ClientID%>').inputmask({ "mask": "d/m/y", 'autoUnmask' : true});	//  value: 23/03/1973
 
 	alert($('#<%= tbDate.ClientID%>').val());	// shows 23031973     (autoUnmask: true)
 });
+```
 
-add custom definitions
+### add custom definitions
 
+```javascript
 $.extend($.inputmask.defaults.definitions, {
     'f': {
         "validator": "[0-9\(\)\.\+/ ]",
@@ -132,47 +159,74 @@ $.extend($.inputmask.defaults.definitions, {
         'prevalidator': null
     }
 });
+```
 
-set defaults
+### set defaults
 
+```javascript
 $.extend($.inputmask.defaults, {
     'autounmask': true
 });
+```
 
-numeric input direction
+### numeric input direction
 
+```javascript
 $(document).ready(function(){
     $('#test').inputmask('€ 999.999.999,99', { numericInput: true });    //   123456  =>  € ___.__1.234,56
 });
+```
 
-remove the inputmask
+### remove the inputmask
 
+```javascript
 $(document).ready(function(){
     $('#test').inputmask('remove');
 });
+```
 
-escape special mask chars
+### escape special mask chars
 
+```javascript
 $(document).ready(function(){
     $("#months").inputmask("m \\months");
 });
+```
 
-remove incomplete input on blur - clearIncomplete
+### clearIncomplete - remove incomplete input on blur
 
+```javascript
 $(document).ready(function(){
     $("#ssn").inputmask("999-99-9999",{placeholder:" ", clearIncomplete: true });
 });
+```
+
+### Optional Masks
+
+When `clearMaskOnLostFocus: true` is set in the options (default), the mask will always clearout masks marked as optional when not filled in.
+
+For example, given:
 
-oncleared option
+```javascript
+$('#test').inputmask('999[-AAA]');
+```
+While the field has focus and is blank, users will see the full mask `___-___`.
+When the required part of the mask is filled and the field loses focus, the user will see `123`.
+When both the required and optional parts of the mask are filled out and the field loses focus, the user will see `123-abc`.
 
+### oncleared option
+
+```javascript
 $(document).ready(function(){
     $("#ssn").inputmask("999-99-9999",{placeholder:" ", oncleared: function(){ alert('Set focus somewhere else ;-)');} });
 });
+```
 
-aliases option
+### aliases option
 
 First you have to create an alias definition (more examples can be found in jquery.inputmask.extentions.js)
 
+```javascript
 $.extend($.inputmask.defaults.aliases, {
         'date': {
             mask: "d/m/y"
@@ -181,32 +235,54 @@ $.extend($.inputmask.defaults.aliases, {
 	    alias: "date"
 	}
 });
+```
+
+use:
 
-use;
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("date");       => equals to    $("#date").inputmask("d/m/y");
 });
+```
 
 or use the dd/mm/yyyy alias of the date alias:
+
+```javascript
 $(document).ready(function(){
    $("#date").inputmask("dd/mm/yyyy");       => equals to    $("#date").inputmask("d/m/y");
 });
+```
 
-auto upper/lower- casing inputmask
+### auto upper/lower- casing inputmask
 
 see jquery.inputmask.extentions.js for an example how to define "auto"-casing in a definition (definition A)
 casing can be null, "upper" or "lower"
 
+```javascript
 $(document).ready(function(){
    $("#test").inputmask("999-AAA");       => 123abc ===> 123-ABC 
 });
+```
 
-getemptymask command
+### getemptymask command
 
 return the default (empty) mask value
 
+```javascript
 $(document).ready(function(){
    $("#test").inputmask("999-AAA");    
    alert($("#test").inputmask("getemptymask"));    => "___-___" 
 });
+```
+
+### RTL input 
+
+Just add the dir="rtl" attribute to the input element
+
+```html
+<input id="test" dir="rtl" />
+```
+
+-----------------------------------------
+
 

+ 41 - 8
jquery.inputmask.js

@@ -3,7 +3,7 @@ Input Mask plugin for jquery
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 0.5.0 - dev
+Version: 0.5.1 - dev
  
 This plugin is based on the masked input plugin written by Josh Bush (digitalbush.com)
 */
@@ -492,9 +492,12 @@ This plugin is based on the masked input plugin written by Josh Bush (digitalbus
                 if (!input.attr("readonly")) {
                     input.bind("mouseenter.inputmask", function() {
                         var input = $(this);
-                        if (!input.hasClass('focus.inputmask') && _val.call(input).length == 0) {
-                            buffer = _buffer.slice();
-                            writeBuffer(input, buffer);
+                        if (!input.hasClass('focus.inputmask')) {
+                        	if(_val.call(input).length == 0) {
+                            	buffer = _buffer.slice();
+                            	writeBuffer(input, buffer);
+                        	} else if (_val.call(input).length < buffer.length)
+                        				writeBuffer(input, buffer);
                         }
                     }).bind("blur.inputmask", function() {
                         var input = $(this);
@@ -502,8 +505,22 @@ This plugin is based on the masked input plugin written by Josh Bush (digitalbus
                         if (_val.call(input) != undoBuffer) {
                             input.change();
                         }
-                        if (opts.clearMaskOnLostFocus && _val.call(input) == _buffer.join(''))
-                            _val.call(input, '');
+                        if (opts.clearMaskOnLostFocus) {
+                         	if(_val.call(input) == _buffer.join(''))
+                            	_val.call(input, '');
+                            else { //clearout optional tail of the mask 
+                            	var tmpBuffer = buffer.slice();
+                            	for(var pos = tmpBuffer.length - 1; pos >= 0 ; pos--) {
+                            		 var testPos = determineTestPosition(pos);
+                            		 if(tests[testPos].optionality){
+                            		 	if(getPlaceHolder(pos) == tmpBuffer[pos] || !isMask(pos))
+                            		 		tmpBuffer.pop();
+                            		 	else break;
+                            		 } else break;
+               					}
+               					writeBuffer(input, tmpBuffer);
+                            }
+                        }
                         if ((opts.clearIncomplete || opts.onincomplete) && checkVal(input, buffer, true) != getMaskLength()) {
                             if (opts.onincomplete) {
                                 opts.onincomplete.call(input);
@@ -523,8 +540,24 @@ This plugin is based on the masked input plugin written by Josh Bush (digitalbus
                         undoBuffer = _val.call(input);
                     }).bind("mouseleave.inputmask", function() {
                         var input = $(this);
-                        if (opts.clearMaskOnLostFocus && !input.hasClass('focus.inputmask') && _val.call(input) == _buffer.join(''))
-                            _val.call(input, '');
+                        if (opts.clearMaskOnLostFocus) {
+                         	if(!input.hasClass('focus.inputmask')) {
+                         		if(_val.call(input) == _buffer.join(''))
+                            	_val.call(input, '');
+                            	else { //clearout optional tail of the mask 
+                            		var tmpBuffer = buffer.slice();
+                            		for(var pos = tmpBuffer.length - 1; pos >= 0 ; pos--) {
+                            			 var testPos = determineTestPosition(pos);
+                            		 	if(tests[testPos].optionality){
+                            		 		if(getPlaceHolder(pos) == tmpBuffer[pos] || !isMask(pos))
+                            		 			tmpBuffer.pop();
+                            		 		else break;
+                            		 	} else break;
+               						}
+               						writeBuffer(input, tmpBuffer);
+                            	}
+                            }
+                        }
                     }).bind("click.inputmask", function() {
                         var input = $(this);
                         setTimeout(function() {