0

I am trying to write a directive to do input validation for ip addresses.

I see a lot of examples on the web similar to this boiler plate code:

 <label>IP Address 1:</label>
 <input ng-model="formData.ip1" required name="ip1" type="text" 
        placeholder='xxx.xxx.xxx.xxx'
        ng-pattern = "/^(\d{1,3}\.){3}(\d{1,3})$/">
 <span ng-show="myForm.ip1.$error.required" style="color:red"> * </span>
 <span ng-show="myForm.ip1.$dirty && myForm.ip1.$invalid" style="color:red">
       This is an invalid IP.</span>

Since this needs to be in dozens of places, and since the validation rules and the way errors are indicated will likely change, I would like to use a directive such as this:

 <label>IP Address A:</label>
 <input ng-model="formData.ipa" required my-ip-validator>

The myIpValidator directive would add attributes (like ng-pattern) and extra elements (like spans)

I've tried several approaches. My latest was a directive with compile such as from here Add directives from directive in AngularJS I started a plunker (see update below)

I couldn't figure out how to get the form name for use in ng-show. Plus, the resulting input element didnt have necessary classes added later by angular, such as ng-pristine, ng-invalid, etc.

How can I do this? I'm open to either fixing the problems with this directive or a totally different approach.

Update: The plunker above was wrong. It was old. I'm working on an update which I'll post soon.

Update 2: I figured out something that works. Plunker at http://plnkr.co/edit/efnfMWprVH91hQnzYkX7?p=preview I was missing passing $compile to the function. And, the other part of it was getting the form name from some DOM inspection. I'll now clean it up and improve it. But if anyone has other suggestions, I'm open to learning. This was my first directive.

Community
  • 1
  • 1
user3141592
  • 1,069
  • 2
  • 10
  • 20
  • Check out my answer in this question, it might give you some ideas. http://stackoverflow.com/questions/22493774/controller-connect-to-directive-for-validation/22494139#22494139 – aet Apr 23 '14 at 23:29
  • aet - Thanks for the ideas. However, I'd like the span to be put after the input by the directive. Because, for example, if someone decides the span should come before the inputs, I would have to modify it in dozens of places. Obviously I've invested so much time in this that by now search and modify would have been more efficient. However, I'm still curious if it can be done and hoping to learn something to help me in the future. – user3141592 Apr 24 '14 at 13:17

1 Answers1

0

I'm answering my own question. Yes, this can be done. I was close with the compile approach. I just needed to fix some minor things. Plunker at http://plnkr.co/edit/efnfMWprVH91hQnzYkX7?p=preview It wasn't working before because I wasn't passing $compile in to the directive. And, I didn't know how to get form and input names.

Here's how I did that:

        var inputname = element.attr("name"),
            foundForm = false,
            ancestor = element.parent();

        while (!foundForm && ancestor) {                
            if ( angular.uppercase(ancestor.prop("tagName")) == "FORM" ) {
                foundForm = true;
                var formname = ancestor.attr("name");
            } else {
                ancestor = ancestor.parent();
            }
        }
user3141592
  • 1,069
  • 2
  • 10
  • 20