Skip to content

Commit

Permalink
Add support for multiple input elements in a form-group fixes paulyod…
Browse files Browse the repository at this point in the history
  • Loading branch information
jantimon committed Feb 13, 2015
1 parent 23bfa9f commit b5f9b4a
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 41 deletions.
55 changes: 38 additions & 17 deletions src/showErrors.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,57 @@ showErrorsModule.directive 'showErrors',
showSuccess

linkFn = (scope, el, attrs, formCtrl) ->
blurred = false
blurred = {}
inputNames = []
options = scope.$eval attrs.showErrors
showSuccess = getShowSuccess options
trigger = getTrigger options
trigger = getTrigger options

inputEl = el[0].querySelector '.form-control[name]'
inputNgEl = angular.element inputEl
inputName = $interpolate(inputNgEl.attr('name') || '')(scope)
unless inputName
throw "show-errors element has no child input elements with a 'name' attribute and a 'form-control' class"
inputElements = {}
for inputElement in el[0].querySelectorAll('.form-control[name]')
if inputName = $interpolate(inputElement.name || '')(scope)
(inputElements[inputName] or= []).push inputElement

isBlurred = () ->
allBlurred = true
angular.forEach blurred, (elementBlurred) ->
allBlurred = allBlurred && elementBlurred
allBlurred

isValid = () ->
allValid = true
angular.forEach inputNames, (inputName) ->
allValid = allValid && formCtrl[inputName].$valid
allValid

inputNgEl.bind trigger, ->
blurred = true
toggleClasses formCtrl[inputName].$invalid
angular.forEach inputElements, (inputEl, inputName) ->
inputNames.push inputName
blurred[inputName] = false
inputNgEl = angular.element inputEl
inputNgEl.bind trigger, ->
blurred[inputName] = true
if isBlurred()
toggleClasses !isValid()

scope.$watch ->
formCtrl[inputName] && formCtrl[inputName].$invalid
, (invalid) ->
return if !blurred
toggleClasses invalid
scope.$watch ->
formCtrl[inputName] && formCtrl[inputName].$invalid
, (invalid) ->
return if !isBlurred()
toggleClasses !isValid()

unless inputNames.length
throw "show-errors element has no child input elements with a 'name' attribute and a 'form-control' class"

scope.$on 'show-errors-check-validity', ->
toggleClasses formCtrl[inputName].$invalid
toggleClasses !isValid()

scope.$on 'show-errors-reset', ->
$timeout ->
# want to run this after the current digest cycle
el.removeClass 'has-error'
el.removeClass 'has-success'
blurred = false
angular.forEach inputNames, (inputName) ->
blurred[inputName] = false
, 0, false

toggleClasses = (invalid) ->
Expand Down
72 changes: 52 additions & 20 deletions src/showErrors.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/showErrors.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 77 additions & 0 deletions test/showErrors.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ describe 'showErrors', ->
<div id="last-name-group" class="form-group" show-errors="{ showSuccess: true }">
<input type="text" name="lastName" ng-model="lastName" ng-minlength="3" class="form-control" />
</div>
<div id="address-group" class="form-group" show-errors="{ showSuccess: true }">
<input type="text" name="zip" ng-model="zip" ng-minlength="3" class="form-control" />
<input type="text" name="city" ng-model="city" ng-minlength="3" class="form-control" />
</div>
</form>'
)($scope)
angular.element(document.body).append el
Expand Down Expand Up @@ -227,6 +231,65 @@ describe 'showErrors', ->
$timeout.flush()
expectLastNameFormGroupHasSuccessClass(el).toBe false

describe 'multiple inputs', ->

describe '$dirty && one $invalid && all blurred', ->
it 'has-error is present', ->
el = compileEl()
$scope.userForm.zip.$setViewValue invalidName
$scope.userForm.city.$setViewValue validName
angular.element(zipEl(el)).triggerHandler 'blur'
angular.element(cityEl(el)).triggerHandler 'blur'
expectAddressFormGroupHasErrorClass(el).toBe true

describe '$dirty && all $invalid && all blurred', ->
it 'has-error is present', ->
el = compileEl()
$scope.userForm.zip.$setViewValue invalidName
$scope.userForm.city.$setViewValue invalidName
angular.element(zipEl(el)).triggerHandler 'blur'
angular.element(cityEl(el)).triggerHandler 'blur'
expectAddressFormGroupHasErrorClass(el).toBe true

describe '$dirty && all $valid && all blurred', ->
it 'has-error is absent', ->
el = compileEl()
$scope.userForm.zip.$setViewValue validName
$scope.userForm.city.$setViewValue validName
angular.element(zipEl(el)).triggerHandler 'blur'
angular.element(cityEl(el)).triggerHandler 'blur'
expectAddressFormGroupHasErrorClass(el).toBe false

describe '$dirty && all $invalid && one blurred', ->
it 'has-error is absent', ->
el = compileEl()
$scope.userForm.zip.$setViewValue invalidName
$scope.userForm.city.$setViewValue invalidName
angular.element(zipEl(el)).triggerHandler 'blur'
expectAddressFormGroupHasErrorClass(el).toBe false

describe '$dirty && one $invalid && one blurred', ->
it 'has-error is absent', ->
el = compileEl()
$scope.userForm.zip.$setViewValue validName
$scope.userForm.city.$setViewValue invalidName
angular.element(zipEl(el)).triggerHandler 'blur'
expectAddressFormGroupHasErrorClass(el).toBe false

describe '$dirty && all $invalid && none blurred', ->
it 'has-error is absent', ->
el = compileEl()
$scope.userForm.zip.$setViewValue invalidName
$scope.userForm.city.$setViewValue invalidName
expectAddressFormGroupHasErrorClass(el).toBe false

describe '$dirty && one $invalid && none blurred', ->
it 'has-error is absent', ->
el = compileEl()
$scope.userForm.zip.$setViewValue validName
$scope.userForm.city.$setViewValue invalidName
expectAddressFormGroupHasErrorClass(el).toBe false

describe 'showErrorsConfig', ->
$compile = undefined
$scope = undefined
Expand Down Expand Up @@ -307,6 +370,12 @@ firstNameEl = (el) ->
lastNameEl = (el) ->
find el, '[name=lastName]'

zipEl = (el) ->
find el, '[name=zip]'

cityEl = (el) ->
find el, '[name=city]'

expectFormGroupHasErrorClass = (el) ->
formGroup = el[0].querySelector '[id=first-name-group]'
expect angular.element(formGroup).hasClass('has-error')
Expand All @@ -319,10 +388,18 @@ expectLastNameFormGroupHasSuccessClass = (el) ->
formGroup = el[0].querySelector '[id=last-name-group]'
expect angular.element(formGroup).hasClass('has-success')

expectAddressFormGroupHasSuccessClass = (el) ->
formGroup = el[0].querySelector '[id=address-group]'
expect angular.element(formGroup).hasClass('has-success')

expectFirstNameFormGroupHasErrorClass = (el) ->
formGroup = el[0].querySelector '[id=first-name-group]'
expect angular.element(formGroup).hasClass('has-error')

expectLastNameFormGroupHasErrorClass = (el) ->
formGroup = el[0].querySelector '[id=last-name-group]'
expect angular.element(formGroup).hasClass('has-error')

expectAddressFormGroupHasErrorClass = (el) ->
formGroup = el[0].querySelector '[id=address-group]'
expect angular.element(formGroup).hasClass('has-error')
Loading

0 comments on commit b5f9b4a

Please sign in to comment.