Created
February 18, 2014 23:58
-
-
Save muratcorlu/9083266 to your computer and use it in GitHub Desktop.
Masked Input Directive trying for AngularJS (It's not working)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 0 User must enter a digit (0 to 9). | |
* 9 User can enter a digit (0 to 9). | |
* # User can enter a digit, space, plus or minus sign. If skipped, enters a blank space. | |
* L User must enter a letter. | |
* ? User can enter a letter. | |
* A User must enter a letter or a digit. | |
* a User can enter a letter or a digit. | |
* & User must enter either a character or a space. | |
* C User can enter characters or spaces. | |
* . , : ; - / Decimal and thousands placeholders, date and time separators. | |
* > Coverts all characters that follow to uppercase. | |
* < Converts all characters that follow to lowercase. | |
* ! Causes the input mask to fill from left to right instead of from right to left. | |
* \ Characters immediately following will be displayed literally. | |
* "" Characters enclosed in double quotation marks will be displayed literally. | |
* | |
* '"+90 "(000) 000 0000' => '+90 (___) ___ ____' | |
* +90 (533) 737 11 44 => 5337371144 | |
* | |
* | |
* Examples: | |
* | |
* '+90' (000) 000 0000 | |
* | |
* <input type="text" masked-input="'+90 '(000) 000 0000" ng-model="phonenumber"> | |
* | |
*/ | |
angular.module('sahibinden.input', []) | |
.value('maskConfig', { | |
maskRules: { | |
'0': /[0-9]/, | |
'9': /[0-9\ ]/, | |
'#': /[0-9\-\+\ ]/, | |
'L': /[a-zA-Z]/, | |
'?': /[a-zA-Z\ ]/, | |
'A': /[a-zA-Z0-9]/, | |
'a': /[a-zA-Z0-9\ ]/, | |
'&': /[a-zA-Z\ ]/, | |
'C': /[a-zA-Z\ ]/ | |
} | |
}) | |
.directive('maskedInput', function (maskConfig) { | |
'use strict'; | |
return { | |
restrict: 'A', // Only use as attribute | |
require: '?ngModel', // ngModel controller is required | |
link: function (scope, element, attrs, ngModel) { | |
var maskDefinition = attrs.maskedInput, | |
caretPositions = [], | |
// Get mask placeholder | |
maskPlaceholder = (function () { | |
var tmpPlaceholder = '', | |
escape = false, // For one-char escaping '\' | |
literalBlock = false, // For block level escaping with quotes | |
charIndex = 0; | |
angular.forEach(maskDefinition.split(''), function (char) { | |
// Escape next char if this is an escape char (\) | |
if (char == '\\') { | |
escape = true; | |
// Toggle literalBlock if this a quote char (' or ") | |
} else if (!escape && (char == '"' || char == '\'')) { | |
literalBlock = !literalBlock; | |
// Set rules if not an escaped char and if it's in maskRules list | |
} else if (!literalBlock && !escape && (char in maskConfig.maskRules)) { | |
caretPositions.push(charIndex); | |
tmpPlaceholder += '_'; | |
charIndex++; | |
// This char is not in rules and is not an escape char | |
// Then add to placeholder directly | |
} else { | |
charIndex++; | |
escape = false; | |
tmpPlaceholder += char; | |
} | |
}); | |
return tmpPlaceholder; | |
})(), | |
unmaskValue = function (maskedValue) { | |
var unmaskedValue = ''; | |
angular.forEach(caretPositions, function (pos) { | |
unmaskedValue += maskedValue.substr(pos, 1); | |
}); | |
return unmaskedValue.replace(/_/g, ''); | |
}, | |
getCaretPosition = function () { | |
var input = element[0], | |
selection; | |
if (input.selectionStart !== undefined) { | |
return input.selectionStart; | |
} else if (document.selection) { | |
// Curse you IE | |
input.focus(); | |
selection = document.selection.createRange(); | |
selection.moveStart('character', -input.value.length); | |
return selection.text.length; | |
} | |
return 0; | |
}, | |
setCaretPosition = function (pos) { | |
var input = element[0], | |
range; | |
if (input.offsetWidth === 0 || input.offsetHeight === 0) { | |
return; // Input's hidden | |
} | |
if (input.setSelectionRange) { | |
input.focus(); | |
input.setSelectionRange(pos, pos); | |
} | |
else if (input.createTextRange) { | |
// Curse you IE | |
range = input.createTextRange(); | |
range.collapse(true); | |
range.moveEnd('character', pos); | |
range.moveStart('character', pos); | |
range.select(); | |
} | |
}, | |
parser = function (value) { | |
console.debug('parser calisti'); | |
var isValid = false, | |
chars, | |
newValue; | |
console.log(value, unmaskValue(value), ngModel.$modelValue); | |
ngModel.$setValidity('mask', isValid); | |
value = unmaskValue(value); | |
if (value) { | |
chars = value.split(''); | |
newValue = maskPlaceholder.replace('_', function () { | |
return chars.pop(); | |
}); | |
if (newValue != value) { | |
ngModel.$setViewValue(newValue); | |
ngModel.$modelValue = value; | |
ngModel.$render(); | |
} | |
} | |
setCaretPosition(caretPositions[value.length]); | |
return value ? newValue : maskPlaceholder; | |
/* | |
if (value != maskPlaceholder) { | |
ngModel.$viewValue = maskPlaceholder; | |
ngModel.$render(); | |
} | |
return value;*/ | |
}, | |
formatter = function (value) { | |
console.debug('formatter calisti'); | |
if (value != maskPlaceholder) { | |
ngModel.$setViewValue(maskPlaceholder); | |
ngModel.$render(); | |
} | |
setCaretPosition(caretPositions[0]); | |
return maskPlaceholder; | |
}; | |
element.bind('keydown', function (event) { | |
var which = event.which, | |
$element = angular.element(this), | |
unmaskedValue = $element.data('unmaskedValue'), | |
value = $element.val(), | |
caretPosition = getCaretPosition(this); | |
unmaskedValue += String.fromCharCode(which); | |
$element.data('unmaskedValue', unmaskedValue); | |
this.value = this.value.substr(0, caretPosition) + String.fromCharCode(which) + this.value.substr(caretPosition + 2); | |
setCaretPosition(caretPosition + 1); | |
console.log(which, caretPosition, value); | |
return false; | |
}); | |
ngModel.$parsers.push(parser); | |
ngModel.$formatters.push(formatter); | |
console.log(maskDefinition, maskPlaceholder, caretPositions); | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment