Skip to content

Commit 4e9ea86

Browse files
committed
added unit tests around the custom trigger option
1 parent 85934e5 commit 4e9ea86

6 files changed

Lines changed: 115 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* Breaking Changes
44
* Added a more specific selector query for the input element. The input element must now also have the 'form-control' class associated with it. Thanks @martindederer
55

6+
* Enhancements
7+
* Added `trigger` option to provide a custom trigger to validate the value. By default the trigger is the `blur` event. Thanks @TEmplarian
8+
69
### 1.1.0
710

811
* Enhancements

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ app.config(['showErrorsConfigProvider', function(showErrorsConfigProvider) {
9595
}]);
9696
```
9797

98-
##### By Input
98+
##### By Input Element
9999
If you only want to show valid values on specific inputs, then you can pass in the `{ showSuccess: true }` option like the example below shows.
100100

101101
```html
@@ -105,6 +105,29 @@ If you only want to show valid values on specific inputs, then you can pass in t
105105
</div>
106106
</form>
107107
```
108+
109+
Custom Trigger
110+
---
111+
By default, the validation is not performed until the `blur` event is trigger on the input
112+
element. However, there are some scenarios where this is not desirable, so it's possible to
113+
override this with the `trigger` option.
114+
115+
##### By Input Element
116+
```html
117+
<form name="userForm">
118+
<div class="form-group" show-errors="{ trigger: 'keypress' }">
119+
<input ng-model="firstName" ng-pattern="/^foo$/" ng-required name="firstName" class="form-control" type="text" />
120+
</div>
121+
</form>
122+
```
123+
124+
##### Globally
125+
```javascript
126+
app = angular.module('yourApp', ['ui.bootstrap.showErrors']);
127+
app.config(['showErrorsConfigProvider', function(showErrorsConfigProvider) {
128+
showErrorsConfigProvider.trigger('keypress');
129+
}]);
130+
```
108131

109132
## Development
110133

src/showErrors.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55

66
showErrorsModule.directive('showErrors', [
77
'$timeout', 'showErrorsConfig', function($timeout, showErrorsConfig) {
8-
var getShowSuccess, linkFn;
8+
var getShowSuccess, getTrigger, linkFn;
9+
getTrigger = function(options) {
10+
var trigger;
11+
trigger = showErrorsConfig.trigger;
12+
if (options && (options.trigger != null)) {
13+
trigger = options.trigger;
14+
}
15+
return trigger;
16+
};
917
getShowSuccess = function(options) {
1018
var showSuccess;
1119
showSuccess = showErrorsConfig.showSuccess;
@@ -15,17 +23,18 @@
1523
return showSuccess;
1624
};
1725
linkFn = function(scope, el, attrs, formCtrl) {
18-
var blurred, inputEl, inputName, inputNgEl, options, showSuccess, toggleClasses;
26+
var blurred, inputEl, inputName, inputNgEl, options, showSuccess, toggleClasses, trigger;
1927
blurred = false;
2028
options = scope.$eval(attrs.showErrors);
2129
showSuccess = getShowSuccess(options);
30+
trigger = getTrigger(options);
2231
inputEl = el[0].querySelector('.form-control[name]');
2332
inputNgEl = angular.element(inputEl);
2433
inputName = inputNgEl.attr('name');
2534
if (!inputName) {
2635
throw "show-errors element has no child input elements with a 'name' attribute and a 'form-control' class";
2736
}
28-
inputNgEl.bind('blur', function() {
37+
inputNgEl.bind(trigger, function() {
2938
blurred = true;
3039
return toggleClasses(formCtrl[inputName].$invalid);
3140
});
@@ -68,14 +77,19 @@
6877
]);
6978

7079
showErrorsModule.provider('showErrorsConfig', function() {
71-
var _showSuccess;
80+
var _showSuccess, _trigger;
7281
_showSuccess = false;
82+
_trigger = 'blur';
7383
this.showSuccess = function(showSuccess) {
7484
return _showSuccess = showSuccess;
7585
};
86+
this.trigger = function(trigger) {
87+
return _trigger = trigger;
88+
};
7689
this.$get = function() {
7790
return {
78-
showSuccess: _showSuccess
91+
showSuccess: _showSuccess,
92+
trigger: _trigger
7993
};
8094
};
8195
});

src/showErrors.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/showErrors.spec.coffee

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ describe 'showErrorsConfig', ->
228228
testModule = angular.module 'testModule', []
229229
testModule.config (showErrorsConfigProvider) ->
230230
showErrorsConfigProvider.showSuccess true
231+
showErrorsConfigProvider.trigger 'keypress'
231232

232233
module 'ui.bootstrap.showErrors', 'testModule'
233234

@@ -240,7 +241,7 @@ describe 'showErrorsConfig', ->
240241
compileEl = ->
241242
el = $compile(
242243
'<form name="userForm">
243-
<div id="first-name-group" class="form-group" show-errors="{showSuccess: false}">
244+
<div id="first-name-group" class="form-group" show-errors="{showSuccess: false, trigger: \'blur\'}">
244245
<input type="text" name="firstName" ng-model="firstName" ng-minlength="3" class="form-control" />
245246
</div>
246247
<div id="last-name-group" class="form-group" show-errors>
@@ -257,7 +258,7 @@ describe 'showErrorsConfig', ->
257258
it 'show-success class is applied', ->
258259
el = compileEl()
259260
$scope.userForm.lastName.$setViewValue validName
260-
angular.element(lastNameEl(el)).triggerHandler 'blur'
261+
angular.element(lastNameEl(el)).triggerHandler 'keypress'
261262
$scope.$digest()
262263
expectLastNameFormGroupHasSuccessClass(el).toBe true
263264

@@ -270,6 +271,23 @@ describe 'showErrorsConfig', ->
270271
$scope.$digest()
271272
expectFirstNameFormGroupHasSuccessClass(el).toBe false
272273

274+
describe 'when showErrorsConfig.trigger is "keypress"', ->
275+
describe 'and no options given', ->
276+
it 'validates the value on the first keypress', ->
277+
el = compileEl()
278+
$scope.userForm.lastName.$setViewValue invalidName
279+
angular.element(lastNameEl(el)).triggerHandler 'keypress'
280+
$scope.$digest()
281+
expectLastNameFormGroupHasErrorClass(el).toBe true
282+
283+
describe 'but options.trigger is "blur"', ->
284+
it 'does not validate the value on keypress', ->
285+
el = compileEl()
286+
$scope.userForm.firstName.$setViewValue invalidName
287+
angular.element(firstNameEl(el)).triggerHandler 'keypress'
288+
$scope.$digest()
289+
expectFirstNameFormGroupHasErrorClass(el).toBe false
290+
273291
find = (el, selector) ->
274292
el[0].querySelector selector
275293

@@ -290,3 +308,11 @@ expectFirstNameFormGroupHasSuccessClass = (el) ->
290308
expectLastNameFormGroupHasSuccessClass = (el) ->
291309
formGroup = el[0].querySelector '[id=last-name-group]'
292310
expect angular.element(formGroup).hasClass('has-success')
311+
312+
expectFirstNameFormGroupHasErrorClass = (el) ->
313+
formGroup = el[0].querySelector '[id=first-name-group]'
314+
expect angular.element(formGroup).hasClass('has-error')
315+
316+
expectLastNameFormGroupHasErrorClass = (el) ->
317+
formGroup = el[0].querySelector '[id=last-name-group]'
318+
expect angular.element(formGroup).hasClass('has-error')

test/showErrors.spec.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(function() {
2-
var expectFirstNameFormGroupHasSuccessClass, expectFormGroupHasErrorClass, expectLastNameFormGroupHasSuccessClass, find, firstNameEl, lastNameEl;
2+
var expectFirstNameFormGroupHasErrorClass, expectFirstNameFormGroupHasSuccessClass, expectFormGroupHasErrorClass, expectLastNameFormGroupHasErrorClass, expectLastNameFormGroupHasSuccessClass, find, firstNameEl, lastNameEl;
33

44
describe('showErrors', function() {
55
var $compile, $scope, $timeout, compileEl, invalidName, validName;
@@ -280,7 +280,8 @@
280280
var testModule;
281281
testModule = angular.module('testModule', []);
282282
testModule.config(function(showErrorsConfigProvider) {
283-
return showErrorsConfigProvider.showSuccess(true);
283+
showErrorsConfigProvider.showSuccess(true);
284+
return showErrorsConfigProvider.trigger('keypress');
284285
});
285286
module('ui.bootstrap.showErrors', 'testModule');
286287
return inject(function(_$compile_, _$rootScope_, _$timeout_) {
@@ -292,7 +293,7 @@
292293
compileEl = function() {
293294
var el;
294295
el = $compile('<form name="userForm">\
295-
<div id="first-name-group" class="form-group" show-errors="{showSuccess: false}">\
296+
<div id="first-name-group" class="form-group" show-errors="{showSuccess: false, trigger: \'blur\'}">\
296297
<input type="text" name="firstName" ng-model="firstName" ng-minlength="3" class="form-control" />\
297298
</div>\
298299
<div id="last-name-group" class="form-group" show-errors>\
@@ -309,13 +310,13 @@
309310
var el;
310311
el = compileEl();
311312
$scope.userForm.lastName.$setViewValue(validName);
312-
angular.element(lastNameEl(el)).triggerHandler('blur');
313+
angular.element(lastNameEl(el)).triggerHandler('keypress');
313314
$scope.$digest();
314315
return expectLastNameFormGroupHasSuccessClass(el).toBe(true);
315316
});
316317
});
317318
});
318-
return describe('when showErrorsConfig.showSuccess is true', function() {
319+
describe('when showErrorsConfig.showSuccess is true', function() {
319320
return describe('but options.showSuccess is false', function() {
320321
return it('show-success class is not applied', function() {
321322
var el;
@@ -327,6 +328,28 @@
327328
});
328329
});
329330
});
331+
return describe('when showErrorsConfig.trigger is "keypress"', function() {
332+
describe('and no options given', function() {
333+
return it('validates the value on the first keypress', function() {
334+
var el;
335+
el = compileEl();
336+
$scope.userForm.lastName.$setViewValue(invalidName);
337+
angular.element(lastNameEl(el)).triggerHandler('keypress');
338+
$scope.$digest();
339+
return expectLastNameFormGroupHasErrorClass(el).toBe(true);
340+
});
341+
});
342+
return describe('but options.trigger is "blur"', function() {
343+
return it('does not validate the value on keypress', function() {
344+
var el;
345+
el = compileEl();
346+
$scope.userForm.firstName.$setViewValue(invalidName);
347+
angular.element(firstNameEl(el)).triggerHandler('keypress');
348+
$scope.$digest();
349+
return expectFirstNameFormGroupHasErrorClass(el).toBe(false);
350+
});
351+
});
352+
});
330353
});
331354

332355
find = function(el, selector) {
@@ -359,4 +382,16 @@
359382
return expect(angular.element(formGroup).hasClass('has-success'));
360383
};
361384

385+
expectFirstNameFormGroupHasErrorClass = function(el) {
386+
var formGroup;
387+
formGroup = el[0].querySelector('[id=first-name-group]');
388+
return expect(angular.element(formGroup).hasClass('has-error'));
389+
};
390+
391+
expectLastNameFormGroupHasErrorClass = function(el) {
392+
var formGroup;
393+
formGroup = el[0].querySelector('[id=last-name-group]');
394+
return expect(angular.element(formGroup).hasClass('has-error'));
395+
};
396+
362397
}).call(this);

0 commit comments

Comments
 (0)