2

I'm trying to implement server-side validation for a form element using angularjs.

I followed this question (using the last answer to that question as the basis of solution).

How to display server errors in Angularjs with ng-messages

And with help from this article: http://codetunes.com/2013/server-form-validation-with-angular/ - I'm trying to clear the error message using a directive after the value is changed.

The problem is, I don't know how to get a handle on the field to reset the validity on the input. The code below was essentially copied from the article but is not working with ng-messages module.

angular.module('OCS')
  .directive('serverError', function () {
    return {
    restrict: 'A',
    link: function (scope, element, attrs, ctrl) {
      element.on('change', function (ev) {
        scope.$apply(function () {
          scope.$setValidity('server', true);
        })
      });
    }
  }
});

The code below reads the response from the server and displays the error messages. (this is working)

if (response.status === 400) {
    response.data.forEach(function(fieldMsg){
      form[fieldMsg.param].$setValidity('server', false);
      if (!$scope.formErrors){
        $scope.formErrors = {};
      }
      $translate('errors.' + fieldMsg.msg).then(function(msg){
        $scope.formErrors[fieldMsg.param] = msg;
      });
    });

And an example of the input:

<div layout-gt-sm="row">
    <md-input-container flex-gt-sm="50">
        <label>{{'pages.profilePage.email' | translate}}</label>
        <input type="email" ng-model="profileDetails.email" name="email" class="md-input md-input-white" required server-error>
        <div ng-messages="updateProfileForm.email.$error" ng-if='updateProfileForm.email.$dirty'>
            <div ng-messages-include="error-messages"></div>
            <div ng-message="server">{{formErrors.email}}</div>
        </div>
    </md-input-container>
</div>
  1. Displaying the server error works fine.
  2. The directive is registered and fires.

Essentially, I need to execute something more like this from within the directive:

form[element[0].name].$setValidity('server', true);

But how can I get a reference to the current form from within the directive without knowing the form name?

---------------- Edited Here --------------

This is what I went with, I'm not sure if there's a better way to access the form from the directive:

angular.module('OCS')
  .directive('serverError', function () {
    return {
    restrict: 'A',
    link: function (scope, element, attrs, ctrl) {
      element.on('change', function (ev) {
        scope.$apply(function () {
          if (scope.formErrors) {
            scope.formErrors[element[0].name] = undefined;

            var formName = element.parents('form').attr('name');
            scope[formName][element[0].name].$setValidity('server', true);
          }
        })
      });
    }
  }
});
2
  • You're using $scope.formErrors to store the errors, so you just need to remove the field from that. i.e. delete $scope.formErrors['email']; Commented May 16, 2016 at 10:25
  • Thanks, I tried that already but it just removes the message, the field and form are still regarded as invalid. Commented May 16, 2016 at 10:29

1 Answer 1

0

You can simply pass the form name to your submit handler:

<form name="form1" ng-submit="handleSubmit(form1)">..</form>

Then you can access the form via the parameter passed to your submit handler:

$scope.handleSubmit = function(form) {
    console.log(form.$name)
}   

i.e.

form['input'].$setValidity('server', true);

Hope this helps?

Sign up to request clarification or add additional context in comments.

1 Comment

this would probably work also if I pass the form name through the scope. But the edit I just posted is okay, it works. Cheers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.