Ip Address mask for AngularJS

z_inx picture z_inx · Jun 10, 2013 · Viewed 16.1k times · Source

Does Anyone know a ip address mask plugin for AngularJS?

Because I tried to use the "Jquery Input IP Address Control", but it's not working. When I try to use it, the "ngModel" attribute doesn't get the value of the textfield. In the screen I can see the value inside the textfield, however, if I do ".value()" in the element, it return a "" value. The same thing occur when I see the value of the $scope element by using console.log().

Can anyone help me?

Thanks!

Edit: SOLVED

People, problem solved.

I used this directive available in http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController:

app.directive('contenteditable', function() {
    return {
        restrict: 'A', // only activate on element attribute
        require: '?ngModel', // get a hold of NgModelController
        link: function(scope, element, attrs, ngModel) {
            if(!ngModel) return; // do nothing if no ng-model

            // Specify how UI should be updated
            ngModel.$render = function() {
            element.html(ngModel.$viewValue || '');
           };

           // Listen for change events to enable binding
           element.bind('blur keyup change', function() {
           scope.$apply(read);
           });
           read(); // initialize

           // Write data to the model
           function read() {
            ngModel.$setViewValue(element.val());
           };
       }
    };
});

After I used this directive, the Jquery Plugin worked fine. Probably because now the ngNodel is getting the element.val(). Before, I think it was getting the element.text().

Answer

vittore picture vittore · Jun 10, 2013

I'm just wondering why you need this in the first place. What about just using [ngPattern][1] directive and placeholder attribute ?

 <div ng-app='app' ng-controller='myCtrl' ng-form='myForm'>
   <input type='text' ng-model='ip' 
          ng-pattern='/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/' 
          placeholder='xxx.xxx.xxx.xxx'  />
   value : {{ ip }}    
 </div>

Several notes:

  • commenters adding ^ and $ quantifiers to the regex. You don't need to do that since angular adding them for you inside ng-pattern directive (see angular.js source code for ng-pattern)

  • I do not belive that regex is good match for checking if each number is in [0,255] range. What I would rather do is implement ng-ipaddress directive, working with ngModelController directly. (see js-fiddle or github link)

    var app = angular.module('app',[])
    
    .directive('ipAddress', function ipAddress(){
    
      return {
        restrict:'A',
        require:'?ngModel',
        link: function(scope, elm, attr, ctrl){         
          if (!ctrl) return;        
          ctrl.$parsers.push(function(viewValue){
            if (!viewValue) return null;          
            var isvalid = isValidIp(viewValue)          
            return isvalid ? viewValue : null;                   
          })
        }          
      }
    
      function isValidIp(value){
           var arr = value.split('.')
           var r = /^\d{1,3}$/;
           return arr.length === 4 && arr.map(function(e){
            return ( r.test(e) && ((e|0) >= 0) && ( (e | 0) <= 255))            
           }).every(function(e){ return e })                 
      }   
    })
    

jsfiddle github