0

I have an input[text] that you type an URL and it will use an async validator to check if it is a valid RSS feed.

The URL is something like this, where feed-url is a directive for the async validation:

<input type="text"
    name="url"
    ng-model="url"
    ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }"
    placeholder="http://"
    feed-url
    >

I want to add the protocol ('http://') if the user forgets to. This must be done before it's validated (because it won't apply the model in case the user forgets because the URL is invalid).

I can't find any way to do it. Anyone has any idea?

Marco Pompei
  • 1,080
  • 1
  • 8
  • 18
  • Hopefully someone can write a full answer, but look in the accepted answer here on unshifting in a custom $parser, if you inject a $parser that can add the value as you need it before passing it on it should work, http://stackoverflow.com/questions/12581439/how-to-add-custom-validation-to-an-angular-js-form – Steve Mitcham Mar 20 '15 at 18:11

2 Answers2

1

Indeed, as suggested in a comment, this is what $parsers are used for - i.e. take the value coming from the View and "parse" it to make it model-compatible.

Parsers run before validators.

To add a parser, you need to add a directive:

.directive("fixUrl", function(){
  return {
    require: "?ngModel",
    link: function(scope, element, attrs, ngModel){
      if (!ngModel) return;

      ngModel.$parsers.push(function(val){
        // poor man's implementation
        if (url.indexOf("http") !== 0){
          url = "http://" + url;
        }
        return url;
      });
    }
  };
});

Usage:

<input ng-model="url" fix-url>
New Dev
  • 48,427
  • 12
  • 87
  • 129
0

Add this directive to your element:

ng-change="validateURL()"

then in your controller, have $scope.validateURL be a function which looks at the scope value that ng-model points to and alter it accordingly.

Example code: http://jsfiddle.net/tsclaus/skq2ubce/2/

The logic in my example could use improvement, but that's a basic idea. Ng-change on text inputs is somewhat annoying to handle due to it firing with every keystroke, so there might be a better way. The 30s delay on the timeout is an example of a way to handle that, and generally works provided they delete all of the "http://" string.

Tahsis Claus
  • 1,879
  • 1
  • 15
  • 27