Commit b67ccacb authored by Aron Carroll's avatar Aron Carroll Committed by Randall Leeds

Improve the formValidate directive

We now just listen for changes to the form.$error object rather
than having the controller triggering an error event. This now supports
other changes such as external directives adding validations to
inputs also.
parent dacbab28
formValidate = -> formValidate = ['$timeout', ($timeout) ->
link: (scope, elem, attr, form) -> link: (scope, elem, attr, form) ->
errorClassName = attr.formValidateErrorClass isSubmitted = false
fieldClassName = 'form-field'
errorClassName = 'form-field-error'
toggleClass = (field, {addClass}) -> toggleClass = (field, {addClass}) ->
fieldEl = elem.find("[data-target=#{field.$name}]") inputEl = elem.find("[name=#{field.$name}]")
fieldEl = inputEl.parents(".#{fieldClassName}").first()
fieldEl.toggleClass(errorClassName, addClass) fieldEl.toggleClass(errorClassName, addClass)
updateField = (field) -> updateField = (field) ->
...@@ -30,18 +33,23 @@ formValidate = -> ...@@ -30,18 +33,23 @@ formValidate = ->
# Validate field when the content changes. # Validate field when the content changes.
elem.on 'change', ':input', -> elem.on 'change', ':input', ->
updateField(form[this.name])
# Validate the field when submit is clicked.
elem.on 'submit', (event) ->
forEachField(updateField) forEachField(updateField)
# Validate when a response is processed. # Validate form on submit and set flag for error watcher.
scope.$on 'error', (event, name) -> elem.on 'submit', ->
return unless form.$name == name isSubmitted = true
forEachField (field) ->
field.$setViewValue(field.$viewValue)
updateField(field)
scope.$watch form.$name + '.$error', ->
if isSubmitted
forEachField(updateField) forEachField(updateField)
isSubmitted = false
, true
require: 'form' require: 'form'
]
markdown = ['$filter', '$timeout', ($filter, $timeout) -> markdown = ['$filter', '$timeout', ($filter, $timeout) ->
......
...@@ -37,8 +37,8 @@ describe 'h.directives', -> ...@@ -37,8 +37,8 @@ describe 'h.directives', ->
$scope.model = {username: ''} $scope.model = {username: ''}
template = ''' template = '''
<form form-validate data-form-validate-error-class="form-field-error" name="login" onsubmit="return false"> <form form-validate name="login" onsubmit="return false">
<div class="form-field" data-error-class="form-field-error" data-target="username"> <div class="form-field">
<input type="text" class="" ng-model="model.username" name="username" required ng-minlength="3" /> <input type="text" class="" ng-model="model.username" name="username" required ng-minlength="3" />
</div> </div>
</form> </form>
...@@ -82,8 +82,8 @@ describe 'h.directives', -> ...@@ -82,8 +82,8 @@ describe 'h.directives', ->
$element.triggerHandler('submit') $element.triggerHandler('submit')
assert.notInclude($field.prop('className'), 'form-field-error') assert.notInclude($field.prop('className'), 'form-field-error')
it 'should apply an error class to an invalid field on "error" event', -> it 'should apply an error class if the form recieves errors after a submit action', ->
$scope.$emit('error', 'login') $element.trigger('submit')
$element.controller('form').username.$setValidity('response', false) $element.controller('form').username.$setValidity('response', false)
$field = $element.find('.form-field') $field = $element.find('.form-field')
...@@ -103,24 +103,24 @@ describe 'h.directives', -> ...@@ -103,24 +103,24 @@ describe 'h.directives', ->
assert.notInclude($field.prop('className'), 'form-field-error') assert.notInclude($field.prop('className'), 'form-field-error')
it 'should reset the "response" error on change', -> it 'should reset the "response" error when the view changes', ->
$field = $element.find('.form-field') $field = $element.find('.form-field')
$input = $element.find('[name=username]') $input = $element.find('[name=username]')
controller = $input.controller('ngModel') controller = $input.controller('ngModel')
controller.$setViewValue('abc') controller.$setViewValue('abc')
# Submit Event # Submit Event
$element.triggerHandler('submit')
controller.$setValidity('response', false) controller.$setValidity('response', false)
controller.responseErrorMessage = 'fail' controller.responseErrorMessage = 'fail'
$scope.$emit('error', $input.controller('form').$name) $scope.$digest()
assert.include($field.prop('className'), 'form-field-error')
assert.include($field.prop('className'), 'form-field-error', 'Fail fast check')
controller.$setViewValue('abc') controller.$setViewValue('abc')
$scope.$digest()
assert.notInclude($field.prop('className'), 'form-field-error') assert.notInclude($field.prop('className'), 'form-field-error')
describe '.username', -> describe '.username', ->
$element = null $element = null
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment