diff --git a/ch.js b/ch.js new file mode 100644 index 00000000..cc1245c1 --- /dev/null +++ b/ch.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./src/angular-input-masks.ch'); diff --git a/ch.test.js b/ch.test.js new file mode 100644 index 00000000..4acae8fb --- /dev/null +++ b/ch.test.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('angular-input-masks-standalone', function() { + var moduleName = require('./ch.js'); + + beforeEach(angular.mock.module('ui.utils.masks')); + + it('should export the module name', function() { + expect(moduleName).toBe('ui.utils.masks'); + }); +}); diff --git a/gulpfile.js b/gulpfile.js index f739f72c..b48fa05f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -63,6 +63,10 @@ gulp.task('build', ['build-dependencies'], function() { fileName: 'angular-input-masks.us.js', debug: false, bundleExternal: false + }, { + fileName: 'angular-input-masks.ch.js', + debug: false, + bundleExternal: false }, { fileName: 'angular-input-masks.js', outputFileName: 'angular-input-masks-standalone.js', diff --git a/src/angular-input-masks.ch.js b/src/angular-input-masks.ch.js new file mode 100644 index 00000000..acd7ddbe --- /dev/null +++ b/src/angular-input-masks.ch.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = angular.module('ui.utils.masks', [ + require('./global/global-masks'), + require('./ch/ch-masks') +]).name; diff --git a/src/angular-input-masks.js b/src/angular-input-masks.js index 9d2a31f2..293518a7 100644 --- a/src/angular-input-masks.js +++ b/src/angular-input-masks.js @@ -3,5 +3,6 @@ module.exports = angular.module('ui.utils.masks', [ require('./global/global-masks'), require('./br/br-masks'), - require('./us/us-masks') + require('./us/us-masks'), + require('./ch/ch-masks') ]).name; diff --git a/src/ch/ch-masks.js b/src/ch/ch-masks.js new file mode 100644 index 00000000..14215bdb --- /dev/null +++ b/src/ch/ch-masks.js @@ -0,0 +1,8 @@ +'use strict'; + +var m = angular.module('ui.utils.masks.ch', [ + require('../helpers'), +]) +.directive('uiChPhoneNumber', require('./phone/ch-phone')); + +module.exports = m.name; diff --git a/src/ch/phone/ch-phone.html b/src/ch/phone/ch-phone.html new file mode 100644 index 00000000..8bfbc67d --- /dev/null +++ b/src/ch/phone/ch-phone.html @@ -0,0 +1,29 @@ + + + + + CH Phone Number Spec + + + + + + +
+

ui-br-phone-number

