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

fix(ngList):Make ngList work with input of type email, url #4549

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@ function map(obj, iterator, context) {
return results;
}

function every(array, fun) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You need to make this visible globally to jshint, otherwise it will complain about this. See the top of the file for examples

for (var i = 0; i < array.length; i++) {
if (i in array && !fun.call(array, array[i], i, Object(array))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure we need to pass the array as context to the function. If we don't need this, then we shouldn't, because there can be a bit of a performance penalty for using Function#call() instead of just a regular function call, although it is most likely not worth worrying about.

return false;
}
}
return true;
}

/**
* @description
Expand Down
19 changes: 16 additions & 3 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\
var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;



var inputType = {

/**
Expand Down Expand Up @@ -581,9 +583,14 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {

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

var testedValid;
var urlValidator = function(value) {
if (ctrl.$isEmpty(value) || URL_REGEXP.test(value)) {
if (isArray(value)) {
testedValid = every(value, function(val){return URL_REGEXP.test(val)})
Copy link
Contributor

Choose a reason for hiding this comment

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

You need a semicolon after return URL_REGEXP.test(val)

} else {
testedValid = URL_REGEXP.test(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

missing semicolon here too

}
if (ctrl.$isEmpty(value) || testedValid) {
ctrl.$setValidity('url', true);
return value;
} else {
Expand All @@ -600,7 +607,13 @@ function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
textInputType(scope, element, attr, ctrl, $sniffer, $browser);

var emailValidator = function(value) {
if (ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value)) {
var testedValid;
if (isArray(value)) {
testedValid = every(value, function(val){return EMAIL_REGEXP.test(val)})
Copy link
Contributor

Choose a reason for hiding this comment

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

another here

} else {
testedValid = EMAIL_REGEXP.test(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

and here

}
if (ctrl.$isEmpty(value) || testedValid) {
ctrl.$setValidity('email', true);
return value;
} else {
Expand Down
136 changes: 112 additions & 24 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -726,50 +726,138 @@ describe('input', function() {
});

describe('email', function() {
describe('should validate e-mail', function(){
it('when used simply', function() {
compileInput('<input type="email" ng-model="email" name="alias" />');
var widget = scope.form.alias;

it('should validate e-mail', function() {
compileInput('<input type="email" ng-model="email" name="alias" />');
changeInputValueTo('[email protected]');
expect(scope.email).toBe('[email protected]');
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);

var widget = scope.form.alias;
changeInputValueTo('[email protected]');
changeInputValueTo('invalid@');
expect(scope.email).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.email).toBeTruthy();
});
it('when used with ngList (default separator)', function() {
compileInput('<input ng-list type="email" ng-model="email" name="alias" />');
var widget = scope.form.alias;

expect(scope.email).toBe('[email protected]');
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);
changeInputValueTo('[email protected]');
expect(scope.email).toEqual(['[email protected]']);
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);

changeInputValueTo('invalid@');
expect(scope.email).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.email).toBeTruthy();
});
changeInputValueTo('[email protected], [email protected]');
expect(scope.email).toEqual(['[email protected]', '[email protected]']);
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);

changeInputValueTo('invalid@');
expect(scope.email).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.email).toBeTruthy();
});
it('when used with ngList (custom separator)', function() {
compileInput('<input ng-list=";" type="email" ng-model="email" name="alias" />');

var widget = scope.form.alias;
changeInputValueTo('[email protected]');
expect(scope.email).toEqual(['[email protected]']);
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);

changeInputValueTo('[email protected];[email protected]');
expect(scope.email).toEqual(['[email protected]', '[email protected]']);
expect(inputElm).toBeValid();
expect(widget.$error.email).toBe(false);

changeInputValueTo('[email protected], [email protected]');
expect(scope.email).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.email).toBeTruthy();


changeInputValueTo('invalid@');
expect(scope.email).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.email).toBeTruthy();
});
});

describe('EMAIL_REGEXP', function() {

describe('EMAIL_REGEXP', function(){
it('should validate email', function() {
expect(EMAIL_REGEXP.test('[email protected]')).toBe(true);
expect(EMAIL_REGEXP.test('[email protected]')).toBe(true);
expect(EMAIL_REGEXP.test('[email protected]')).toBe(false);
});
});

});


describe('url', function() {
describe('should validate url', function(){
it('when used simply', function() {
compileInput('<input type="url" ng-model="url" name="alias" />');
var widget = scope.form.alias;

it('should validate url', function() {
compileInput('<input type="url" ng-model="url" name="alias" />');
var widget = scope.form.alias;
changeInputValueTo('http://www.something.com');
expect(scope.url).toBe('http://www.something.com');
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);

changeInputValueTo('http://www.something.com');
expect(scope.url).toBe('http://www.something.com');
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);
changeInputValueTo('invalid.com');
expect(scope.url).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.url).toBeTruthy();
});
it('when used with ngList (default separator)', function() {
compileInput('<input ng-list type="url" ng-model="url" name="alias" />');

changeInputValueTo('invalid.com');
expect(scope.url).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.url).toBeTruthy();
var widget = scope.form.alias;
changeInputValueTo('http://www.something.com');
expect(scope.url).toEqual(['http://www.something.com']);
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);

changeInputValueTo('http://www.something.com, http://www.somethingelse.com');
expect(scope.url).toEqual(['http://www.something.com', 'http://www.somethingelse.com']);
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);

changeInputValueTo('http:');
expect(scope.url).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.url).toBeTruthy();
});
it('when used with ngList (custom separator)', function() {
compileInput('<input ng-list=";" type="url" ng-model="url" name="alias" />');

var widget = scope.form.alias;
changeInputValueTo('http://www.something.com');
expect(scope.url).toEqual(['http://www.something.com']);
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);

changeInputValueTo('http://www.something.com;http://www.somethingelse.com');
expect(scope.url).toEqual(['http://www.something.com', 'http://www.somethingelse.com']);
expect(inputElm).toBeValid();
expect(widget.$error.url).toBe(false);

changeInputValueTo('http://www.something.com, http://www.somethingelse.com');
expect(scope.url).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.url).toBeTruthy();

changeInputValueTo('http:');
expect(scope.url).toBeUndefined();
expect(inputElm).toBeInvalid();
expect(widget.$error.url).toBeTruthy();
});
});


Expand Down