Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Adds tel input type validation #7315

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/;
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
var TIME_REGEXP = /^(\d\d):(\d\d)$/;
var TEL_REGEXP = /^[0-9+\(\)#\.\s\/ext-]+$/;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ext-" as part of the character class? that doesn't look right.

is there some precedence for making this a regular expression that is acceptable across all locales? localization of this stuff is usually pretty tricky and we can't have US only solution. :-/

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to allow extensions, eg 'x 2345' or 'ext 2342'.
'-' is allowed for obvious reasons.. 555-1234

I haven't been able to find any standard way of doing it, but this should
hold up well under i18n. It's the closest thing to a standard I could find.

Thinking this over, I'm not actually sure if this is the best way to do it.
An ng-pattern on each input also works.

-Walter

On Mon, May 19, 2014 at 3:18 PM, Igor Minar notifications@github.comwrote:

In src/ng/directive/input.js:

@@ -16,6 +16,7 @@ var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/;
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
var MONTH_REGEXP = /^(\d{4})-(\d\d)$/;
var TIME_REGEXP = /^(\d\d):(\d\d)$/;
+var TEL_REGEXP = /^[0-9+()#.\s/ext-]+$/;

"ext-" as part of the character class? that doesn't look right.

is there some precedence for making this a regular expression that is
acceptable across all locales? localization of this stuff is usually pretty
tricky and we can't have US only solution. :-/


Reply to this email directly or view it on GitHubhttps://github.com//pull/7315/files#r12811211
.

var DEFAULT_REGEXP = /(\b|^)default(\b|$)/;

var inputType = {
Expand Down Expand Up @@ -670,6 +671,83 @@ var inputType = {
'url': urlInputType,


/**
* @ngdoc input
* @name input[tel]
*
* @description
* HTML5 tel input validation. Will display a text input in browsers that do no yet support tel inputs.
* Sets the `tel` validation error key if the content is not a valid telephone number.
*
*
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} required Sets `required` validation error key if the value is not entered.
* @param {string=} ngRequired Adds `required` attribute and `required` validation constraint to
* the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
* `required` when you want to data-bind to the `required` attribute.
* @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than
* minlength.
* @param {number=} ngMaxlength Sets `maxlength` validation error key if the value is longer than
* maxlength.
* @param {string=} ngPattern Sets `pattern` validation error key if the value does not match the
* RegExp pattern expression. Expected value is `/regexp/` for inline patterns or `regexp` for
* patterns defined as scope expressions.
* @param {string=} ngChange Angular expression to be executed when input changes due to user
* interaction with the input element.
*
* @example
<example name="tel-input-directive">
<file name="index.html">
<script>
function Ctrl($scope) {
$scope.text = '(415) 555-1234 x 601';
}
</script>
<form name="myForm" ng-controller="Ctrl">
URL: <input type="tel" name="input" ng-model="text" required>
<span class="error" ng-show="myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.tel">
Not valid telephone number!</span>
<tt>text = {{text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
<tt>myForm.$error.tel = {{!!myForm.$error.tel}}</tt><br/>
</form>
</file>
<file name="protractor.js" type="protractor">
var text = element(by.binding('text'));
var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text'));

it('should initialize to model', function() {
expect(text.getText()).toContain('(415) 555-1234 x 601');
expect(valid.getText()).toContain('true');
});

it('should be invalid if empty', function() {
input.clear();
input.sendKeys('');

expect(text.getText()).toEqual('text =');
expect(valid.getText()).toContain('false');
});

it('should be invalid if not telephone', function() {
input.clear();
input.sendKeys('box');

expect(valid.getText()).toContain('false');
});
</file>
</example>
*/
'tel': telInputType,


/**
* @ngdoc input
* @name input[email]
Expand Down Expand Up @@ -1196,6 +1274,17 @@ function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) {
ctrl.$parsers.push(urlValidator);
}

function telInputType(scope, element, attr, ctrl, $sniffer, $browser) {
textInputType(scope, element, attr, ctrl, $sniffer, $browser);

var telValidator = function(value) {
return validate(ctrl, 'tel', ctrl.$isEmpty(value) || TEL_REGEXP.test(value), value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another one of those things which will probably drive us crazy because of the absolutely idiotic html5 constraint validation rules in the spec, if not now, then later.

I expect we probably only get a type mismatch error in modern browsers right now, if anything at all, so this is probably okay. But down the line it might be significantly less okay.

This isn't necessarily something to worry about now, and TBH I would say just ship it. However, I think this needs an LGTM from another core team member first.

};

ctrl.$formatters.push(telValidator);
ctrl.$parsers.push(telValidator);
}

function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
textInputType(scope, element, attr, ctrl, $sniffer, $browser);

Expand Down