Skip to content

Commit

Permalink
feat(uiFrPhoneMask): implement french phone number format
Browse files Browse the repository at this point in the history
  • Loading branch information
cdupoiron authored and assisrafael committed Sep 22, 2017
1 parent 9d9cf3d commit 6c1b450
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ _See more usage examples in the [Demo page](http://assisrafael.github.io/angular
- ui-br-car-plate-mask
- ui-scientific-notation-mask
- ui-us-phone-number
- ui-fr-phone-number

## Other build options

Expand All @@ -221,13 +222,15 @@ If you are using npm (without browserify):
- angular-input-masks-dependencies.js: provides all external dependencies (string-mask, br-validations, momentjs)
- angular-input-masks-br.js: provides only global and BR directives, and does not include external dependencies (string-mask, br-validations, momentjs)
- angular-input-masks-us.js: provides only global and US directives, and does not include external dependencies (string-mask, br-validations, momentjs)
- angular-input-masks-fr.js: provides only global and FR directives, and does not include external dependencies (string-mask, br-validations, momentjs)
- angular-input-masks.js: provides all directives, and does not include external dependencies (string-mask, br-validations, momentjs)

If you are using npm with browserify:

- ```require('angular-input-masks')```: provides all directives
- ```require('angular-input-masks/br')```: only global and BR directives
- ```require('angular-input-masks/us')```: only global and US directives
- ```require('angular-input-masks/fr')```: only global and FR directives

## Filters

Expand Down
27 changes: 27 additions & 0 deletions demo/fr.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>Angular Mask FR Demo</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.fr.js"></script>
<script>
angular.module('demo', ['ui.utils.masks.fr'])
.controller('ctrl', function ctrl($scope) {
$scope.initializedPhoneNumber = '3133536767';
});
</script>
</head>
<body ng-app="demo">
<form name="form" ng-controller="ctrl">
<h2>ui-fr-phone-number</h2>
<input id="fr-phone-input" type="text" name="phoneNumberTest" ng-model="phoneNumber" ui-fr-phone-number><br>
<span id="fr-phone-value">{{phoneNumber}}</span> - {{form.phoneNumberTest.$valid}}<br>
<br>
<input id="init-fr-phone-input" type="text" name="initializedPhoneNumberTest" ng-model="initializedPhoneNumber" ui-fr-phone-number><br>
<span id="init-fr-phone-value">{{initializedPhoneNumber}}</span> - {{form.initializedPhoneNumberTest.$valid}}<br>
<br>
</form>
</body>
</html>
1 change: 1 addition & 0 deletions fr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./src/angular-input-masks.fr');
9 changes: 9 additions & 0 deletions fr.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe('angular-input-masks-standalone', function () {
var moduleName = require('./fr.js');

beforeEach(angular.mock.module('ui.utils.masks'));

it('should export the module name', function () {
expect(moduleName).toBe('ui.utils.masks');
});
});
8 changes: 6 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ gulp.task('build', ['build-dependencies'], function() {
debug: false,
bundleExternal: false
}, {
fileName: 'angular-input-masks.us.js',
fileName: 'angular-input-masks.ch.js',
debug: false,
bundleExternal: false
}, {
fileName: 'angular-input-masks.ch.js',
fileName: 'angular-input-masks.fr.js',
debug: false,
bundleExternal: false
}, {
fileName: 'angular-input-masks.us.js',
debug: false,
bundleExternal: false
}, {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
"releases/",
"index.js",
"br.js",
"ch.js",
"fr.js",
"us.js",
"LICENSE",
"CHANGELOG.md",
Expand Down
4 changes: 4 additions & 0 deletions src/angular-input-masks.fr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = angular.module('ui.utils.masks', [
require('./global/global-masks'),
require('./fr/fr-masks')
]).name;
5 changes: 3 additions & 2 deletions src/angular-input-masks.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module.exports = angular.module('ui.utils.masks', [
require('./global/global-masks'),
require('./br/br-masks'),
require('./us/us-masks'),
require('./ch/ch-masks')
require('./ch/ch-masks'),
require('./fr/fr-masks'),
require('./us/us-masks')
]).name;
8 changes: 8 additions & 0 deletions src/fr/fr-masks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

var m = angular.module('ui.utils.masks.fr', [
require('../helpers')
])
.directive('uiFrPhoneNumber', require('./phone/fr-phone'));

module.exports = m.name;
29 changes: 29 additions & 0 deletions src/fr/phone/fr-phone.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FR Phone Number 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.fr.js"></script>
<script>
angular.module('app', ['ui.utils.masks'])
.controller('ctrl', function ctrl($scope) {
$scope.initializedPhoneNumber = '3133536767';
});
</script>
</head>
<body ng-app="app">
<form name="form" ng-controller="ctrl">
<h2>ui-fr-phone-number</h2>
<input id="fr-phone-input" type="text" name="phoneNumberTest" ng-model="phoneNumber" ng-model-options="{allowInvalid:true}" ui-fr-phone-number><br>
<span id="fr-phone-value">{{phoneNumber}}</span> - {{form.phoneNumberTest.$valid}}

<br>
<br>

<input id="init-fr-phone-input" type="text" name="initializedPhoneNumberTest" ng-model="initializedPhoneNumber" ng-model-options="{allowInvalid:true}" ui-fr-phone-number><br>
<span id="init-fr-phone-value">{{initializedPhoneNumber}}</span> - {{form.initializedPhoneNumberTest.$valid}}<br>
</form>
</body>
</html>
25 changes: 25 additions & 0 deletions src/fr/phone/fr-phone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

var StringMask = require('string-mask');
var maskFactory = require('../../libs/mask-factory');

var phoneMaskFR = new StringMask('00 00 00 00 00');

module.exports = maskFactory({
clearValue: function(rawValue) {
return rawValue.toString().replace(/[^0-9]/g, '').slice(0, 10);
},
format: function(cleanValue) {
var formattedValue;

formattedValue = phoneMaskFR.apply(cleanValue) || '';

return formattedValue.trim().replace(/[^0-9]$/, '');
},
validations: {
frPhoneNumber: function(value) {
var valueLength = value && value.toString().length;
return valueLength === 10;
}
}
});
64 changes: 64 additions & 0 deletions src/fr/phone/fr-phone.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use strict';

describe('ui.utils.masks.fr.phone', function() {
it('should load the demo page', function() {
browser.get('/src/fr/phone/fr-phone.html');
expect(browser.getTitle()).toEqual('FR Phone Number Spec');
});

describe('ui-fr-phone-number:', function() {
var runTests = function(input, value) {
var BS = protractor.Key.BACK_SPACE;
var tests = [
{key:'1', viewValue:'1', modelValue:'1'},
{key:'2', viewValue:'12', modelValue:'12'},
{key:'3', viewValue:'12 3', modelValue:'123'},
{key:'4', viewValue:'12 34', modelValue:'1234'},
{key:'5', viewValue:'12 34 5', modelValue:'12345'},
{key:'6', viewValue:'12 34 56', modelValue:'123456'},
{key:'7', viewValue:'12 34 56 7', modelValue:'1234567'},
{key:'8', viewValue:'12 34 56 78', modelValue:'12345678'},
{key:'9', viewValue:'12 34 56 78 9', modelValue:'123456789'},
{key:'0', viewValue:'12 34 56 78 90', modelValue:'1234567890'},
{key:'1', viewValue:'12 34 56 78 90', modelValue:'1234567890'},
{key:BS, viewValue:'12 34 56 78 9', modelValue:'123456789'},
{key:BS, viewValue:'12 34 56 78 ', modelValue:'12345678'},
{key:BS, viewValue:'12 34 56 78', modelValue:'12345678'},
{key:BS, viewValue:'12 34 56 7', modelValue:'1234567'},
{key:BS, viewValue:'12 34 56 ', modelValue:'123456'},
{key:BS, viewValue:'12 34 56', modelValue:'123456'},
{key:BS, viewValue:'12 34 5', modelValue:'12345'},
{key:BS, viewValue:'12 34 ', modelValue:'1234'},
{key:BS, viewValue:'12 34', modelValue:'1234'},
{key:BS, viewValue:'12 3', modelValue:'123'},
{key:BS, viewValue:'12 ', modelValue:'12'},
{key:BS, viewValue:'12', modelValue:'12'},
{key:BS, viewValue:'1', modelValue:'1'},
{key:BS, viewValue:'', modelValue:''},
];

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 phone number mask while the user is typing:', function() {
var input = element(by.id('fr-phone-input')),
value = element(by.id('fr-phone-value'));

runTests(input, value);
});

it('should apply a phone number mask in a model with default value:', function() {
var input = element(by.id('init-fr-phone-input')),
value = element(by.id('init-fr-phone-value'));

expect(input.getAttribute('value')).toEqual('31 33 53 67 67');
input.clear();

runTests(input, value);
});
});
});
53 changes: 53 additions & 0 deletions src/fr/phone/fr-phone.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

require('../fr-masks');

describe('ui-fr-phone-mask', function() {
beforeEach(angular.mock.module('ui.utils.masks.fr'));

it('should throw an error if used without ng-model', function() {
expect(function() {
TestUtil.compile('<input ui-fr-phone-number>');
}).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-fr-phone-number>');
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 (4+10D)', function() {
var input = TestUtil.compile('<input ng-model="model" ui-fr-phone-number>', {
model: '3011201034'
});

var model = input.controller('ngModel');
expect(model.$viewValue).toBe('30 11 20 10 34');
});

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

var tests = [
{value:'@', viewValue:'', modelValue:''},
{value:'2-', viewValue:'2', modelValue:'2'},
{value:'23a', viewValue:'23', modelValue:'23'},
{value:'23_34', viewValue:'23 34', modelValue:'2334'},
{value:'23346!', viewValue:'23 34 6', modelValue:'23346'},
{value:'23346!324', viewValue:'23 34 63 24', modelValue:'23346324'},
];

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 6c1b450

Please sign in to comment.