This repository has been archived by the owner on Jul 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added validation through custom user defined function
- Loading branch information
1 parent
54cc7e1
commit da5e972
Showing
13 changed files
with
467 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
'use strict'; | ||
|
||
var myApp = angular.module('myApp', ['ghiscoding.validation', 'pascalprecht.translate', 'ui.bootstrap']); | ||
// -- | ||
// configuration | ||
myApp.config(['$compileProvider', function ($compileProvider) { | ||
$compileProvider.debugInfoEnabled(false); | ||
}]) | ||
.config(['$translateProvider', function ($translateProvider) { | ||
$translateProvider.useStaticFilesLoader({ | ||
prefix: '../../locales/validation/', | ||
suffix: '.json' | ||
}); | ||
// load English ('en') table on startup | ||
$translateProvider.preferredLanguage('en').fallbackLanguage('en'); | ||
$translateProvider.useSanitizeValueStrategy('escapeParameters'); | ||
}]); | ||
|
||
// -- | ||
// Directive | ||
myApp.controller('CtrlDirective', ['validationService', function (validationService) { | ||
var vmd = this; | ||
vmd.model = {}; | ||
|
||
// use the validationService only to declare the controllerAs syntax | ||
var vs = new validationService({ controllerAs: vmd }); | ||
|
||
vmd.myCustomValidation1 = function() { | ||
// you can return a boolean for isValid or an objec (see the next function) | ||
var isValid = (vmd.model.input1 === "abc"); | ||
return isValid; | ||
} | ||
|
||
vmd.myCustomValidation2 = function() { | ||
// or you can return an object as { isValid: bool, message: msg } | ||
var isValid = (vmd.model.input2 === "def"); | ||
return { isValid: isValid, message: 'Returned error from custom function.'}; | ||
} | ||
|
||
vmd.submitForm = function() { | ||
if(vs.checkFormValidity(vmd.form1)) { | ||
alert('All good, proceed with submit...'); | ||
} | ||
} | ||
}]); | ||
|
||
// -- | ||
// Service | ||
myApp.controller('CtrlService', ['$scope', 'validationService', function ($scope, validationService) { | ||
var vms = this; | ||
vms.model = {}; | ||
//vms.model.input3 = 'a'; | ||
// use the validationService only to declare the controllerAs syntax | ||
var vs = new validationService({ controllerAs: vms }); | ||
|
||
vs.setGlobalOptions({ scope: $scope }) | ||
.addValidator('input3', 'alpha|min_len:2|custom:vms.myCustomValidation3:alt=Alternate error message.|required') | ||
.addValidator('input4', 'alpha|min_len:2|custom:vms.myCustomValidation4|required'); | ||
|
||
vms.myCustomValidation3 = function() { | ||
// you can return a boolean for isValid or an objec (see the next function) | ||
var isValid = (vms.model.input3 === "abc"); | ||
return isValid; | ||
} | ||
|
||
vms.myCustomValidation4 = function() { | ||
// or you can return an object as { isValid: bool, message: msg } | ||
var isValid = (vms.model.input4 === "def"); | ||
console.log(isValid); | ||
return { isValid: isValid, message: 'Returned error from custom function.'}; | ||
} | ||
|
||
vms.submitForm = function() { | ||
if(new validationService().checkFormValidity(vms.form2)) { | ||
alert('All good, proceed with submit...'); | ||
} | ||
} | ||
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<!DOCTYPE html> | ||
<html ng-app="myApp" ng-strict-di ng-cloak=""> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<title>Angular-Validation with Custom Javascript function</title> | ||
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> | ||
<link rel="stylesheet" href="../../style.css"> | ||
</head> | ||
|
||
<body> | ||
<div class="container"> | ||
<div ng-controller="CtrlDirective as vmd"> | ||
<h2>Example of Angular-Validation with Custom Javascript function</h2> | ||
|
||
<h3>Directive</h3> | ||
<div class="alert alert-danger alert-dismissable" ng-show="vmd.form1.$validationSummary.length > 0"> | ||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> | ||
<h4><strong>ERRORS!</strong></h4> | ||
<ul> | ||
<li ng-repeat="item in vmd.form1.$validationSummary">{{ item.field }}: {{item.message}}</li> | ||
</ul> | ||
</div> | ||
|
||
<form name="vmd.form1"> | ||
<div class="form-group"> | ||
<p>Type '<b>abc</b>' for a valid answer </p> | ||
<label for="input1">Custom javascript Validation (error msg using alt:)</label> | ||
<!-- defining the custom javascript function call by using `custom:` or `javascript:` --> | ||
<input type="text" class="form-control" | ||
name="input1" | ||
ng-model="vmd.model.input1" | ||
placeholder="alpha|min_len:2|custom:vmd.myCustomValidation1|required" | ||
validation="alpha|min_len:2|custom:vmd.myCustomValidation1:alt=Alternate error message.|required" /> | ||
</div> | ||
<br/> | ||
<div class="form-group"> | ||
<p>Type '<b>def</b>' for a valid answer </p> | ||
<label for="input2">Custom javascript Validation (error msg declared in custom function)</label> | ||
<!-- same as previous but defined as `javascript` and error message is declared directly in the custom function --> | ||
<input type="text" class="form-control" | ||
name="input2" | ||
ng-model="vmd.model.input2" | ||
placeholder="alpha|min_len:2|custom:vmd.myCustomValidation2|required" | ||
validation="alpha|min_len:2|custom:vmd.myCustomValidation2|required" /> | ||
</div> | ||
<div class="form-actions"> | ||
<button type="submit" name="btn_ngDisabled1" class="btn btn-primary" ng-disabled="vmd.form1.$invalid" >{{ 'SAVE' | translate }} (ngDisabled)</button> | ||
<button type="submit" name="btn_ngSubmit1" class="btn btn-primary" ng-click="vmd.submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button> | ||
</div> | ||
</form> | ||
</div> | ||
|
||
<hr/> | ||
|
||
<div ng-controller="CtrlService as vms"> | ||
<h3>Service</h3> | ||
<div class="alert alert-danger alert-dismissable" ng-show="vms.form2.$validationSummary.length > 0"> | ||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> | ||
<h4><strong>ERRORS!</strong></h4> | ||
<ul> | ||
<li ng-repeat="item in vms.form2.$validationSummary">{{ item.field }}: {{item.message}}</li> | ||
</ul> | ||
</div> | ||
|
||
<form name="vms.form2"> | ||
<div class="form-group"> | ||
<p>Type '<b>abc</b>' for a valid answer </p> | ||
<label for="input3">Custom javascript Validation (error msg using alt:)</label> | ||
<!-- defining the custom javascript function call by using `custom:` or `javascript:` --> | ||
<input type="text" class="form-control" | ||
name="input3" | ||
ng-model="vms.model.input3" | ||
placeholder="alpha|min_len:2|custom:vms.myCustomValidation3|required" /> | ||
</div> | ||
<br/> | ||
<div class="form-group"> | ||
<p>Type '<b>def</b>' for a valid answer </p> | ||
<label for="input4">Custom javascript Validation (error msg declared in custom function)</label> | ||
<!-- same as previous but defined as `javascript` and error message is declared directly in the custom function --> | ||
<input type="text" class="form-control" | ||
name="input4" | ||
ng-model="vms.model.input4" | ||
placeholder="alpha|min_len:2|custom:vms.myCustomValidation4|required" /> | ||
</div> | ||
<div class="form-actions"> | ||
<button type="submit" name="btn_ngDisabled2" class="btn btn-primary" ng-disabled="vms.form2.$invalid" >{{ 'SAVE' | translate }} (ngDisabled)</button> | ||
<button type="submit" name="btn_ngSubmit2" class="btn btn-primary" ng-click="vms.submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
<!-- external librairies CDN --> | ||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script> | ||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular-route.js"></script> | ||
|
||
<!-- angular-translate --> | ||
<!-- Visit Angular-Translate https://github.com/PascalPrecht/angular-translate --> | ||
<script src="../../vendors/angular-translate/angular-translate.min.js"></script> | ||
<script src="../../vendors/angular-translate/angular-translate-loader-static-files.min.js"></script> | ||
|
||
<!-- Angular-UI --> | ||
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.2.js"></script> | ||
|
||
<!-- Angular-Validation --> | ||
<script type="text/javascript" src="../../dist/angular-validation.min.js"></script> | ||
<!-- | ||
<script type="text/javascript" src="../../src/validation-directive.js"></script> | ||
<script type="text/javascript" src="../../src/validation-service.js"></script> | ||
<script type="text/javascript" src="../../src/validation-common.js"></script> | ||
<script type="text/javascript" src="../../src/validation-rules.js"></script> | ||
--> | ||
|
||
<!-- my application --> | ||
<script type="text/javascript" src="app.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
describe('Angular-Validation Custom Javascript Validation Tests:', function () { | ||
// global variables | ||
var formElementNames = ['input1', 'input2', 'input3', 'input4']; | ||
var errorMessages = [ | ||
'May only contain letters. Must be at least 2 characters. Field is required.', | ||
'May only contain letters. Must be at least 2 characters. Field is required.', | ||
'May only contain letters. Must be at least 2 characters. Field is required.', | ||
'May only contain letters. Must be at least 2 characters. Field is required.' | ||
]; | ||
var errorTooShort = [ | ||
'Must be at least 2 characters. Alternate error message.', | ||
'Must be at least 2 characters. Returned error from custom function.', | ||
'Must be at least 2 characters. Alternate error message.', | ||
'Must be at least 2 characters. Returned error from custom function.' | ||
]; | ||
var oneChar = ['a', 'd', 'a', 'd']; | ||
var validInputTexts = ['abc', 'def', 'abc', 'def']; | ||
|
||
describe('When choosing `more-examples` custom javascript', function () { | ||
it('Should navigate to home page', function () { | ||
browser.get('http://localhost/Github/angular-validation/more-examples/customJavascript/'); | ||
|
||
// Find the title element | ||
var titleElement = element(by.css('h2')); | ||
expect(titleElement.getText()).toEqual('Example of Angular-Validation with Custom Javascript function'); | ||
}); | ||
|
||
it('Should have multiple errors in Directive & Service validation summary', function () { | ||
var itemRows = element.all(by.binding('message')); | ||
var inputName; | ||
|
||
for (var i = 0, j = 0, ln = itemRows.length; i < ln; i++) { | ||
expect(itemRows.get(i).getText()).toEqual(defaultErrorMessages[i]); | ||
} | ||
}); | ||
|
||
it('Should check that both submit buttons are disabled', function() { | ||
var elmSubmit1 = $('[name=btn_ngDisabled1]'); | ||
expect(elmSubmit1.isEnabled()).toBe(false); | ||
|
||
var elmSubmit2 = $('[name=btn_ngDisabled2]'); | ||
expect(elmSubmit2.isEnabled()).toBe(false); | ||
}); | ||
|
||
it('Should click, blur on each form elements and error message should display on each of them', function () { | ||
for (var i = 0, ln = formElementNames.length; i < ln; i++) { | ||
var elmInput = $('[name=' + formElementNames[i] + ']'); | ||
elmInput.click(); | ||
elmInput.sendKeys(protractor.Key.TAB); | ||
|
||
var elmError = $('.validation-' + formElementNames[i]); | ||
expect(elmError.getText()).toEqual(errorMessages[i]); | ||
} | ||
}); | ||
|
||
it('Should enter 1 character in all inputs and display minChar error message', function() { | ||
for (var i = 0, ln = formElementNames.length; i < ln; i++) { | ||
var elmInput = $('[name=' + formElementNames[i] + ']'); | ||
elmInput.click(); | ||
elmInput.sendKeys('a'); | ||
|
||
var elmError = $('.validation-' + formElementNames[i]); | ||
expect(elmError.getText()).toEqual(errorTooShort[i]); | ||
} | ||
}); | ||
|
||
it('Should enter valid text and make error go away', function () { | ||
for (var i = 0, ln = formElementNames.length; i < ln; i++) { | ||
var elmInput = $('[name=' + formElementNames[i] + ']'); | ||
elmInput.click(); | ||
clearInput(elmInput); | ||
elmInput.sendKeys(validInputTexts[i]); | ||
elmInput.sendKeys(protractor.Key.TAB); | ||
|
||
var elmError = $('.validation-' + formElementNames[i]); | ||
expect(elmError.getText()).toEqual(''); | ||
} | ||
}); | ||
|
||
it('Should have both validation summary empty', function() { | ||
var itemRows = element.all(by.binding('message')); | ||
expect(itemRows.count()).toBe(0); | ||
}); | ||
|
||
it('Should check that both submit buttons are now enabled', function() { | ||
var elmSubmit1 = $('[name=btn_ngDisabled1]'); | ||
expect(elmSubmit1.isEnabled()).toBe(true); | ||
|
||
var elmSubmit2 = $('[name=btn_ngDisabled2]'); | ||
expect(elmSubmit2.isEnabled()).toBe(true); | ||
}); | ||
|
||
it('Should navigate to home page', function () { | ||
browser.get('http://localhost/Github/angular-validation/more-examples/customJavascript/'); | ||
|
||
// Find the title element | ||
var titleElement = element(by.css('h2')); | ||
expect(titleElement.getText()).toEqual('Example of Angular-Validation with Custom Javascript function'); | ||
}); | ||
|
||
it('Should click on both ngSubmit buttons', function() { | ||
var btnNgSubmit1 = $('[name=btn_ngSubmit1]'); | ||
btnNgSubmit1.click(); | ||
|
||
var btnNgSubmit2 = $('[name=btn_ngSubmit2]'); | ||
btnNgSubmit2.click(); | ||
}); | ||
|
||
it('Should show error message on each inputs', function () { | ||
for (var i = 0, ln = formElementNames.length; i < ln; i++) { | ||
var elmInput = $('[name=' + formElementNames[i] + ']'); | ||
elmInput.click(); | ||
elmInput.sendKeys(protractor.Key.TAB); | ||
|
||
var elmError = $('.validation-' + formElementNames[i]); | ||
expect(elmError.getText()).toEqual(errorMessages[i]); | ||
} | ||
}); | ||
|
||
}); | ||
}); | ||
|
||
/** From a given input name, clear the input | ||
* @param string input name | ||
*/ | ||
function clearInput(elem) { | ||
elem.getAttribute('value').then(function (text) { | ||
var len = text.length | ||
var backspaceSeries = Array(len+1).join(protractor.Key.BACK_SPACE); | ||
elem.sendKeys(backspaceSeries); | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.