Skip to content
This repository was archived by the owner on Jul 1, 2020. It is now read-only.

Commit da5e972

Browse files
committed
Added custom validation #75
- Added validation through custom user defined function
1 parent 54cc7e1 commit da5e972

13 files changed

+467
-26
lines changed

app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ myApp.controller('CtrlValidationDirective', ['$q', '$scope', 'validationService'
8383
// -- Controller to use Angular-Validation Directive with 2 forms
8484
// on this page we will pre-validate the form and show all errors on page load
8585
// ---------------------------------------------------------------
86-
myApp.controller('Ctrl2forms', ['$scope', 'validationService', function ($scope, validationService) {
86+
myApp.controller('Ctrl2forms', ['validationService', function (validationService) {
8787
var vm = this; // use the ControllerAs alias syntax
8888

8989
// set the global options BEFORE any function declarations, we will prevalidate current form

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-validation-ghiscoding",
3-
"version": "1.4.10",
3+
"version": "1.4.11",
44
"author": "Ghislain B.",
55
"description": "Angular-Validation Directive and Service (ghiscoding)",
66
"main": [

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
Angular-Validation change logs
22

3+
1.4.11 (2015-10-29) Enhancement #75 - Added custom rules validation through custom functions. Fixed issue #76 - problem with ui-mask in directive.
34
1.4.10 (2015-10-12) Sanitized error messages. Fixed issue #69 - Stop when invalid characters typed on input[number].
45
1.4.9 (2015-10-05) Enhancement #57, #66, #67 - Added 3rd party addon validation (like ngTagsInput, Angular Multiselect, Dropdown multi-select, etc...)
56
1.4.8 (2015-09-12) Fixed issue #68 - Matching validation issue (password confirmation).

dist/angular-validation.min.js

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

more-examples/customJavascript/app.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
var myApp = angular.module('myApp', ['ghiscoding.validation', 'pascalprecht.translate', 'ui.bootstrap']);
4+
// --
5+
// configuration
6+
myApp.config(['$compileProvider', function ($compileProvider) {
7+
$compileProvider.debugInfoEnabled(false);
8+
}])
9+
.config(['$translateProvider', function ($translateProvider) {
10+
$translateProvider.useStaticFilesLoader({
11+
prefix: '../../locales/validation/',
12+
suffix: '.json'
13+
});
14+
// load English ('en') table on startup
15+
$translateProvider.preferredLanguage('en').fallbackLanguage('en');
16+
$translateProvider.useSanitizeValueStrategy('escapeParameters');
17+
}]);
18+
19+
// --
20+
// Directive
21+
myApp.controller('CtrlDirective', ['validationService', function (validationService) {
22+
var vmd = this;
23+
vmd.model = {};
24+
25+
// use the validationService only to declare the controllerAs syntax
26+
var vs = new validationService({ controllerAs: vmd });
27+
28+
vmd.myCustomValidation1 = function() {
29+
// you can return a boolean for isValid or an objec (see the next function)
30+
var isValid = (vmd.model.input1 === "abc");
31+
return isValid;
32+
}
33+
34+
vmd.myCustomValidation2 = function() {
35+
// or you can return an object as { isValid: bool, message: msg }
36+
var isValid = (vmd.model.input2 === "def");
37+
return { isValid: isValid, message: 'Returned error from custom function.'};
38+
}
39+
40+
vmd.submitForm = function() {
41+
if(vs.checkFormValidity(vmd.form1)) {
42+
alert('All good, proceed with submit...');
43+
}
44+
}
45+
}]);
46+
47+
// --
48+
// Service
49+
myApp.controller('CtrlService', ['$scope', 'validationService', function ($scope, validationService) {
50+
var vms = this;
51+
vms.model = {};
52+
//vms.model.input3 = 'a';
53+
// use the validationService only to declare the controllerAs syntax
54+
var vs = new validationService({ controllerAs: vms });
55+
56+
vs.setGlobalOptions({ scope: $scope })
57+
.addValidator('input3', 'alpha|min_len:2|custom:vms.myCustomValidation3:alt=Alternate error message.|required')
58+
.addValidator('input4', 'alpha|min_len:2|custom:vms.myCustomValidation4|required');
59+
60+
vms.myCustomValidation3 = function() {
61+
// you can return a boolean for isValid or an objec (see the next function)
62+
var isValid = (vms.model.input3 === "abc");
63+
return isValid;
64+
}
65+
66+
vms.myCustomValidation4 = function() {
67+
// or you can return an object as { isValid: bool, message: msg }
68+
var isValid = (vms.model.input4 === "def");
69+
console.log(isValid);
70+
return { isValid: isValid, message: 'Returned error from custom function.'};
71+
}
72+
73+
vms.submitForm = function() {
74+
if(new validationService().checkFormValidity(vms.form2)) {
75+
alert('All good, proceed with submit...');
76+
}
77+
}
78+
}]);
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<!DOCTYPE html>
2+
<html ng-app="myApp" ng-strict-di ng-cloak="">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Angular-Validation with Custom Javascript function</title>
6+
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
7+
<link rel="stylesheet" href="../../style.css">
8+
</head>
9+
10+
<body>
11+
<div class="container">
12+
<div ng-controller="CtrlDirective as vmd">
13+
<h2>Example of Angular-Validation with Custom Javascript function</h2>
14+
15+
<h3>Directive</h3>
16+
<div class="alert alert-danger alert-dismissable" ng-show="vmd.form1.$validationSummary.length &gt; 0">
17+
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
18+
<h4><strong>ERRORS!</strong></h4>
19+
<ul>
20+
<li ng-repeat="item in vmd.form1.$validationSummary">{{ item.field }}: {{item.message}}</li>
21+
</ul>
22+
</div>
23+
24+
<form name="vmd.form1">
25+
<div class="form-group">
26+
<p>Type '<b>abc</b>' for a valid answer </p>
27+
<label for="input1">Custom javascript Validation (error msg using alt:)</label>
28+
<!-- defining the custom javascript function call by using `custom:` or `javascript:` -->
29+
<input type="text" class="form-control"
30+
name="input1"
31+
ng-model="vmd.model.input1"
32+
placeholder="alpha|min_len:2|custom:vmd.myCustomValidation1|required"
33+
validation="alpha|min_len:2|custom:vmd.myCustomValidation1:alt=Alternate error message.|required" />
34+
</div>
35+
<br/>
36+
<div class="form-group">
37+
<p>Type '<b>def</b>' for a valid answer </p>
38+
<label for="input2">Custom javascript Validation (error msg declared in custom function)</label>
39+
<!-- same as previous but defined as `javascript` and error message is declared directly in the custom function -->
40+
<input type="text" class="form-control"
41+
name="input2"
42+
ng-model="vmd.model.input2"
43+
placeholder="alpha|min_len:2|custom:vmd.myCustomValidation2|required"
44+
validation="alpha|min_len:2|custom:vmd.myCustomValidation2|required" />
45+
</div>
46+
<div class="form-actions">
47+
<button type="submit" name="btn_ngDisabled1" class="btn btn-primary" ng-disabled="vmd.form1.$invalid" >{{ 'SAVE' | translate }} (ngDisabled)</button>
48+
<button type="submit" name="btn_ngSubmit1" class="btn btn-primary" ng-click="vmd.submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button>
49+
</div>
50+
</form>
51+
</div>
52+
53+
<hr/>
54+
55+
<div ng-controller="CtrlService as vms">
56+
<h3>Service</h3>
57+
<div class="alert alert-danger alert-dismissable" ng-show="vms.form2.$validationSummary.length &gt; 0">
58+
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
59+
<h4><strong>ERRORS!</strong></h4>
60+
<ul>
61+
<li ng-repeat="item in vms.form2.$validationSummary">{{ item.field }}: {{item.message}}</li>
62+
</ul>
63+
</div>
64+
65+
<form name="vms.form2">
66+
<div class="form-group">
67+
<p>Type '<b>abc</b>' for a valid answer </p>
68+
<label for="input3">Custom javascript Validation (error msg using alt:)</label>
69+
<!-- defining the custom javascript function call by using `custom:` or `javascript:` -->
70+
<input type="text" class="form-control"
71+
name="input3"
72+
ng-model="vms.model.input3"
73+
placeholder="alpha|min_len:2|custom:vms.myCustomValidation3|required" />
74+
</div>
75+
<br/>
76+
<div class="form-group">
77+
<p>Type '<b>def</b>' for a valid answer </p>
78+
<label for="input4">Custom javascript Validation (error msg declared in custom function)</label>
79+
<!-- same as previous but defined as `javascript` and error message is declared directly in the custom function -->
80+
<input type="text" class="form-control"
81+
name="input4"
82+
ng-model="vms.model.input4"
83+
placeholder="alpha|min_len:2|custom:vms.myCustomValidation4|required" />
84+
</div>
85+
<div class="form-actions">
86+
<button type="submit" name="btn_ngDisabled2" class="btn btn-primary" ng-disabled="vms.form2.$invalid" >{{ 'SAVE' | translate }} (ngDisabled)</button>
87+
<button type="submit" name="btn_ngSubmit2" class="btn btn-primary" ng-click="vms.submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button>
88+
</div>
89+
</form>
90+
</div>
91+
</div>
92+
93+
<!-- external librairies CDN -->
94+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
95+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.js"></script>
96+
97+
<!-- angular-translate -->
98+
<!-- Visit Angular-Translate https://github.com/PascalPrecht/angular-translate -->
99+
<script src="../../vendors/angular-translate/angular-translate.min.js"></script>
100+
<script src="../../vendors/angular-translate/angular-translate-loader-static-files.min.js"></script>
101+
102+
<!-- Angular-UI -->
103+
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.2.js"></script>
104+
105+
<!-- Angular-Validation -->
106+
<script type="text/javascript" src="../../dist/angular-validation.min.js"></script>
107+
<!--
108+
<script type="text/javascript" src="../../src/validation-directive.js"></script>
109+
<script type="text/javascript" src="../../src/validation-service.js"></script>
110+
<script type="text/javascript" src="../../src/validation-common.js"></script>
111+
<script type="text/javascript" src="../../src/validation-rules.js"></script>
112+
-->
113+
114+
<!-- my application -->
115+
<script type="text/javascript" src="app.js"></script>
116+
</body>
117+
</html>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-validation-ghiscoding",
3-
"version": "1.4.10",
3+
"version": "1.4.11",
44
"author": "Ghislain B.",
55
"description": "Angular-Validation Directive and Service (ghiscoding)",
66
"main": "app.js",

protractor/conf.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
// Spec patterns are relative to the current working directory when protractor is called
2323
specs: [
2424
'badInput_spec.js',
25+
'custom_spec.js',
2526
'mixed_validation_spec.js',
2627
'angularUI_spec.js',
2728
'dynamic_spec.js',
@@ -33,9 +34,9 @@
3334
],
3435
jasmineNodeOpts: {
3536
showColors: true,
36-
defaultTimeoutInterval: 800000
37+
defaultTimeoutInterval: 850000
3738
},
38-
allScriptsTimeout: 800000,
39+
allScriptsTimeout: 850000,
3940
seleniumAddress: 'http://localhost:4444/wd/hub',
4041

4142
// format the output when tests are run with Team City

protractor/custom_spec.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
describe('Angular-Validation Custom Javascript Validation Tests:', function () {
2+
// global variables
3+
var formElementNames = ['input1', 'input2', 'input3', 'input4'];
4+
var errorMessages = [
5+
'May only contain letters. Must be at least 2 characters. Field is required.',
6+
'May only contain letters. Must be at least 2 characters. Field is required.',
7+
'May only contain letters. Must be at least 2 characters. Field is required.',
8+
'May only contain letters. Must be at least 2 characters. Field is required.'
9+
];
10+
var errorTooShort = [
11+
'Must be at least 2 characters. Alternate error message.',
12+
'Must be at least 2 characters. Returned error from custom function.',
13+
'Must be at least 2 characters. Alternate error message.',
14+
'Must be at least 2 characters. Returned error from custom function.'
15+
];
16+
var oneChar = ['a', 'd', 'a', 'd'];
17+
var validInputTexts = ['abc', 'def', 'abc', 'def'];
18+
19+
describe('When choosing `more-examples` custom javascript', function () {
20+
it('Should navigate to home page', function () {
21+
browser.get('http://localhost/Github/angular-validation/more-examples/customJavascript/');
22+
23+
// Find the title element
24+
var titleElement = element(by.css('h2'));
25+
expect(titleElement.getText()).toEqual('Example of Angular-Validation with Custom Javascript function');
26+
});
27+
28+
it('Should have multiple errors in Directive & Service validation summary', function () {
29+
var itemRows = element.all(by.binding('message'));
30+
var inputName;
31+
32+
for (var i = 0, j = 0, ln = itemRows.length; i < ln; i++) {
33+
expect(itemRows.get(i).getText()).toEqual(defaultErrorMessages[i]);
34+
}
35+
});
36+
37+
it('Should check that both submit buttons are disabled', function() {
38+
var elmSubmit1 = $('[name=btn_ngDisabled1]');
39+
expect(elmSubmit1.isEnabled()).toBe(false);
40+
41+
var elmSubmit2 = $('[name=btn_ngDisabled2]');
42+
expect(elmSubmit2.isEnabled()).toBe(false);
43+
});
44+
45+
it('Should click, blur on each form elements and error message should display on each of them', function () {
46+
for (var i = 0, ln = formElementNames.length; i < ln; i++) {
47+
var elmInput = $('[name=' + formElementNames[i] + ']');
48+
elmInput.click();
49+
elmInput.sendKeys(protractor.Key.TAB);
50+
51+
var elmError = $('.validation-' + formElementNames[i]);
52+
expect(elmError.getText()).toEqual(errorMessages[i]);
53+
}
54+
});
55+
56+
it('Should enter 1 character in all inputs and display minChar error message', function() {
57+
for (var i = 0, ln = formElementNames.length; i < ln; i++) {
58+
var elmInput = $('[name=' + formElementNames[i] + ']');
59+
elmInput.click();
60+
elmInput.sendKeys('a');
61+
62+
var elmError = $('.validation-' + formElementNames[i]);
63+
expect(elmError.getText()).toEqual(errorTooShort[i]);
64+
}
65+
});
66+
67+
it('Should enter valid text and make error go away', function () {
68+
for (var i = 0, ln = formElementNames.length; i < ln; i++) {
69+
var elmInput = $('[name=' + formElementNames[i] + ']');
70+
elmInput.click();
71+
clearInput(elmInput);
72+
elmInput.sendKeys(validInputTexts[i]);
73+
elmInput.sendKeys(protractor.Key.TAB);
74+
75+
var elmError = $('.validation-' + formElementNames[i]);
76+
expect(elmError.getText()).toEqual('');
77+
}
78+
});
79+
80+
it('Should have both validation summary empty', function() {
81+
var itemRows = element.all(by.binding('message'));
82+
expect(itemRows.count()).toBe(0);
83+
});
84+
85+
it('Should check that both submit buttons are now enabled', function() {
86+
var elmSubmit1 = $('[name=btn_ngDisabled1]');
87+
expect(elmSubmit1.isEnabled()).toBe(true);
88+
89+
var elmSubmit2 = $('[name=btn_ngDisabled2]');
90+
expect(elmSubmit2.isEnabled()).toBe(true);
91+
});
92+
93+
it('Should navigate to home page', function () {
94+
browser.get('http://localhost/Github/angular-validation/more-examples/customJavascript/');
95+
96+
// Find the title element
97+
var titleElement = element(by.css('h2'));
98+
expect(titleElement.getText()).toEqual('Example of Angular-Validation with Custom Javascript function');
99+
});
100+
101+
it('Should click on both ngSubmit buttons', function() {
102+
var btnNgSubmit1 = $('[name=btn_ngSubmit1]');
103+
btnNgSubmit1.click();
104+
105+
var btnNgSubmit2 = $('[name=btn_ngSubmit2]');
106+
btnNgSubmit2.click();
107+
});
108+
109+
it('Should show error message on each inputs', function () {
110+
for (var i = 0, ln = formElementNames.length; i < ln; i++) {
111+
var elmInput = $('[name=' + formElementNames[i] + ']');
112+
elmInput.click();
113+
elmInput.sendKeys(protractor.Key.TAB);
114+
115+
var elmError = $('.validation-' + formElementNames[i]);
116+
expect(elmError.getText()).toEqual(errorMessages[i]);
117+
}
118+
});
119+
120+
});
121+
});
122+
123+
/** From a given input name, clear the input
124+
* @param string input name
125+
*/
126+
function clearInput(elem) {
127+
elem.getAttribute('value').then(function (text) {
128+
var len = text.length
129+
var backspaceSeries = Array(len+1).join(protractor.Key.BACK_SPACE);
130+
elem.sendKeys(backspaceSeries);
131+
})
132+
}

readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#Angular Validation (Directive / Service)
2-
`Version: 1.4.10`
2+
`Version: 1.4.11`
33
### Form validation after user inactivity of default 1sec. (customizable timeout)
44

55
Forms Validation with Angular made easy! Angular-Validation is an angular directive/service with locales (languages) with a very simple approach of defining your `validation=""` directly within your element to validate (input, textarea, etc) and...that's it!!! The directive/service will take care of the rest!
@@ -80,6 +80,7 @@ All the documentation has been moved to the Wiki section, see the [github wiki](
8080
* [DisplayErrorTo](https://github.com/ghiscoding/angular-validation/wiki/Bootstrap-Input-Groups-Wrapping)
8181
* [Isolated Scope](https://github.com/ghiscoding/angular-validation/wiki/Isolated-Scope)
8282
* [PreValidate Form (on page load)](https://github.com/ghiscoding/angular-validation/wiki/PreValidate-Form-(on-page-load))
83+
* [Custom Validation function](https://github.com/ghiscoding/angular-validation/wiki/Custom-Validation-functions)
8384
* [Remote Validation (AJAX)](https://github.com/ghiscoding/angular-validation/wiki/Remote-Validation-(AJAX))
8485
* [Remove a Validator](https://github.com/ghiscoding/angular-validation/wiki/Remove-Validator-from-Element)
8586
* [Reset Form](https://github.com/ghiscoding/angular-validation/wiki/Reset-Form)

0 commit comments

Comments
 (0)