0

So I have a directive like so which works great but I want to have it so if the user changes the IP Address to "192.168.3.10" or the Gateway to "192.168.3.1" that all three fields are marked as invalid.

Essentially if one field is marked invalid, make the other two.

var myApp = angular.module('myApp', []);

myApp.controller("MyCtrl", ["$scope",function($scope) {
$scope.IPAddress = "192.168.1.10";
$scope.Gateway = "192.168.1.1";
$scope.Netmask = "255.255.255.0";
}]);
myApp.directive("networkCheck", function() {
  return {
    require: 'ngModel',
    scope: {
      otherIp: "=",
      netmask: "="
    },
    link: function(scope, elem, attrs, ctrl) {
      var sameNetwork = function(ipOne, ipTwo, netmask) {
      console.log(ipOne, ipTwo, netmask);
      if (!ipOne || !ipTwo || !netmask) {
        return true;
      }
      var components1 = ipOne.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
      var components2 = ipTwo.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
      var subcomps = netmask.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);

      if (components1 === null || components2 === null || subcomps === null) {
        return;
      }

      var ip1 = parseInt(components1[1]);
      var ip2 = parseInt(components1[2]);
      var ip3 = parseInt(components1[3]);
      var ip4 = parseInt(components1[4]);

      var sp1 = parseInt(components2[1]);
      var sp2 = parseInt(components2[2]);
      var sp3 = parseInt(components2[3]);
      var sp4 = parseInt(components2[4]);

      var sn1 = parseInt(subcomps[1]);
      var sn2 = parseInt(subcomps[2]);
      var sn3 = parseInt(subcomps[3]);
      var sn4 = parseInt(subcomps[4]);

      var octa1 = ip1 & sn1;
      var octa2 = ip2 & sn2;
      var octa3 = ip3 & sn3;
      var octa4 = ip4 & sn4;
      var octb1 = sp1 & sn1;
      var octb2 = sp2 & sn2;
      var octb3 = sp3 & sn3;
      var octb4 = sp4 & sn4;

      if ((octa1 == octb1) && (octa2 == octb2) && (octa3 == octb3) && (octa4 == octb4)) {
        return true;
      } else {
        return false;
      }
    };

    ctrl.$validators.networkCheck = function(modelValue) {
      return sameNetwork(modelValue, scope.otherIp, scope.netmask);
    };

    scope.$watch("ipCheck", function() {
      ctrl.$validate();
    });
  }
}
});

http://jsfiddle.net/t55fLhry/1/

1 Answer 1

1

One thing you could do is pass the form into your directive, then set a $watch and check each model's validity through the model's controller. This will allow you to update validity of all inputs anytime one of them has changes:

see this updated jsfiddle: http://jsfiddle.net/q2fLz54t/

markup

<input type="text" name="ipaddress" network-check ng-model="IPAddress" form="IPForm"/>

directive

...
scope.$watch("ngModel", function(newValue, oldValue) {
  if (newValue !== oldValue) {
    sameNetwork(scope.form.gateway, scope.form.ipaddress, scope.form.netmask);
  }
});
...
var sameNetwork = function(ipOne, ipTwo, netmask) {
  ...    
  // set validity in your checking function 
  ipOne.$setValidity('network-check', true);
  ipTwo.$setValidity('network-check', true); 
  netmask.$setValidity('network-check', true);
  ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is fantastic! Never thought of passing in the form itself. I'll have to keep this bit of info tucked away. So simple.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.