Skip to content

Instantly share code, notes, and snippets.

@avilaj
Last active February 16, 2017 17:19
Show Gist options
  • Save avilaj/3431f2b1c7bc9673236898aba7dd4cef to your computer and use it in GitHub Desktop.
Save avilaj/3431f2b1c7bc9673236898aba7dd4cef to your computer and use it in GitHub Desktop.
AngularJS Server-side validation directive
/*
* Let’s assume that the server returns validation errors using
* the following format:
*
* [{
* "field": "code",
* "type": "unique",
* "value": 123,
* "message": "this field is unique"
* }]
*
*/
import ServerValidationController from './server-validation.controller';
const serverValidationComponent = {
require: {
form: '^form'
},
template: '',
controller: ServerValidationController,
controllerAs: 'vm',
bindings: {
errors: '<'
}
}
export default angular.module('server-validation', [])
.component('server-validate', serverValidationComponent)
export default class ServerValidationController {
constructor($scope) {
'ngInject';
$scope.$watch(() => this.errors, errors => this.mapErrorsToFields(errors) )
}
invalidateField (field, errorType) {
const changeListener = () => {
field.$setValidity(errorType, true);
let index = field.$viewChangeListeners.indexOf(changeListener);
if (index > -1) {
field.$viewChangeListeners.splice(index, 1);
}
}
field.$setDirty();
field.$setValidity(errorType, false);
field.$viewChangeListeners.push(changeListener);
}
mapErrorsToFields (errors = []) {
errors.map(error => {
this.invalidateField(this.form[error.field], `server.${error.type.toLowerCase()}`)
})
}
}
<form name="form" ng-submit="create()">
<server-validate errors="errorsFromServer"></server-validate>
<div class="form-group">
<input type="text" ng-model="model.code" required name="code" />
<div class="help-block" ng-messages="form.code.$error">
<div ng-message="required">This field is required</div>
<div ng-message="server.unique">This field must be unique</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-disabled="form.$pristine || form.$invalid">
Send
</button>
</div>
</form>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment