How to write a custom validator directive?

Assume that you have a form, in the form you have a text input which is allow you to input an url follow these rule

required (can not be empty)

accept a-z,A-Z,0-9 and the “_”

OK so how do we implement it?
firstly create a form with an input inside and a button to submit form

1

2

3

4

<form name="frmSurvey">

<input type="text"name="article_url"/>

<button type="button">Submit</button>

</form>

when you create a form like so angularjs automatically create an object with form’s name, let see how is the object look like:

as we see frmSurvey object has some elements such as: $error, $valid… and article_url (the input text),
article_url also is an object has some elements as: $valid, $modelValue, $viewValue $dirty
so now I want when I click Submit button I just need to check like so:

// create linking function and pass in our NgModelController as a 4th argument

link:function(scope,element,attr,ctrl){

let urlregex=scope.$parent.URL_REGEX;

functionisExist(ngModelValue){

let url='/backend/article/checkURLExist/'+ngModelValue;

return$http.get(url);

}

functiondoValid(ngModelValue){

if(urlregex.test(ngModelValue)){

ctrl.$setValidity('pattern',true);

}else{

ctrl.$setValidity('pattern',false);

}

if(ngModelValue.length<=30){

ctrl.$setValidity('maxLength',true);

}else{

ctrl.$setValidity('maxLength',false);

}

let xhr=isExist(ngModelValue);

xhr.then((res)=>{

$timeout(function(){

let isExist=res.data;

if(isExist==="0"){

ctrl.$setValidity('unique',true);

}

else{

ctrl.$setValidity('unique',false);

}

});

});

// we need to return our ngModelValue, to be displayed to the user(value of the input)

returnngModelValue;

}

// we need to add our doValid function to an array of other(build-in or custom) functions

// I have not notice any performance issues, but it would be worth investigating how much

// effect does this have on the performance of the app

ctrl.$parsers.push(doValid);

}

};

}

pay attention on those lines below they are the most important part to add a validator to the form object

(the isExist validator part is just a bonus for unique check, check it out if you need otherwise you can ignore it)
1. set the validaty by ctrl.$setValidity(‘pattern’, true);
2. return ngModelValue; if we dont have this line the $modelValue of input text won have the value, but if you want you still can get the value by $viewValue
3. and finally add the doValid function to an array of other functions, if we don’t have this line nothing will be done