Yulian
Yulian

Reputation: 6769

How to use angular-translate and ng-xeditable's validation together?

I'm using angular-translate and angular-xeditable. I have the following field:

<a href="#"
       editable-text="name"
       onbeforesave="validate($data)"
       onaftersave="save(name)">
       {{ name }}
</a>

In the validate function I'm validating the name field and if everything is correct I'm saving the data through the save method. However, if the name field is not correct, I should return a validation message. There's an example in the documentation of angular-xeditable of such a scenario.

$scope.validate = function(name) {
    if (name.length > 10) {
        return "Validation Message that doesn't need multiple languages";
    }
}

Now, if the name field is more than 10 characters long, a message will be display to the user and the data won't be saved. However, I'm using angular-translate in my app and I want to show a message that is translated in the appropriate language. Moreover, I want to customize my messages for different scenarios so that I won't need to have thousands of different messages for all of my fields.

For example:

var translationsEN = {
    STRING_LENGTH_MESSAGE: '{{ fieldName }} should be between {{ min }} and {{ max }}',
    REQUIRED: '{{ fieldName }} is required.'
}
var translationsDE = {
    // The same messages in German.
}

Now the best thing that I could think of is changing the code in the validate function to this:

$scope.validate = function(name) {
    if (name.length > 10) {
        $translate('VALIDATION_MESSAGE', { fieldName: 'name', min: 0, max: 10 })
            .then(function(translation) {
                $scope.message = translation;
            }
        );

        return $scope.message;
    }
}

Of course, at the time of showing the error message, the error message is not translated yet and the message that is shown to the user is not correct.

How can I achieve the desired result - to show translated validation messages to the user?

Here's a JSFiddle of my example.

Upvotes: 2

Views: 309

Answers (1)

a-change
a-change

Reputation: 666

Spent a fair amount of hours with this today :)

What seems to be a workaround is compiling an element that'll have the translate directive, so the OP's function would look sth like:

$scope.validateName = function(name) {
    if (name.length > 10) {
      console.log('fail')
      var element = $compile('<span translate="VALIDATION_MESSAGE"></span>')($scope)[0];
      return $timeout(function() {
        $scope.$apply();
        return element.textContent
      }, 10);
    }
  };

A bit more on compiling and dynamically adding directives (which is what would also help solve the task — if we could dynamically set the translate directive to the error container) is in the answers to this question: Dynamically add directive in AngularJS

UPDATE: changed the code a bit, so that it works with validating the name in controller. $timeout might not be needed if the validation is performed on server but in this case it wouldn't be possible to use $scope.$apply() otherwise without which the result wouldn't be interpolated.

Working JSFiddle — first input is validated in the OP's way, the second — with the function above.

Hope it helps.

Upvotes: 0

Related Questions