dominic
dominic

Reputation: 405

Angular Js Directive to Convert Input

Hi Guys I want to write a angular directive which encodes the input text to html. So that critical characters are converted. For example ö -> &ouml
I have found this nice library, which I want to use.

My problem is I want to have this convertation only in my model. The user shouldn't see anything from this.

For now I have tried this way. But this doesn't do what I want. I'm new to angular and don't get comfortable with directives. Maybe you can help me.

angular.module('schwimmfestivalAngApp')
    .directive('encodedInput', function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, element, ctrl, he) {

                element.bind('onblur',
                    function () {
                        ctrl.$modelValue = he.encode(ctrl.$viewValue, {
                            'useNamedReferences': true
                        });
                    }
                )
                ;

            }
        };
    });

Upvotes: 0

Views: 310

Answers (2)

dominic
dominic

Reputation: 405

Thanks to Robert for his hints. I think I have figured it out now.

For me it works but not seems to be the perfect way.

This is for now how my directive looks for now.

.directive('encodedInput', function ($window) {
    return {
      restrict: 'A',
      require: '?ngModel',
      link: function (scope, element, attrs, ngModel) {
        if (!ngModel) return; // do nothing if no ng-model

        // Specify how UI should be updated
        ngModel.$render = function () {
          element.html($window.he.decode(ngModel.$modelValue || ''));
        };

        var inputString = '';

        // Listen for change events to enable binding
        element.on('blur keyup change', function () {

          //Check wether the string has changed. So the & will not be extra encoded.
          if (inputString != ngModel.$viewValue) {//Combined without logging
            console.log(length);
            length = inputString.length;
            ngModel.$setViewValue($window.he.encode(ngModel.$viewValue, {
              'useNamedReferences': true
            }));
          }
          inputString = ngModel.$viewValue;
        });
        function read(string) {

        }
      }
    };
  }

Upvotes: 0

Robert Koritnik
Robert Koritnik

Reputation: 105039

This is definitely not a beginner's task as you need to have a bit more experience with Angular to make it work as expected.

Manipulating data between view and model in an Angular directive has two parts. One that does conversion from model to view and the other that does conversion from view to model. Basically you should manipulate data in both directions, so your view displays something while your model holds a manipulated value that satisfies your requirements.

Model ⇒ View

You should implement $render function to aid this part:

ngModelController.$render = function() {
    ...
}

View ⇒ Model

This part may implement several things. The most important thing in your scenario is probably calling $setViewValue function

element.on("blur", function(evt) {
    ngModelController.$setViewValue(...);
});

Naming may be a bit misleading here as we want data model value to change and not view model value, but read this excerpt directly from docs:

When $setViewValue is called, the new value will be staged for committing through the $parsers and $validators pipelines. If there are no special ngModelOptions specified then the staged value sent directly for processing, finally to be applied to $modelValue and then the expression specified in the ng-model attribute. Lastly, all the registered change listeners, in the $viewChangeListeners list, are called.

But there're also directive parsers that can manipulate your view value before it gets committed to the model.

ngModelController.$parsers.push(customParser);

function customParser(value) {
    return /* some value */;
}

Documentation details

Make sure you thoroughly read the ngModelController documentation.

Important note

Make sure you implement several other points mentioned in this documentation by only adding console logs so you can get a grasp of directive execution cycle.

Upvotes: 1

Related Questions