简体   繁体   中英

Angularjs - Validate initial url value with custom directive

I have this custom validation directive:

/**
 *  Overwrites default url validation using Django's URL validator
 *  Original source: http://stackoverflow.com/questions/21138574/overwriting-the-angularjs-url-validator
 */
angular.module('dmn.vcInputUrl', [])

.directive('vcUrl', function() {

  // Match Django's URL validator, which allows schemeless urls.
  var URL_REGEXP = /^((?:http|ftp)s?:\/\/)(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:\/?|[\/?]\S+)$/i;

  var validator = function(value) {
    if (!URL_REGEXP.test(value) && URL_REGEXP.test('http://' + value)) {
      return 'http://' + value;
      } else {
        return value;
      }
    }

  return {
    require: '?ngModel',
    link: function link(scope, element, attrs, ngModel) {
      function allowSchemelessUrls() {


        // Silently prefixes schemeless URLs with 'http://' when converting a view value to model value.    
        ngModel.$parsers.unshift(validator);

        ngModel.$validators.url = function(value) {
          return ngModel.$isEmpty(value) || URL_REGEXP.test(value);
        };
      }
      if (ngModel && attrs.type === 'url') {
        allowSchemelessUrls();
      }
    }
  };
});

It works fine when you 'dirty' the input by typing or pasting, but I need it to run this validation, overwriting the default type="url" validation when the value is initially set in the ngModel.

I've tried adding ngModel.$formatters.unshift(validator); but it results in the 'http://' being added to input, which I need to avoid as user's changes are manually approved and it would be a waste of time to approve the addition of 'http://'.

Any help would be appreciated!

Set ng-model-options on the input type field, for example:

 <input type="text" ng-model-options="{ updateOn: 'default', debounce: {'default': 0} }"</input> 

This will ensure your validator gets fired "when the value is initially set in the ngModel", as you have stated in the question.

See detailed AngularJs documentaion on ngModelOptions: enter link description here

validation of Url :

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <form name="form"> URL: <input type="url" ng-model="url.text" placeholder="Enter Link" name="fb_link"></input> <span class="error" ng-show="form.fb_link.$error.url"></span> </form> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM