Skip to content

Instantly share code, notes, and snippets.

@TigorC
Last active August 29, 2015 14:08
Show Gist options
  • Save TigorC/216db556b9ff739e26e8 to your computer and use it in GitHub Desktop.
Save TigorC/216db556b9ff739e26e8 to your computer and use it in GitHub Desktop.
Angular 1.3 form validation directives
angular.module("Validation", ["ngMessages"]).constant("validationClassConfig",
validClass: "has-success"
invalidClass: "has-error"
)
.service("formValidation", ->
setDirtyField = (field) ->
field.$setDirty()
localValidateForm: (form) ->
_formValidate = (innerForm) ->
angular.forEach innerForm, (field, name) ->
if angular.isString(name) and !name.match('^[\$]')
setDirtyField field
if not angular.isFunction field.$setViewValue
_formValidate field
_formValidate form
errorsList: (form, data, skipUnknownFields) ->
findedField = null
getField = (form, fieldName) ->
angular.forEach form, (field, name) ->
if angular.isString(name) and not name.match("^[$]")
if angular.isFunction(field.$setViewValue)
findedField = field if name == fieldName
else
findedField = getField(field, fieldName)
return
findedField
setNonFieldErrors = (erorrs) ->
form.$errorMessages = if angular.isString(erorrs) then erorrs else erorrs.join(", ")
angular.forEach data, (errors, field) ->
if field == "non_field_errors"
setNonFieldErrors errors
return
formField = getField(form, field)
return if not formField and skipUnknownFields
if not formField and not skipUnknownFields
throw new Error("Field '#{field}' not found in '#{form.$name}' form")
formField.$setValidity "server", false
formField.$errorMessages = if angular.isString(errors) then errors else errors.join(", ")
setDirtyField formField
)
.directive("validationClassFor", ["validationClassConfig", (validationClassConfig) ->
require: "^form"
link: (scope, element, attrs, formCtrl) ->
invalidClass = validationClassConfig.invalidClass
validClass = validationClassConfig.validClass
field = null
fieldFindWatch = scope.$watch (-> formCtrl[attrs.validationClassFor]), (
(newValue) ->
return if not newValue
field = newValue
startWatch()
fieldFindWatch() # stop find field
)
startWatch = ->
scope.$watch (-> {errors: field.$error, dirty: field.$dirty}), ((newValue) ->
if field.$invalid and field.$dirty
element.removeClass(validClass).addClass invalidClass
else if field.$valid and field.$dirty and element.hasClass(invalidClass)
element.removeClass(invalidClass).addClass validClass
else
element.removeClass(invalidClass).removeClass validClass
), true
])
.directive("formFieldErrors", ->
require: "^form"
scope: true
restrict: "AE"
template: '
<div ng-messages="formField.$error"
ng-messages-include="new/angularapp/common/templates/messages.html"
ng-show="formField.$dirty">
<span class="help-block" ng-message="server">{{ formField.$errorMessages }}</span>
</div>'
link: (scope, element, attrs, formCtrl) ->
fieldFindWatch = scope.$watch (-> formCtrl[attrs.field]), ((newValue) ->
return if not newValue
scope.formField = newValue
startWatch()
fieldFindWatch() # stop find field
)
startWatch = ->
scope.$watch "formField.$viewValue", (newValue) ->
scope.formField.$setValidity "server", true
formCtrl.$errorMessages = undefined
)
.directive("formErrors", ->
restrict: "AE"
scope:
form: "="
template: '<div class="alert alert-danger" role="alert" ng-show="form.$errorMessages">{{ form.$errorMessages }}</div>'
)
.directive('submit', ['$parse', 'formValidation', ($parse, formValidation) ->
restrict: 'A'
link: (scope, formElement, attrs) ->
submitHandler = if attrs.submitHandler then $parse(attrs.submitHandler)(scope) else null
formElement.bind 'submit', (e) ->
form = scope[attrs.name]
e.preventDefault()
formValidation.localValidateForm form
submitHandler() if submitHandler
scope.$apply()
scope.$apply(attrs.submit) if form.$valid
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment