通貨のフィールドをフィルタリングするためのディレクティブが必要なので、ユーザーは入力するだけで、小数が暗示されます。
ニーズ:
ユーザーが入力すると、100分の1から開始します。したがって、「4」と入力して「0.04」と表示し、「42」と入力して「0.42」と入力し、298023と入力して「2980.23」と表示します
-
Ng-currencyフィルターは、これらの要件をそのまま満たしていません。私が何を意味するかを知るために、プランカーの振る舞いを見てください。
My First Plunker には `input = text 'があり、負の数を許可します。 1つの問題は、最初の数値として負の数値を入力できないことです。フィールドをクリアすると、「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;
});
}
};
}]);
私の セカンドプランカー はinput = text
そして負の入力を可能にします。最初のプランカーと同様に、数字を入力した後でのみ、最初の文字としてネガを使用することはできません。 2つ目は、100分の1ではなく10分の1から始まることです。 (「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);
}
};
}]);
これらのソリューションを調整したり、要件を満たすように調整したりするにはどうすればよいですか?余分なライブラリやアドオンは避けたいです。通貨フィルターのソースを調べて、追加の要件でそのフィルターを再作成するのが最善のアプローチだと言われています。これを実行したいのですが、現時点では実際にはそのスキルがありません。これらの2つのディレクティブは私が持っているものです。
この単純なディレクティブを確認してください。
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 >
このライブをご覧ください [〜#〜]プランカー[〜#〜] (7月14日)
私はこれがあなたの要件を完全に満たすことができると思います
https://github.com/FCSAmerica/angular-fcsa-number
デフォルトで小数の数値のみを許可する入力を制限できますangular入力検証またはcharコードを使用します。
Angular Numeric
Angular Numericは、完全な数値入力フィールドを実装する高度なディレクティブです。
使い方はとても簡単ですが、パワフルです。
<input numeric min="-20" max="100" decimals="3" />
最小値と最大値のチェックがあります。値が最小値を下回ると、値は最小値に設定されます。値が最大値を超えると、値が最大値に設定されます。
フォーマットはblurイベントで行われます。千の区切り文字と小数は、現在のAngularロケールに基づいています。
小数点以下の桁数を設定できます。