2012-12-02 12 views
11

私はこの解決策を見たhttp://jsfiddle.net/gronky/GnTDJ/それは動作します。つまり、あなたが入力25、それは0.25最新のAngularJSでパーセント形式の入力作業を行う方法は?

HTMLとしてバックモデルに押されたとき:

<script type="text/javascript" ng:autobind 
     src="http://code.angularjs.org/0.9.17/angular-0.9.17.js"></script> 
<script> 
function Main() { 
    this.var = '1.0000'; 
} 
</script> 
<div ng:controller="Main"> 
    <input type="text" name="var" ng:format="percent"> 
    <pre>var = {{var|json}}</pre> 
</div>​ 

はJavaScript:

angular.formatter('percent', { 
    parse: function(value) { 
    var m = value.match(/^(\d+)\/(\d+)/); 
    if (m != null) 
     return angular.filter.number(parseInt(m[1])/parseInt(m[2]), 2); 
    return angular.filter.number(parseFloat(value)/100, 2); 
    }, 
    format: function(value) { 
    return angular.filter.number(parseFloat(value)*100, 0); 
    }, 
}); 
​ 

私はそれが最新のAngularJSに取り組んで作ってみました、それはdoesnのhttp://jsfiddle.net/TrJcB/これはつまり、25を入力すると25にも戻されますが、正しい0.25の値がモデルにプッシュされません。

または、すでに%の組み込みフォーマッタがありますか?私は通貨フォーマッターもカンマ区切りの番号も欲しかった。

答えて

17

多くのAPIが変更されて以来、現在のAngularバージョンでは動作しません。 angular.formatterは現在使用できなくなり、いずれもangular.filterではありません。

これを書く方法は、ディレクティブを使用して、$parser$formatterをディレクティブコントローラで使用することです。だからあなたのリンク機能もフィルターが今$filterサービスを介してアクセスされ

link: function(scope, ele, attr, ctrl){ 
     ctrl.$parsers.unshift(
      function(viewValue){ 
       return $filter('number')(parseFloat(viewValue)/100, 2); 
      } 
     ); 
     ctrl.$formatters.unshift(
      function(modelValue){ 
       return $filter('number')(parseFloat(modelValue)*100, 2); 
      } 
     ); 
     } 

ようになります。 http://docs.angularjs.org/api/ng.filter:number

オリジナル例えば

更新フィドル :http://jsfiddle.net/abhaga/DdeCZ/18/

通貨フィルタは、角ですでに提供されています:http://docs.angularjs.org/api/ng.filter:currency

+0

ありがとう! 2番目の照会に関して、私は代わりに通貨の入力を探しています。つまり、入力をキー入力すると、コントロールは自動的にカンマを挿入します。おそらく私は通貨の入力を達成するためにあなたのフィドルからパーセントで始めるでしょう。どうもありがとう! – Hao

+1

