Skip to content

Commit

Permalink
feat(ui-br-car-plate-mask): input mask for brazilian car plate
Browse files Browse the repository at this point in the history
  • Loading branch information
dflourusso committed Mar 3, 2016
1 parent 0617380 commit 03d971b
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ _See more usage examples in the [Demo page](http://assisrafael.github.io/angular
- ui-time-mask
- ui-date-mask
- ui-br-boleto-bancario-mask
- ui-br-car-plate-mask
- ui-scientific-notation-mask
- ui-us-phone-number

Expand Down
5 changes: 5 additions & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ <h2>ui-br-ie-mask</h2>
<input type="text" name="field20" ng-model="inscEst" ui-br-ie-mask="state"><br>
<span ng-bind="state"></span>: <span ng-bind="inscEst"></span> - <span ng-bind="form.field20.$error | json"></span><br>
<br>

<h2>ui-br-car-plate-mask</h2>
<input type="text" name="field25" ng-model="carPlate" ui-br-car-plate-mask><br>
<span></span>Plate: <span ng-bind="carPlate"></span> - <span ng-bind="form.field25.$error | json"></span><br>
<br>
</form>
</body>
</html>
1 change: 1 addition & 0 deletions src/br/br-masks.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var m = angular.module('ui.utils.masks.br', [
.directive('uiBrCpfcnpjMask', require('./cpf-cnpj/cpf-cnpj'))
.directive('uiBrIeMask', require('./inscricao-estadual/ie'))
.directive('uiNfeAccessKeyMask', require('./nfe/nfe'))
.directive('uiBrCarPlateMask', require('./car-plate/car-plate'))
.directive('uiBrPhoneNumber', require('./phone/br-phone'));

module.exports = m.name;
27 changes: 27 additions & 0 deletions src/br/car-plate/car-plate.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Car Plate Spec</title>
<script src="/node_modules/angular/angular.min.js"></script>
<script src="/releases/angular-input-masks-dependencies.js"></script>
<script src="/releases/angular-input-masks.br.js"></script>
<script>
angular.module('app', ['ui.utils.masks'])
.controller('ctrl', function ctrl($scope) {
$scope.initializedCarPlate = 'ABC2010';
});
</script>
</head>
<body ng-app="app">
<form name="form" ng-controller="ctrl">
<h2>ui-br-car-plate-mask</h2>
<input type="text" name="field17" ng-model="initializedCarPlate" ui-br-car-plate-mask><br>
<span ng-bind="initializedCarPlate"></span> - {{form.field17.$error}}<br>
<br>
<input type="text" name="field18" ng-model="carPlate" ng-model-options="{allowInvalid:true}" ui-br-car-plate-mask><br>
<span ng-bind="carPlate"></span> - {{form.field18.$error}}<br>
<br>
</form>
</body>
</html>
18 changes: 18 additions & 0 deletions src/br/car-plate/car-plate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var StringMask = require('string-mask');
var maskFactory = require('mask-factory');

var carPlateMask = new StringMask('UUU-0000');

module.exports = maskFactory({
clearValue: function(rawValue) {
return rawValue.replace(/[^a-zA-Z0-9]/g, '').slice(0, 7);
},
format: function(cleanValue) {
return (carPlateMask.apply(cleanValue) || '').replace(/[^a-zA-Z0-9]$/, '');
},
validations: {
carPlate: function(value) {
return value.length === 7;
}
}
});
49 changes: 49 additions & 0 deletions src/br/car-plate/car-plate.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
var StringMask = require('string-mask');

describe('ui.utils.masks.br.car-plate', function() {
it('should load the demo page', function() {
browser.get('/src/br/car-plate/car-plate.html');
expect(browser.getTitle()).toEqual('Car Plate Spec');
});

describe('ui-br-car-plate-mask:', function() {
it('should apply a Car Plate mask while the user is typping:', function() {
var BS = protractor.Key.BACK_SPACE;

var tests = [
{key:'@', viewValue:'', modelValue:''},
{key:'A', viewValue:'A', modelValue:'A'},
{key:'B', viewValue:'AB', modelValue:'AB'},
{key:'C', viewValue:'ABC', modelValue:'ABC'},
{key:'-', viewValue:'ABC', modelValue:'ABC'},
{key:'2', viewValue:'ABC-2', modelValue:'ABC2'},
{key:'0', viewValue:'ABC-20', modelValue:'ABC20'},
{key:'1', viewValue:'ABC-201', modelValue:'ABC201'},
{key:'0', viewValue:'ABC-2010', modelValue:'ABC2010'},
{key:'9', viewValue:'ABC-2010', modelValue:'ABC2010'},
{key:BS, viewValue:'ABC-201', modelValue:'ABC201'},
{key:BS, viewValue:'ABC-20', modelValue:'ABC20'},
{key:BS, viewValue:'ABC-2', modelValue:'ABC2'},
{key:BS, viewValue:'ABC', modelValue:'ABC'},
{key:BS, viewValue:'AB', modelValue:'AB'},
{key:BS, viewValue:'A', modelValue:'A'},
];

var input = element(by.model('carPlate')),
value = element(by.binding('carPlate'));

for (var i = 0; i < tests.length; i++) {
input.sendKeys(tests[i].key);
expect(input.getAttribute('value')).toEqual(tests[i].viewValue);
expect(value.getText()).toEqual(tests[i].modelValue);
}
});

it('should apply a Car Plate mask in a model with default value:', function() {
var input = element(by.model('initializedCarPlate')),
value = element(by.binding('initializedCarPlate'));

expect(input.getAttribute('value')).toEqual('ABC-2010');
});
});
});
60 changes: 60 additions & 0 deletions src/br/car-plate/car-plate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require('../br-masks');

describe('ui-br-car-plate-mask', function() {
beforeEach(angular.mock.module('ui.utils.masks.br'));

it('should throw an error if used without ng-model', function() {
expect(function() {
TestUtil.compile('<input ui-br-car-plate-mask>');
}).toThrow();
});

it('should register a $parser and a $formatter', function() {
var input = TestUtil.compile('<input ng-model="model">');
var model = input.controller('ngModel');

var maskedInput = TestUtil.compile('<input ng-model="maskedModel" ui-br-car-plate-mask>');
var maskedModel = maskedInput.controller('ngModel');

expect(maskedModel.$parsers.length).toBe(model.$parsers.length + 1);
expect(maskedModel.$formatters.length).toBe(model.$formatters.length + 1);
});

it('should format initial model values', function() {
var input = TestUtil.compile('<input ng-model="model" ui-br-car-plate-mask>', {
model: 'ABC2010'
});

var model = input.controller('ngModel');
expect(model.$viewValue).toBe('ABC-2010');
});

it('should accept formatted initial model values', function() {
var input = TestUtil.compile('<input ng-model="model" ui-br-car-plate-mask>', {
model: 'ABC-2010'
});

var model = input.controller('ngModel');
expect(model.$viewValue).toBe('ABC-2010');
});

it('should ignore non digits', function() {
var input = TestUtil.compile('<input ng-model="model"' +
'ng-model-options="{allowInvalid:true}" ui-br-car-plate-mask>');
var model = input.controller('ngModel');

var tests = [
{value:'@', viewValue:'', modelValue:''},
{value:'A-', viewValue:'A', modelValue:'A'},
{value:'ABC_2', viewValue:'ABC-2', modelValue:'ABC2'},
{value:'ABC!2', viewValue:'ABC-2', modelValue:'ABC2'},
{value:'ABC!2324', viewValue:'ABC-2324', modelValue:'ABC2324'},
];

tests.forEach(function(test) {
input.val(test.value).triggerHandler('input');
expect(model.$viewValue).toBe(test.viewValue);
expect(model.$modelValue).toBe(test.modelValue);
});
});
});

0 comments on commit 03d971b

Please sign in to comment.