2016-06-27 112 views
12

我需要一個指令來過濾貨幣的字段,因此用戶只需鍵入並隱含小數。Angular中的Money格式化指令

需求:

  1. 格式小數字段的用戶類型 -

開始在百位的用戶類型。因此,他們可以鍵入 「4」 看 「0.04」,輸入 「42」,並看到 「0.42」,類型298023和看 「2980.23」

  • 字段必須是數字
  • 必須允許底片-
  • 允許0.00爲數字輸入
  • 理想的情況下將使用類型=「數字」,而是「類型=文本」是正常
  • 您應該能夠清除該字段爲空。
  • ng貨幣篩選器不能按原樣滿足這些要求。請參閱猛擊者的行爲以瞭解我的意思。

    我的First Plunker有`input = text'並允許負數。一個問題是,你不能輸入負數作爲第一個數字。當清除該字段時,它將返回到「0.00」,但它應該完全清除。

    app.directive('format', ['$filter', function ($filter) { 
    return { 
          require: 'ngModel', //there must be ng-model in the html 
          link: function (scope, elem, attr, ctrl) { 
           if (!ctrl) return; 
    
           ctrl.$parsers.unshift(function (viewValue, modelValue) { 
            var plainNumber = viewValue.replace(/[^-+0-9]/g,''); 
            var newVal = plainNumber.charAt(plainNumber.length-1); 
            var positive = plainNumber.charAt(0) != '-'; 
            if(isNaN(plainNumber.charAt(plainNumber.length-1))){ 
             plainNumber = plainNumber.substr(0,plainNumber.length-1) 
            } 
            //use angular internal 'number' filter 
            plainNumber = $filter('number')(plainNumber/100, 2).replace(/,/g, ''); 
            if(positive && newVal == '-'){ 
             plainNumber = '-' + plainNumber; 
            } 
            else if(!positive && newVal == '+'){ 
             plainNumber = plainNumber.substr(1); 
            } 
            plainNumber.replace('.', ','); 
    
            //update the $viewValue 
            ctrl.$setViewValue(plainNumber); 
            //reflect on the DOM element 
            ctrl.$render(); 
            //return the modified value to next parser 
            return plainNumber; 
           }); 
          } 
         }; 
    
    }]); 
    

    Second Plunkerinput = text並允許負輸入。就像第一個闖入者一樣,只有在輸入數字後,它纔會允許第一個字符爲負數。第二個是它從十分之一而不是百分之一開始。 (如果你輸入「3」,你應該看到「0.03」,但在這裏它顯示了「0.3」)

    app.directive('inputRestrictor', [function() { 
        return { 
         restrict: 'A', 
         require: 'ngModel', 
         link: function(scope, element, attr, ngModelCtrl) { 
          var pattern = /[^.0-9+-]/g; 
    
          function fromUser(text) { 
           if (!text) 
           return text; 
    
           var rep = /[+]/g; 
           var rem = /[-]/g; 
           rep.exec(text); 
           rem.exec(text); 
    
           var indexp = rep.lastIndex; 
           var indexm = rem.lastIndex; 
           text = text.replace(/[+.-]/g, ''); 
           if (indexp > 0 || indexm > 0) { 
            if (indexp > indexm) text = "+" + text; // plus sign? 
            else text = "-" + text; 
           } 
    
           var transformedInput = text.replace(pattern, ''); 
           transformedInput = transformedInput.replace(/([0-9]{1,2}$)/, ".$1") 
           ngModelCtrl.$setViewValue(transformedInput); 
           ngModelCtrl.$render(); 
           return transformedInput; 
          } 
    
          ngModelCtrl.$parsers.push(fromUser); 
         } 
        }; 
    }]); 
    

    我如何協調這些解決方案或定製一個符合要求?我想避免額外的庫或附加組件。我被告知,最好的方法是研究貨幣過濾器的來源,並重新創建具有額外要求的過濾器。我很樂意這樣做,但我現在真的沒有這方面的技能。這兩個指令是我的。

    +3

    的角度提供一個內置的貨幣過濾器:https://docs.angularjs.org/api/ng/filter/currency –

    +0

    @ SSC-hrep3該過濾器是好的,但它不符合作爲用戶類型添加小數點的要求。這是指令的目的。要明白我的意思,請輸入plunker字段,看看會發生什麼。 – jenryb

    +1

    嗨,[ng-currency](https://github.com/aguirrel/ng-currency)很有幫助。 – Maher

    回答

    7

    。::更新的答案 - 7月14日::。


    檢查這個簡單的指令:

    app.directive('price', [function() { 
        return { 
         require: 'ngModel', 
         link: function (scope, element, attrs, ngModel) { 
          attrs.$set('ngTrim', "false"); 
    
          var formatter = function(str, isNum) { 
           str = String(Number(str || 0)/(isNum?1:100)); 
           str = (str=='0'?'0.0':str).split('.'); 
           str[1] = str[1] || '0'; 
           return str[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') + '.' + (str[1].length==1?str[1]+'0':str[1]); 
          } 
          var updateView = function(val) { 
           scope.$applyAsync(function() { 
            ngModel.$setViewValue(val || ''); 
            ngModel.$render(); 
           }); 
          } 
          var parseNumber = function(val) { 
           var modelString = formatter(ngModel.$modelValue, true); 
           var sign = { 
            pos: /[+]/.test(val), 
            neg: /[-]/.test(val) 
           } 
           sign.has = sign.pos || sign.neg; 
           sign.both = sign.pos && sign.neg; 
    
           if (!val || sign.has && val.length==1 || ngModel.$modelValue && Number(val)===0) { 
            var newVal = (!val || ngModel.$modelValue && Number()===0?'':val); 
            if (ngModel.$modelValue !== newVal) 
             updateView(newVal); 
    
            return ''; 
           } 
           else { 
            var valString = String(val || ''); 
            var newSign = (sign.both && ngModel.$modelValue>=0 || !sign.both && sign.neg?'-':''); 
            var newVal = valString.replace(/[^0-9]/g,''); 
            var viewVal = newSign + formatter(angular.copy(newVal)); 
    
            if (modelString !== valString) 
             updateView(viewVal); 
    
            return (Number(newSign + newVal)/100) || 0; 
           } 
          } 
          var formatNumber = function(val) { 
           if (val) { 
            var str = String(val).split('.'); 
            str[1] = str[1] || '0'; 
            val = str[0] + '.' + (str[1].length==1?str[1]+'0':str[1]); 
           } 
           return parseNumber(val); 
          } 
    
          ngModel.$parsers.push(parseNumber); 
          ngModel.$formatters.push(formatNumber); 
         } 
        }; 
    }]); 
    

    而且使用這樣的:

    <input type="text" ng-model="number" price > 
    

    親身體驗在這個PLUNKER(7月14日)

    +0

    關閉,但這不會在兩位數後添加小數,這應該反映在視圖以及模型中。 – jenryb

    +0

    @jenryb你的意思是,你想強制小數點後2位? –

    +0

    是的。看到任何一個強盜的行爲,看看我的意思 – jenryb

    3

    我認爲這完全可以填補你的要求

    https://github.com/FCSAmerica/angular-fcsa-number 
    

    可以限制輸入,允許只數在默認情況下角輸入驗證小數或使用字符代碼。

    1

    角數字

    Angular Numeric是一個複雜的指令,它實現了一個完整的數字輸入字段。

    非常簡單易用 - 但功能強大。

    <input numeric min="-20" max="100" decimals="3" /> 
    

    上有最小和最大值檢查。當該值低於最小值 時,該值被設置爲最小值。當值超過最大值 時,該值被設置爲最大值。

    格式化在模糊事件上完成;千位分隔符和小數點 基於當前的Angular語言環境。

    可以設置小數位數。

    https://www.npmjs.com/package/angular-numeric-directive

    +0

    不完全是我在找的東西。我不想在模糊上進行格式化,而應該在用戶輸入時進行格式化。 – jenryb