他のフォーマッタ/パーサがモデルを 'undefined'にすることができます(' $ filter( 'number') 'は別のフォーマッタが尋ねると' '4,00" 'を返します) ''。 "'小数点区切り文字)を指定します。 – elbaid

+0

これは10進数ではなく文字列を返すものとしますか?どのようにして10進数を返すことができますか? –

33

割合フィルタを実装するための別の方法は、(角#と連携〜1.2あなたはここにドキュメントを見つけることができます):

angular.module('moduleName') 
.filter('percentage', ['$filter', function($filter) { 
    return function(input, decimals) { 
     return $filter('number')(input*100, decimals)+'%'; 
    }; 
}]); 

それを使用する方法:

<span>{{someNumber | percentage:2}}</span> 
2

ここでは、構文解析、フォーマット、の完全な指令があり、入力の角度検証を実行します。 (角度1.2でテストされた& 1.3)

私たちのデータモデルとサーバーとの間の乗数を10進表記(0.7634)で表現することができるようにこれを使用しますが、ユーザーには人間が判読可能な形式(76.34)最大の精度を実現します。このディレクティブは、純粋に数値的な側面に関係していることに注意してください。私はそれをここに含めるのではなく、別々にテンプレートに '%'を挿入する方が簡単だと分かります。

デフォルトでは-100〜100の入力値が適用されますが、attrs pct-minpct-maxを使用して独自の境界を指定できます。

'use strict'; 

angular.module('XLDirectives') 
    .directive('xlPercentage', function($filter) { 
    // A directive for both formatting and properly validating a percentage value. 
    // Assumes that our internal model is expressed as floats -1 to +1: .099 is 9.9% 
    // Formats display into percents 1-100, and parses user inputs down to the model. 
    // Parses user input as floats between 0 and 100 into floats less than 1. 
    // Validates user input to be within the range -100 to +100. 
    // Sets Angular $valid property accordingly on the ngModelController. 
    // If a `pct-max` or `pct-min` attribute is specified on the <input>, will use those bounds instead. 
    // If a `pct-decimals` attr present, will truncate inputs accordingly. 

    function outputFormatter(modelValue, decimals) { 
     var length = decimals || 2; 
     if (modelValue != null) { 
     return $filter('number')(parseFloat(modelValue) * 100, length); 
     } else { 
     return undefined; 
     } 
    }; 

    function inputParser(viewValue, decimals) { 
     var length = decimals || 4; 
     if (viewValue != null) { 
     return $filter('number')(parseFloat(viewValue)/100, length); 
     } else { 
     return undefined; 
     } 

    } 

    function isWithinBounds(value, upper, lower) { 
     if (value >= lower && value <= upper) { 
     return true; 
     } else { 
     return false; 
     } 
    } 

    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function postLink(scope, element, attrs, ctrl) { 
     ctrl.$parsers.unshift(function(viewValue) { 
      // confirm the input from the view contains numbers, before parsing 
      var numericStatus = viewValue.match(/(\d+)/), 
      min = parseFloat(attrs.pctMin) || -100, 
      max = parseFloat(attrs.pctMax) || 100, 
      decimals = parseFloat(attrs.pctDecimals) || 4, 
      bounded = isWithinBounds(viewValue, max, min); 
      if (numericStatus !== null && bounded) { 
      ctrl.$setValidity('percentage', true); 
      // round to max four digits after decimal 
      return inputParser(viewValue, decimals); 
      } else { 
      ctrl.$setValidity('percentage', false); 
      return undefined 
      } 
     }); 

     ctrl.$formatters.unshift(outputFormatter); 
     // we have to watch for changes, and run the formatter again afterwards 
     element.on('change', function(e) { 
      var element = e.target; 
      element.value = outputFormatter(ctrl.$modelValue, 2); 
     }); 
     } 
    }; 
    }); 


// REFS: 
// http://stackoverflow.com/questions/17344828/angularjs-should-i-use-a-filter-to-convert-integer-values-into-percentages 
// http://stackoverflow.com/questions/13668440/how-to-make-a-percent-formatted-input-work-on-latest-angularjs 
+1

注: attrs.pct-minが attrs.pctMinしなければならないと attrs.pct-maxがattrs.pctMax (ポスト編集提出)OlivierClé[email protected] –

+1

する必要があります:あなたのコメント(未遂編集)していただきありがとうございます。これらの変更のいくつかを使用して、このディレクティブをプロダクションで改善しましたが、ここでそれを更新するのを忘れました。 – XML

0

私は、##と##の入力を可能にするために、abhagaの答えを変更しました。私の意見では、これははるかにユーザーフレンドリーです

link: function(scope, element, attr, ngModel) { 
      ngModel.$parsers.unshift(
       function(viewValue){ 
        var perc = parseFloat(viewValue); 
        if (perc<0 || perc>100 || !isFinite(perc)){ 
         return null; 
        } 
        if (perc>1 && perc<=100){ 
         return parseFloat($filter('number')(perc/100)); 
        } 
        return perc; 
       } 
      ); 
      ngModel.$formatters.unshift(
       function(modelValue){ 
        if(!isFinite(modelValue)){ 
         return ""; 
        } 
        return $filter('number')(parseFloat(modelValue)*100, 2); 
       } 
      ); 
     } 
関連する問題