+
+ - - {{form.freeLinePhoneNumber.$error}}
+
+
+ - - {{form.phoneNumber.$error}}
+
+
+ - - {{form.initializedPhoneNumber.$error}}
+
+ + diff --git a/src/ch/phone/ch-phone.js b/src/ch/phone/ch-phone.js new file mode 100644 index 00000000..bf75a2f8 --- /dev/null +++ b/src/ch/phone/ch-phone.js @@ -0,0 +1,25 @@ +'use strict'; + +var StringMask = require('string-mask'); +var maskFactory = require('mask-factory'); + +var phoneMask = new StringMask('+00 00 000 00 00'); + +module.exports = maskFactory({ + clearValue: function(rawValue) { + return rawValue.toString().replace(/[^0-9]/g, '').slice(0, 11); + }, + format: function(cleanValue) { + var formatedValue; + + formatedValue = phoneMask.apply(cleanValue) || ''; + + return formatedValue.trim().replace(/[^0-9]$/, ''); + }, + validations: { + chPhoneNumber: function(value) { + var valueLength = value && value.toString().length; + return valueLength === 11; + } + } +}); diff --git a/src/ch/phone/ch-phone.spec.js b/src/ch/phone/ch-phone.spec.js new file mode 100644 index 00000000..34406827 --- /dev/null +++ b/src/ch/phone/ch-phone.spec.js @@ -0,0 +1,88 @@ +'use strict'; + +describe('ui.utils.masks.number', function() { + it('should load the demo page', function() { + browser.get('/src/ch/phone/ch-phone.html'); + expect(browser.getTitle()).toEqual('CH Phone Number Spec'); + }); + + describe('ui-ch-phone-number:', function() { + it('should apply a phone number mask while the user is typping:', function() { + 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 567', modelValue:'1234567'}, + {key:'8', viewValue:'+12 34 567 8', modelValue:'12345678'}, + {key:'9', viewValue:'+12 34 567 89', modelValue:'123456789'}, + {key:'0', viewValue:'+12 34 567 89 0', modelValue:'1234567890'}, + {key:'1', viewValue:'+12 34 567 89 01', modelValue:'12345678901'}, + {key:'2', viewValue:'+12 34 567 89 01', modelValue:'12345678901'}, + {key:BS, viewValue:'+12 34 567 89 0', modelValue:'1234567890'}, + {key:BS, viewValue:'+12 34 567 89 ', modelValue:'123456789'}, + {key:BS, viewValue:'+12 34 567 89', modelValue:'123456789'}, + {key:BS, viewValue:'+12 34 567 8', modelValue:'12345678'}, + {key:BS, viewValue:'+12 34 567 ', modelValue:'1234567'}, + {key:BS, viewValue:'+12 34 567', modelValue:'1234567'}, + {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:''}, + ]; + + var input = element(by.model('phoneNumber')), + value = element(by.exactBinding('phoneNumber')); + + 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 in a model with default value:', function() { + 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 567', modelValue:'1234567'}, + {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:''}, + ]; + + var input = element(by.model('initializedPhoneNumber')), + value = element(by.exactBinding('initializedPhoneNumber')); + + expect(input.getAttribute('value')).toEqual('+41 79 000 00 00'); + input.clear(); + + 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); + } + }); + }); +}); diff --git a/src/ch/phone/ch-phone.test.js b/src/ch/phone/ch-phone.test.js new file mode 100644 index 00000000..2679734a --- /dev/null +++ b/src/ch/phone/ch-phone.test.js @@ -0,0 +1,78 @@ +'use strict'; + +require('../ch-masks'); + +describe('ui-ch-phone-number', function() { + beforeEach(angular.mock.module('ui.utils.masks.ch')); + + it('should throw an error if used without ng-model', function() { + expect(function() { + TestUtil.compile(''); + }).toThrow(); + }); + + it('should register a $parser and a $formatter', function() { + var input = TestUtil.compile(''); + var model = input.controller('ngModel'); + + var maskedInput = TestUtil.compile(''); + 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('', { + model: '41790000000' + }); + + var model = input.controller('ngModel'); + expect(model.$viewValue).toBe('+41 79 000 00 00'); + }); + + it('should ignore non digits', function() { + var input = TestUtil.compile(''); + 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 632 4', modelValue:'23346324'}, + ]; + + tests.forEach(function(test) { + input.val(test.value).triggerHandler('input'); + expect(model.$viewValue).toBe(test.viewValue); + expect(model.$modelValue).toBe(test.modelValue); + }); + }); + + it('should validate a phone number', function() { + var input = TestUtil.compile('', { + model: '417900' + }); + + var model = input.controller('ngModel'); + expect(model.$error.chPhoneNumber).toBe(true); + input.val('41790000000').triggerHandler('input'); + expect(model.$error.chPhoneNumber).toBeUndefined(); + }); + + it('should use the type of the model value (if initialized)', function() { + var input = TestUtil.compile('', { + model: '41790000000' + }); + + var model = input.controller('ngModel'); + expect(model.$viewValue).toBe('+41 79 000 00 00'); + expect(model.$modelValue).toBe('41790000000'); + input.val('41619618686').triggerHandler('input'); + expect(model.$viewValue).toBe('+41 61 961 86 86'); + expect(model.$modelValue).toBe('41619618686'); + }); +});