Skip to content

Commit f3723c8

Browse files
philippspinnlerassisrafael
authored andcommitted
feat(uiChPhoneNumber): add ch (Switzerland) phone mask
* Added ch (switzerland) phone mask * little clean up * Fixed failing tests
1 parent 1174428 commit f3723c8

10 files changed

+254
-1
lines changed

ch.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
module.exports = require('./src/angular-input-masks.ch');

ch.test.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict';
2+
3+
describe('angular-input-masks-standalone', function() {
4+
var moduleName = require('./ch.js');
5+
6+
beforeEach(angular.mock.module('ui.utils.masks'));
7+
8+
it('should export the module name', function() {
9+
expect(moduleName).toBe('ui.utils.masks');
10+
});
11+
});

gulpfile.js

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ gulp.task('build', ['build-dependencies'], function() {
6363
fileName: 'angular-input-masks.us.js',
6464
debug: false,
6565
bundleExternal: false
66+
}, {
67+
fileName: 'angular-input-masks.ch.js',
68+
debug: false,
69+
bundleExternal: false
6670
}, {
6771
fileName: 'angular-input-masks.js',
6872
outputFileName: 'angular-input-masks-standalone.js',

src/angular-input-masks.ch.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'use strict';
2+
3+
module.exports = angular.module('ui.utils.masks', [
4+
require('./global/global-masks'),
5+
require('./ch/ch-masks')
6+
]).name;

src/angular-input-masks.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
module.exports = angular.module('ui.utils.masks', [
44
require('./global/global-masks'),
55
require('./br/br-masks'),
6-
require('./us/us-masks')
6+
require('./us/us-masks'),
7+
require('./ch/ch-masks')
78
]).name;

src/ch/ch-masks.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
var m = angular.module('ui.utils.masks.ch', [
4+
require('../helpers'),
5+
])
6+
.directive('uiChPhoneNumber', require('./phone/ch-phone'));
7+
8+
module.exports = m.name;

src/ch/phone/ch-phone.html

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>CH Phone Number Spec</title>
6+
<script src="/node_modules/angular/angular.min.js"></script>
7+
<script src="/releases/angular-input-masks-dependencies.js"></script>
8+
<script src="/releases/angular-input-masks.ch.js"></script>
9+
<script>
10+
angular.module('app', ['ui.utils.masks'])
11+
.controller('ctrl', function ctrl($scope) {
12+
$scope.initializedPhoneNumber = '41790000000';
13+
});
14+
</script>
15+
</head>
16+
<body ng-app="app">
17+
<form name="form" ng-controller="ctrl">
18+
<h2>ui-br-phone-number</h2>
19+
<input type="text" name="freeLinePhoneNumber" ng-model="freeLinePhoneNumber" ng-model-options="{allowInvalid:true}" ui-ch-phone-number><br>
20+
<span ng-bind="freeLinePhoneNumber">-</span> - {{form.freeLinePhoneNumber.$error}}<br>
21+
<br>
22+
<input type="text" name="phoneNumber" ng-model="phoneNumber" ng-model-options="{allowInvalid:true}" ui-ch-phone-number><br>
23+
<span ng-bind="phoneNumber">-</span> - {{form.phoneNumber.$error}}<br>
24+
<br>
25+
<input type="text" name="initializedPhoneNumber" ng-model="initializedPhoneNumber" ng-model-options="{allowInvalid:true}" ui-ch-phone-number><br>
26+
<span ng-bind="initializedPhoneNumber">-</span> - {{form.initializedPhoneNumber.$error}}<br>
27+
</form>
28+
</body>
29+
</html>

src/ch/phone/ch-phone.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
var StringMask = require('string-mask');
4+
var maskFactory = require('mask-factory');
5+
6+
var phoneMask = new StringMask('+00 00 000 00 00');
7+
8+
module.exports = maskFactory({
9+
clearValue: function(rawValue) {
10+
return rawValue.toString().replace(/[^0-9]/g, '').slice(0, 11);
11+
},
12+
format: function(cleanValue) {
13+
var formatedValue;
14+
15+
formatedValue = phoneMask.apply(cleanValue) || '';
16+
17+
return formatedValue.trim().replace(/[^0-9]$/, '');
18+
},
19+
validations: {
20+
chPhoneNumber: function(value) {
21+
var valueLength = value && value.toString().length;
22+
return valueLength === 11;
23+
}
24+
}
25+
});

src/ch/phone/ch-phone.spec.js

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
'use strict';
2+
3+
describe('ui.utils.masks.number', function() {
4+
it('should load the demo page', function() {
5+
browser.get('/src/ch/phone/ch-phone.html');
6+
expect(browser.getTitle()).toEqual('CH Phone Number Spec');
7+
});
8+
9+
describe('ui-ch-phone-number:', function() {
10+
it('should apply a phone number mask while the user is typping:', function() {
11+
var BS = protractor.Key.BACK_SPACE;
12+
13+
var tests = [
14+
{key:'1', viewValue:'+1', modelValue:'1'},
15+
{key:'2', viewValue:'+12', modelValue:'12'},
16+
{key:'3', viewValue:'+12 3', modelValue:'123'},
17+
{key:'4', viewValue:'+12 34', modelValue:'1234'},
18+
{key:'5', viewValue:'+12 34 5', modelValue:'12345'},
19+
{key:'6', viewValue:'+12 34 56', modelValue:'123456'},
20+
{key:'7', viewValue:'+12 34 567', modelValue:'1234567'},
21+
{key:'8', viewValue:'+12 34 567 8', modelValue:'12345678'},
22+
{key:'9', viewValue:'+12 34 567 89', modelValue:'123456789'},
23+
{key:'0', viewValue:'+12 34 567 89 0', modelValue:'1234567890'},
24+
{key:'1', viewValue:'+12 34 567 89 01', modelValue:'12345678901'},
25+
{key:'2', viewValue:'+12 34 567 89 01', modelValue:'12345678901'},
26+
{key:BS, viewValue:'+12 34 567 89 0', modelValue:'1234567890'},
27+
{key:BS, viewValue:'+12 34 567 89 ', modelValue:'123456789'},
28+
{key:BS, viewValue:'+12 34 567 89', modelValue:'123456789'},
29+
{key:BS, viewValue:'+12 34 567 8', modelValue:'12345678'},
30+
{key:BS, viewValue:'+12 34 567 ', modelValue:'1234567'},
31+
{key:BS, viewValue:'+12 34 567', modelValue:'1234567'},
32+
{key:BS, viewValue:'+12 34 56', modelValue:'123456'},
33+
{key:BS, viewValue:'+12 34 5', modelValue:'12345'},
34+
{key:BS, viewValue:'+12 34 ', modelValue:'1234'},
35+
{key:BS, viewValue:'+12 34', modelValue:'1234'},
36+
{key:BS, viewValue:'+12 3', modelValue:'123'},
37+
{key:BS, viewValue:'+12 ', modelValue:'12'},
38+
{key:BS, viewValue:'+12', modelValue:'12'},
39+
{key:BS, viewValue:'+1', modelValue:'1'},
40+
{key:BS, viewValue:'', modelValue:''},
41+
];
42+
43+
var input = element(by.model('phoneNumber')),
44+
value = element(by.exactBinding('phoneNumber'));
45+
46+
for (var i = 0; i < tests.length; i++) {
47+
input.sendKeys(tests[i].key);
48+
expect(input.getAttribute('value')).toEqual(tests[i].viewValue);
49+
expect(value.getText()).toEqual(tests[i].modelValue);
50+
}
51+
});
52+
53+
it('should apply a phone number mask in a model with default value:', function() {
54+
var BS = protractor.Key.BACK_SPACE;
55+
56+
var tests = [
57+
{key:'1', viewValue:'+1', modelValue:'1'},
58+
{key:'2', viewValue:'+12', modelValue:'12'},
59+
{key:'3', viewValue:'+12 3', modelValue:'123'},
60+
{key:'4', viewValue:'+12 34', modelValue:'1234'},
61+
{key:'5', viewValue:'+12 34 5', modelValue:'12345'},
62+
{key:'6', viewValue:'+12 34 56', modelValue:'123456'},
63+
{key:'7', viewValue:'+12 34 567', modelValue:'1234567'},
64+
{key:BS, viewValue:'+12 34 56', modelValue:'123456'},
65+
{key:BS, viewValue:'+12 34 5', modelValue:'12345'},
66+
{key:BS, viewValue:'+12 34 ', modelValue:'1234'},
67+
{key:BS, viewValue:'+12 34', modelValue:'1234'},
68+
{key:BS, viewValue:'+12 3', modelValue:'123'},
69+
{key:BS, viewValue:'+12 ', modelValue:'12'},
70+
{key:BS, viewValue:'+12', modelValue:'12'},
71+
{key:BS, viewValue:'+1', modelValue:'1'},
72+
{key:BS, viewValue:'', modelValue:''},
73+
];
74+
75+
var input = element(by.model('initializedPhoneNumber')),
76+
value = element(by.exactBinding('initializedPhoneNumber'));
77+
78+
expect(input.getAttribute('value')).toEqual('+41 79 000 00 00');
79+
input.clear();
80+
81+
for (var i = 0; i < tests.length; i++) {
82+
input.sendKeys(tests[i].key);
83+
expect(input.getAttribute('value')).toEqual(tests[i].viewValue);
84+
expect(value.getText()).toEqual(tests[i].modelValue);
85+
}
86+
});
87+
});
88+
});

src/ch/phone/ch-phone.test.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
require('../ch-masks');
4+
5+
describe('ui-ch-phone-number', function() {
6+
beforeEach(angular.mock.module('ui.utils.masks.ch'));
7+
8+
it('should throw an error if used without ng-model', function() {
9+
expect(function() {
10+
TestUtil.compile('<input ui-ch-phone-number>');
11+
}).toThrow();
12+
});
13+
14+
it('should register a $parser and a $formatter', function() {
15+
var input = TestUtil.compile('<input ng-model="model">');
16+
var model = input.controller('ngModel');
17+
18+
var maskedInput = TestUtil.compile('<input ng-model="maskedModel" ui-ch-phone-number>');
19+
var maskedModel = maskedInput.controller('ngModel');
20+
21+
expect(maskedModel.$parsers.length).toBe(model.$parsers.length + 1);
22+
expect(maskedModel.$formatters.length).toBe(model.$formatters.length + 1);
23+
});
24+
25+
it('should format initial model values', function() {
26+
var input = TestUtil.compile('<input ng-model="model" ui-ch-phone-number>', {
27+
model: '41790000000'
28+
});
29+
30+
var model = input.controller('ngModel');
31+
expect(model.$viewValue).toBe('+41 79 000 00 00');
32+
});
33+
34+
it('should ignore non digits', function() {
35+
var input = TestUtil.compile('<input ng-model="model" ng-model-options="{allowInvalid:true}"' +
36+
' ui-ch-phone-number>');
37+
var model = input.controller('ngModel');
38+
39+
var tests = [
40+
{value:'@', viewValue:'', modelValue:''},
41+
{value:'2-', viewValue:'+2', modelValue:'2'},
42+
{value:'23a', viewValue:'+23', modelValue:'23'},
43+
{value:'23_34', viewValue:'+23 34', modelValue:'2334'},
44+
{value:'23346!', viewValue:'+23 34 6', modelValue:'23346'},
45+
{value:'23346!324', viewValue:'+23 34 632 4', modelValue:'23346324'},
46+
];
47+
48+
tests.forEach(function(test) {
49+
input.val(test.value).triggerHandler('input');
50+
expect(model.$viewValue).toBe(test.viewValue);
51+
expect(model.$modelValue).toBe(test.modelValue);
52+
});
53+
});
54+
55+
it('should validate a phone number', function() {
56+
var input = TestUtil.compile('<input ng-model="model" ui-ch-phone-number>', {
57+
model: '417900'
58+
});
59+
60+
var model = input.controller('ngModel');
61+
expect(model.$error.chPhoneNumber).toBe(true);
62+
input.val('41790000000').triggerHandler('input');
63+
expect(model.$error.chPhoneNumber).toBeUndefined();
64+
});
65+
66+
it('should use the type of the model value (if initialized)', function() {
67+
var input = TestUtil.compile('<input ng-model="model" ui-ch-phone-number>', {
68+
model: '41790000000'
69+
});
70+
71+
var model = input.controller('ngModel');
72+
expect(model.$viewValue).toBe('+41 79 000 00 00');
73+
expect(model.$modelValue).toBe('41790000000');
74+
input.val('41619618686').triggerHandler('input');
75+
expect(model.$viewValue).toBe('+41 61 961 86 86');
76+
expect(model.$modelValue).toBe('41619618686');
77+
});
78+
});

0 commit comments

Comments
 (0)