Skip to content

Commit 414d055

Browse files
committed
A number of improvements to improve flexibility and ease of use
- Use an options object instead of hard coded values - Make auto initalizeation optional - add refresh method - allow a nodeList to be used instead of a selector - Fix bug where inputs are replaced losing some props in IE and losing event handlers in all browsers
1 parent 1832e33 commit 414d055

File tree

2 files changed

+80
-55
lines changed

2 files changed

+80
-55
lines changed

index.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
</li>
3838
</ul>
3939

40-
<script src="js/masking-input.js"></script>
41-
40+
<script src="js/masking-input.js" data-autoinit="true"></script>
4241
</body>
4342
</html>

js/masking-input.js

+79-53
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,73 @@
11
var masking = {
22

3-
// User defined Values
4-
//maskedInputs : document.getElementsByClassName('masked'), // add with IE 8's death
5-
maskedInputs : document.querySelectorAll('.masked'), // kill with IE 8's death
6-
maskedNumber : 'XdDmMyY9',
7-
maskedLetter : '_',
8-
9-
init: function () {
10-
masking.setUpMasks(masking.maskedInputs);
11-
masking.maskedInputs = document.querySelectorAll('.masked'); // Repopulating. Needed b/c static node list was created above.
12-
masking.activateMasking(masking.maskedInputs);
3+
// Default Values
4+
defaults: {
5+
masked : '.masked',
6+
maskedNumber : 'XdDmMyY9',
7+
maskedLetter : '_',
8+
error: function(){}
139
},
1410

15-
setUpMasks: function (inputs) {
16-
var i, l = inputs.length;
11+
init: function ( options ) {
12+
if ( options && options.masked ) {
13+
// Make it easy to wrap this plugin and pass elements instead of a selector
14+
options.masked = typeof options.masked === string ? document.querySelectorAll( options.masked ) : options.masked;
15+
}
1716

18-
for(i = 0; i < l; i++) {
19-
masking.createShell(inputs[i]);
17+
if ( options ) {
18+
this.options = {
19+
masked: options.masked || document.querySelectorAll( this.defaults.masked ),
20+
maskedNumber: options.maskedNumber || this.defaults.maskedNumber,
21+
maskedLetter: options.maskedLetter || this.defaults.maskedLetter,
22+
error: options.onError || this.defaults.onError
23+
}
24+
} else {
25+
this.options = this.defaults;
26+
this.options.masked = document.querySelectorAll( this.options.masked );
27+
}
28+
29+
this.refresh( true );
30+
},
31+
32+
refresh: function( init ) {
33+
var input, parentClass;
34+
35+
if ( !init ) {
36+
this.options.masked = document.querySelectorAll( this.options.masked );
37+
}
38+
39+
for(i = 0; i < this.options.masked.length; i++) {
40+
input = this.options.masked[i]
41+
parentClass = input.parentNode.getAttribute('class');
42+
43+
if ( !parentClass || ( parentClass && parentClass.indexOf( 'shell' ) === -1 ) ) {
44+
this.createShell(input);
45+
this.activateMasking(input);
46+
}
2047
}
2148
},
2249

2350
// replaces each masked input with a shall containing the input and it's mask.
2451
createShell : function (input) {
25-
var text = '',
26-
placeholder = input.getAttribute('placeholder');
52+
var wrap = document.createElement('span'),
53+
mask = document.createElement('span'),
54+
emphasis = document.createElement('i'),
55+
placeholderText = input.getAttribute('placeholder'),
56+
placeholder = document.createTextNode(placeholderText);
2757

2858
input.setAttribute('maxlength', placeholder.length);
29-
input.setAttribute('data-placeholder', placeholder);
59+
input.setAttribute('data-placeholder', placeholderText);
3060
input.removeAttribute('placeholder');
3161

32-
text = '<span class="shell">' +
33-
'<span aria-hidden="true" id="' + input.id +
34-
'Mask"><i></i>' + placeholder + '</span>' +
35-
input.outerHTML +
36-
'</span>';
62+
mask.setAttribute('aria-hidden', 'true');
63+
mask.setAttribute('id', input.getAttribute('id') + 'Mask');
64+
mask.appendChild(emphasis);
65+
mask.appendChild(placeholder);
3766

38-
input.outerHTML = text;
67+
wrap.setAttribute('class', 'shell');
68+
wrap.appendChild(mask);
69+
input.parentNode.insertBefore( wrap, input );
70+
wrap.appendChild(input);
3971
},
4072

4173
setValueOfMask : function (e) {
@@ -46,20 +78,15 @@ var masking = {
4678
},
4779

4880
// add event listeners
49-
activateMasking : function (inputs) {
50-
var i, l;
51-
52-
for (i = 0, l = inputs.length; i < l; i++) {
53-
if (masking.maskedInputs[i].addEventListener) { // remove "if" after death of IE 8
54-
masking.maskedInputs[i].addEventListener('keyup', function(e) {
55-
masking.handleValueChange(e);
56-
}, false);
57-
} else if (masking.maskedInputs[i].attachEvent) { // For IE 8
58-
masking.maskedInputs[i].attachEvent("onkeyup", function(e) {
59-
e.target = e.srcElement;
60-
masking.handleValueChange(e);
61-
});
62-
}
81+
activateMasking : function (input) {
82+
var that = this;
83+
if (input.addEventListener) { // remove "if" after death of IE 8
84+
input.addEventListener('keyup', this.handleValueChange, false);
85+
} else if (input.attachEvent) { // For IE 8
86+
input.attachEvent("onkeyup", function(e) {
87+
e.target = e.srcElement;
88+
that.handleValueChange(e);
89+
});
6390
}
6491
},
6592

@@ -94,20 +121,15 @@ var masking = {
94121
strippedValue = isCharsetPresent ? value.replace(/\W/g, "") : value.replace(/\D/g, "");
95122

96123
for (i = 0, j = 0; i < l; i++) {
97-
var x =
98124
isInt = !isNaN(parseInt(strippedValue[j]));
99125
isLetter = strippedValue[j] ? strippedValue[j].match(/[A-Z]/i) : false;
100-
matchesNumber = masking.maskedNumber.indexOf(placeholder[i]) >= 0;
101-
matchesLetter = masking.maskedLetter.indexOf(placeholder[i]) >= 0;
102-
126+
matchesNumber = this.options.maskedNumber.indexOf(placeholder[i]) >= 0;
127+
matchesLetter = this.options.maskedLetter.indexOf(placeholder[i]) >= 0;
103128
if ((matchesNumber && isInt) || (isCharsetPresent && matchesLetter && isLetter)) {
104-
105129
newValue += strippedValue[j++];
106-
107130
} else if ((!isCharsetPresent && !isInt && matchesNumber) || (isCharsetPresent && ((matchesLetter && !isLetter) || (matchesNumber && !isInt)))) {
108-
// masking.errorOnKeyEntry(); // write your own error handling function
109-
return newValue;
110-
131+
this.options.onError( e ); // write your own error handling function
132+
return newValue;
111133
} else {
112134
newValue += placeholder[i];
113135
}
@@ -117,7 +139,7 @@ var masking = {
117139
}
118140
}
119141
if (e.target.getAttribute('data-valid-example')) {
120-
return masking.validateProgress(e, newValue);
142+
return this.validateProgress(e, newValue);
121143
}
122144
return newValue;
123145
},
@@ -146,11 +168,15 @@ var masking = {
146168
}
147169

148170
return value;
149-
},
150-
151-
errorOnKeyEntry : function () {
152-
// Write your own error handling
153171
}
154-
}
172+
};
173+
174+
// Declaritive initalization
175+
(function(){
176+
var scripts = document.getElementsByTagName( "script" ),
177+
script = scripts[ scripts.length - 1 ];
178+
if ( script.getAttribute( "data-autoinit" ) ) {
179+
masking.init();
180+
}
181+
})();
155182

156-
masking.init();

0 commit comments

Comments
 (0)