angular.js number-input

علی ذوالفقار
1399/09/23 10:46:23 (860)
// usage :   <input type='text' number-input ng-model="myModel">
app.directive('numberInput', function($filter) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModelCtrl) {
  
        ngModelCtrl.$formatters.push(function(modelValue) {
          return setDisplayNumber(modelValue, true);
        });
  
        ngModelCtrl.$parsers.push(function(viewValue) {
          setDisplayNumber(viewValue);
          return setModelNumber(viewValue);
        });
  
        elem.bind('keyup focus', function() {
          setDisplayNumber(elem.val());
        });
  
        function setDisplayNumber(val, formatter) {
            var valStr, displayValue;
    
            if (typeof val === 'undefined') {
              return 0;
            }
    
            valStr = val.toString();
            displayValue = valStr.replace(/,/g, '').replace(/[A-Za-z]/g, '');
            displayValue = parseFloat(displayValue);
            displayValue = (!isNaN(displayValue)) ? displayValue.toString() : '';
    
            // handle leading character -/0
            if (valStr.length === 1 && valStr[0] === '-') {
              displayValue = valStr[0];
            } else if (valStr.length === 1 && valStr[0] === '0') {
              displayValue = '';
            } else {
              displayValue = $filter('number')(displayValue);
            }
    
            // handle decimal
            if (!attrs.integer) {
              if (displayValue.indexOf('.') === -1) {
                if (valStr.slice(-1) === '.') {
                  displayValue += '.';
                } else if (valStr.slice(-2) === '.0') {
                  displayValue += '.0';
                } else if (valStr.slice(-3) === '.00') {
                  displayValue += '.00';
                }
              } // handle last character 0 after decimal and another number
              else {
                if (valStr.slice(-1) === '0') {
                  displayValue += '0';
                }
              }
            }
    
            if (attrs.positive && displayValue[0] === '-') {
              displayValue = displayValue.substring(1);
            }
    
            if (typeof formatter !== 'undefined') {
              return (displayValue === '') ? 0 : displayValue;
            } else {
              elem.val((displayValue === '0') ? '' : displayValue);
            }
          }

          function setModelNumber(val) {
            var modelNum = val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, '');
            modelNum = parseFloat(modelNum);
            modelNum = (!isNaN(modelNum)) ? modelNum : 0;
            if (modelNum.toString().indexOf('.') !== -1) {
              modelNum = Math.round((modelNum + 0.00001) * 1000) / 1000;
            }
            if (attrs.positive) {
              modelNum = Math.abs(modelNum);
            }
            return modelNum;
          }
        
        function _setDisplayNumber(val, formatter) { // old function 
            if (typeof val === 'undefined'){                
                return 0; // default is 0 
            } 
            
            var arrValue = val.toString().split('.');// get value and split in tow part ___.__ , fixPart and decimalPart 
            // max 16 digit 
            arrValue[0] = arrValue[0].toString().replace(/,/g, '').replace(/[A-Za-z]/g, '');// remove "," and characters from data 
            if(arrValue[0].toString().length > 16 ){
                alert('max 16 digit')
                arrValue[0] = 0 ; //  arrValue[0].toString().substring(0,16);
            } 
            arrValue[0] = parseInt(arrValue[0].toString().replace(/,/g, '').replace(/[A-Za-z]/g, ''));// convert to number 
            if(isNaN(arrValue[0])) arrValue[0] = 0 ; // if not a number , then it is 0 

            if(arrValue[1]) {
                arrValue[1] = parseInt(arrValue[1].toString().replace(/,/g, '').replace(/[A-Za-z]/g, '')); // do the same do decimal-part
            }

            if(arrValue.length>1){ // if there is a decimal part , format fix part and attach to decimal part with a dot 
                elem.val(arrValue[0].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + '.' + arrValue[1]);
            }else{ // just format fix part 
              elem.val(arrValue[0].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
            }
        }
  
        function _setModelNumber(val) { // old function 
          // if(val.length==2 and '01') return 1 ; // if it is 01 , then show it as 1           
          // var rv = parseFloat(val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, '')); // remove "," and characters
          return (isNaN(parseFloat(val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, '')))) ? 0 : parseFloat(val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, ''));           
        }
      }
    };
  });
  
Back