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

Commit c15535c

Browse files
committed
RemoveValidator in Directive, fixed ngDisabled in Service
- Added RemoveValidator( ) for Directive as well - Added Protractor tests on RemoveValidator( ) for both the Directive and Service - Fixed ngDisabled not working correctly in Service - Added Protractor tests for ngDisabled On/Off in both Directive and Service
1 parent 84976fc commit c15535c

17 files changed

+363
-87
lines changed

app.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,22 @@ myApp.controller('Ctrl', ['$location', '$route', '$scope', '$translate', functio
4040
myApp.controller('CtrlValidationDirective', ['$q', '$scope', 'validationService', function ($q, $scope, validationService) {
4141
$scope.$validationOptions = { debounce: 1500, preValidateFormElements: false }; // you can change default debounce globally
4242

43+
// remove a single element ($scope.form1, string)
44+
// OR you can also remove multiple elements through an array type .removeValidator($scope.form1, ['input2','input3'])
45+
$scope.removeInputValidator = function ( elmName ) {
46+
new validationService().removeValidator($scope.form1, elmName);
47+
};
48+
4349
$scope.submitForm = function() {
4450
if(new validationService().checkFormValidity($scope.form1)) {
4551
alert('All good, proceed with submit...');
4652
}
4753
}
54+
4855
$scope.showValidationSummary = function () {
4956
$scope.displayValidationSummary = true;
5057
}
58+
5159
$scope.customRemoteValidationCall = function() {
5260
var deferred = $q.defer();
5361
setTimeout(function() {
@@ -126,7 +134,8 @@ myApp.controller('CtrlValidationService', ['$q', '$scope', '$translate', 'valida
126134
.addValidator({elmName: 'input17', rules: 'alpha_spaces|exact_len:3|required', debounce: 3000})
127135
.addValidator('input18', 'date_iso_min:2001-01-01|required')
128136
.addValidator('input19', 'date_us_short_between:11/28/99,12/31/15|required')
129-
.addValidator('area1', 'alpha_dash_spaces|min_len:15|required');
137+
.addValidator('area1', 'alpha_dash_spaces|min_len:15|required')
138+
.addValidator('input20', 'alpha_dash|min_len:2|required');
130139

131140
// remove a single element ($scope.form1, string)
132141
// OR you can also remove multiple elements through an array type .removeValidator($scope.form1, ['input2','input3'])

bower.json

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

changelog.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ Angular-Validation change logs
2929
1.3.25 (2015-05-19) Enhancement #34 to add Remote Validation and updated Protractor to cover this new feature.
3030
1.3.26 (2015-05-30) Added enhancement #35 - PreValidate the Form, display all errors on page load.
3131
1.3.27 (2015-06-02) Added possibility to use own isolated scope (issue #37 and #26). Fixed an implementation issue found from last revision (issue #35). Fixed email validation (issue #38). Fixed a performance issue found with onBlur which would run as much validations as there was characters inside the input when onBlur was called (abcdef => would make 6 validations) and this was extremely costly with a Remote validation call. Update the code of Remote validation to also accept the "As" alias "remote:vm.customRemoteValidation". Finally added and updated a few Protractor tests to cover all of the above and more.
32-
1.3.28 (2015-06-04) Fixed a bug with ngDisabled not being interpreted before observing it (ng-disabled="vm.type == 1" would give false result because it was not being interpreted), added Protractor Test for this behavior in 2Forms page. Added `displayOnlyLastErrorMsg` in the list of Global Options. Cleaned up a lot of code.
32+
1.3.28 (2015-06-04) Fixed a bug with ngDisabled not being interpreted before observing it (ng-disabled="vm.type == 1" would give false result because it was not being interpreted), added Protractor Test for this behavior in 2Forms page. Added `displayOnlyLastErrorMsg` in the list of Global Options. Cleaned up a lot of code.
33+
1.3.29 (2015-06-10) Added RemoveValidator() for Directive, added Protractor tests on RemoveValidator() for both the Directive and Service. Fixed ngDisabled not working correctly in Service, added Protractor tests for ngDisabled On/Off in both Directive and Service

dist/angular-validation.min.js

+5-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

full-tests/Directive.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ <h4><strong>{{ 'ERRORS' | translate }}!</strong></h4>
2424
</div>
2525

2626
<div class="form-actions">
27-
<button type="submit" name="save_btn" class="btn btn-primary" ng-disabled="form01.$invalid">{{ 'SAVE' | translate }} (ngDisabled)</button>
27+
<button type="submit" name="btn_ngDisabled" class="btn btn-primary" ng-disabled="form01.$invalid">{{ 'SAVE' | translate }} (ngDisabled)</button>
2828
<button type="submit" name="save_btn" class="btn btn-primary" ng-click="submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button>
2929
</div>
3030
</form>

full-tests/Service.html

+5
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,9 @@ <h4><strong>{{ 'ERRORS' | translate }}!</strong></h4>
488488
<input class="form-control" type="text" name="input116" ng-model="input116">
489489
</div>
490490
</fieldset>
491+
492+
<div class="form-actions">
493+
<button type="submit" name="btn_ngDisabled" class="btn btn-primary" ng-disabled="form01.$invalid">{{ 'SAVE' | translate }} (ngDisabled)</button>
494+
<button type="submit" name="save_btn" class="btn btn-primary" ng-click="submitForm()">{{ 'SAVE' | translate }} (ngSubmit)</button>
495+
</div>
491496
</form>

package.json

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

protractor/full_tests_spec.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
(function(elmInput, data, i) {
7676
elmInput.clear().then(function() {
7777
elmInput.sendKeys(data);
78-
//elmInput.sendKeys(protractor.Key.TAB);
78+
elmInput.sendKeys(protractor.Key.TAB);
7979
var elmError = $('.validation-input' + i);
8080
expect(elmError.getText()).toEqual('');
8181
});
@@ -84,6 +84,11 @@
8484
}
8585
}, 420000);
8686

87+
it('Should check that ngDisabled button is now enabled', function() {
88+
var elmSubmit1 = $('[name=btn_ngDisabled]');
89+
expect(elmSubmit1.isEnabled()).toBe(true);
90+
});
91+
8792
it('Should enter invalid text and make error appear', function () {
8893
for (var i = 0, ln = validations.length; i < ln; i++) {
8994
var elmInput = $('[name=input' + i + ']');
@@ -96,7 +101,7 @@
96101
(function(elmInput, data, i) {
97102
elmInput.clear().then(function() {
98103
elmInput.sendKeys(data);
99-
//elmInput.sendKeys(protractor.Key.TAB);
104+
elmInput.sendKeys(protractor.Key.TAB);
100105
var elmError = $('.validation-input' + i);
101106
expect(elmError.getText()).toEqual(validations[i].error_message[languages[0]]);
102107
});

protractor/mixed_validation_spec.js

+145-5
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,15 @@
8080
'Change language',
8181
'May only contain letters, numbers, dashes and spaces. Must be at least 15 characters. Field is required.'
8282
];
83-
var errorMessages2FormsExtra = 'Field is required.';
83+
var errorMessages2FormsExtra = 'May only contain letters, numbers and dashes. Must be at least 2 characters. Field is required.';
8484
var validInput2FormsTexts = [
8585
'John',
8686
'Doe',
8787
'abc',
8888
'en',
8989
'This is a great tool'
9090
];
91+
var input3error = 'May only contain a positive or negative float value (integer excluded). Needs to be a numeric value, between -0.6 and 99.5. Field is required.';
9192

9293
for(var k = 0, kln = types.length; k < kln; k++) {
9394
// because we are dealing with promises, we better use closures to pass certain variables
@@ -173,7 +174,6 @@
173174
element(by.cssContainingText('option', 'en')).click(); // click on good option first
174175
element(by.cssContainingText('option', '...')).click(); // then click on option[0], the one containing '...'
175176
elmInput.sendKeys(protractor.Key.TAB);
176-
//browser.sleep(5000); // sleep 5 seconds
177177

178178
var elmError = $('.validation-select1');
179179
expect(elmError.getText()).toEqual(errorMessages[i]);
@@ -194,6 +194,7 @@
194194
var elmInput = $('[name=' + formElementNames[i] + ']');
195195
elmInput.click();
196196
elmInput.sendKeys(validInputTexts[i]);
197+
elmInput.sendKeys(protractor.Key.TAB);
197198

198199
if (formElementNames[i] === 'select1') {
199200
element(by.cssContainingText('option', validInputTexts[i])).click(); // click on good option
@@ -205,6 +206,135 @@
205206
}
206207
});
207208

209+
it('Should check that ngDisabled button is now enabled', function() {
210+
var elmSubmit1 = $('[name=btn_ngDisabled]');
211+
expect(elmSubmit1.isEnabled()).toBe(true);
212+
});
213+
214+
it('Should make input3 error appear', function() {
215+
// scroll back to top
216+
browser.executeScript('window.scrollTo(0,0);').then(function () {
217+
// make input3 invalid, remove text
218+
var elmInput3 = $('[name=input3]');
219+
clearInput(elmInput3);
220+
elmInput3.sendKeys(protractor.Key.TAB);
221+
222+
// error should appear on input3
223+
var elmError2 = $('.validation-input3');
224+
expect(elmError2.getText()).toEqual(input3error);
225+
});
226+
});
227+
228+
it('Should show input3 error in ValidationSummary', function () {
229+
var btnShowSummary = $('button[name=btn_showValidation]');
230+
btnShowSummary.click();
231+
browser.waitForAngular();
232+
233+
// showValidation checkbox should false at first but true after
234+
var elmCheckboxShowSummary = element(by.model('displayValidationSummary'));
235+
expect(elmCheckboxShowSummary.isSelected()).toBeTruthy();
236+
237+
// scroll back to top
238+
browser.executeScript('window.scrollTo(0,0);').then(function () {
239+
var itemRows = element.all(by.binding('message'));
240+
var inputName;
241+
242+
for (var i = 0, j = 0, ln = itemRows.length; i < ln; i++) {
243+
expect(itemRows.get(i).getText()).toEqual('input3: ' + input3error);
244+
}
245+
});
246+
});
247+
248+
it('Should click on "Remove input3 validator" and error should go away from input & ValidationSummary', function() {
249+
// scroll back to top
250+
browser.executeScript('window.scrollTo(0,0);').then(function () {
251+
var btnRemoveValidator2 = $('button[name=btn_RemoveValidator2]');
252+
btnRemoveValidator2.click();
253+
browser.waitForAngular();
254+
255+
// error should be removed from input3
256+
var elmError2 = $('.validation-input3');
257+
expect(elmError2.getText()).toEqual('');
258+
259+
// validation summary should become empty
260+
var itemRows = element.all(by.binding('message'));
261+
expect(itemRows.count()).toBe(0);
262+
});
263+
});
264+
265+
it('Should enter any text on input3 and stay without errors', function () {
266+
// make input3 invalid, remove text
267+
var elmInput3 = $('[name=input3]');
268+
elmInput3.sendKeys('any text');
269+
//elmInput3.sendKeys(protractor.Key.TAB);
270+
271+
// error should be removed from input3
272+
var elmError3 = $('.validation-input3');
273+
expect(elmError3.getText()).toEqual('');
274+
275+
// validation summary should become empty
276+
var itemRows = element.all(by.binding('message'));
277+
expect(itemRows.count()).toBe(0);
278+
});
279+
280+
it('Should check that ngDisabled button is now enabled (after input3 check)', function() {
281+
var elmSubmit1 = $('[name=btn_ngDisabled]');
282+
expect(elmSubmit1.isEnabled()).toBe(true);
283+
});
284+
285+
it('Should make input20 editable & error should appear', function() {
286+
// click on the radio button OFF, that will make the input editable
287+
element(by.id('radioDisableInput20_off')).click();
288+
browser.waitForAngular();
289+
290+
// error should appear
291+
var elmError = $('.validation-input20');
292+
expect(elmError.getText()).toEqual(errorMessages2FormsExtra);
293+
294+
// Save button should become disable
295+
var elmSubmit1 = $('[name=btn_ngDisabled]');
296+
expect(elmSubmit1.isEnabled()).toBe(false);
297+
});
298+
299+
it('Should show input20 error in ValidationSummary', function () {
300+
var btnShowSummary = $('button[name=btn_showValidation]');
301+
btnShowSummary.click();
302+
browser.waitForAngular();
303+
304+
// showValidation checkbox should false at first but true after
305+
var elmCheckboxShowSummary = element(by.model('displayValidationSummary'));
306+
expect(elmCheckboxShowSummary.isSelected()).toBeTruthy();
307+
308+
// scroll back to top
309+
browser.executeScript('window.scrollTo(0,0);').then(function () {
310+
var itemRows = element.all(by.binding('message'));
311+
var inputName;
312+
313+
for (var i = 0, j = 0, ln = itemRows.length; i < ln; i++) {
314+
expect(itemRows.get(i).getText()).toEqual('input20: May only contain letters, numbers and dashes. Must be at least 2 characters. Field is required.');
315+
}
316+
});
317+
});
318+
319+
it('Should disable input20, error go away from input & validation summary', function() {
320+
// click on the radio button OFF, that will make the input editable
321+
element(by.id('radioDisableInput20_on')).click();
322+
browser.waitForAngular();
323+
324+
// error should appear
325+
var elmError = $('.validation-input20');
326+
expect(elmError.getText()).toEqual('');
327+
328+
// validation summary should become empty
329+
var itemRows = element.all(by.binding('message'));
330+
expect(itemRows.count()).toBe(0);
331+
});
332+
333+
it('Should check that ngDisabled button is now enabled (after input20 check)', function() {
334+
var elmSubmit1 = $('[name=btn_ngDisabled]');
335+
expect(elmSubmit1.isEnabled()).toBe(true);
336+
});
337+
208338
it('Should reload english route, click on submit and display all error messages', function () {
209339
// scroll back to top if we want to be able to click on the English button
210340
browser.executeScript('window.scrollTo(0,0);').then(function () {
@@ -257,6 +387,7 @@
257387
}
258388
});
259389
});
390+
260391
}); // Directive()
261392
})(types, k); // closure
262393
} // for()
@@ -344,7 +475,7 @@
344475
expect(elmSubmit2.isEnabled()).toBe(true);
345476
});
346477

347-
it('Should make input4 editable & error should show on input4', function() {
478+
it('Should make input4 editable & error should appear', function() {
348479
// click on the radio button OFF, that will make the input editable
349480
element(by.id('radioDisableInput4_off')).click();
350481

@@ -397,5 +528,14 @@
397528
var elmSubmit2 = $('[name=save_btn2]');
398529
expect(elmSubmit2.isEnabled()).toBe(true);
399530
});
400-
});
401-
});
531+
532+
}); // describe 2forms
533+
}); // describe Angular-Validation tests
534+
535+
function clearInput(elem) {
536+
elem.getAttribute('value').then(function (text) {
537+
var len = text.length
538+
var backspaceSeries = Array(len+1).join(protractor.Key.BACK_SPACE);
539+
elem.sendKeys(backspaceSeries);
540+
})
541+
}

readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#Angular Validation (Directive / Service)
2-
`Version: 1.3.28`
2+
`Version: 1.3.29`
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!

src/validation-common.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ angular
5757
};
5858

5959
// list of available published public functions of this object
60+
validationCommon.prototype.arrayFindObject = arrayFindObject; // search an object inside an array of objects
6061
validationCommon.prototype.defineValidation = defineValidation; // define our validation object
6162
validationCommon.prototype.getFormElementByName = getFormElementByName; // get the form element custom object by it's name
6263
validationCommon.prototype.getFormElements = getFormElements; // get the array of form elements (custom objects)
@@ -212,7 +213,8 @@ angular
212213
* @param string elmName: element name
213214
*/
214215
function removeFromValidationSummary(elmName, validationSummaryObj) {
215-
var form = getElementParentForm(elmName, this); // find the parent form (only found if it has a name)
216+
var self = this;
217+
var form = getElementParentForm(elmName, self); // find the parent form (only found if it has a name)
216218
var vsObj = (!!validationSummaryObj) ? validationSummaryObj : _validationSummary;
217219

218220
var index = arrayFindObjectIndex(vsObj, 'field', elmName); // find index of object in our array
@@ -226,7 +228,7 @@ angular
226228
_validationSummary.splice(index, 1);
227229
}
228230

229-
this.scope.$validationSummary = _validationSummary;
231+
self.scope.$validationSummary = _validationSummary;
230232

231233
// and also save it inside the current scope form (if found)
232234
if (!!form) {
@@ -348,8 +350,8 @@ angular
348350
}
349351

350352
// get some common variables
351-
var elmName = (!!self.validatorAttrs && !!self.validatorAttrs.name)
352-
? self.validatorAttrs.name
353+
var elmName = (!!self.ctrl && !!self.ctrl.$name)
354+
? self.ctrl.$name
353355
: (!!self.attrs && !!self.attrs.name)
354356
? self.attrs.name
355357
: self.elm.attr('name');
@@ -627,8 +629,8 @@ angular
627629
}
628630

629631
// get the element name, whichever we find it
630-
var elmName = (!!self.validatorAttrs && !!self.validatorAttrs.name)
631-
? self.validatorAttrs.name
632+
var elmName = (!!self.ctrl && !!self.ctrl.$name)
633+
? self.ctrl.$name
632634
: (!!self.attrs && !!self.attrs.name)
633635
? self.attrs.name
634636
: self.elm.attr('name');

0 commit comments

Comments
 (0)