Мне нужна директива для фильтрации поля для валюты, поэтому пользователю просто нужно ввести тип и указать десятичное значение.
Потребности:
- Форматировать десятичное поле как пользовательские типы -
Начните с сотых по количеству пользователей. Поэтому они набирают "4" и видят "0.04", типа "42" и см. "0,42", тип 298023 и см. "2980.23"
- Поле должно быть числом
- Должен разрешить негативы
-
- Разрешить 0.00 как числовой ввод
- Идеально использовать type = "number", но "type = text" в порядке
- Вы должны очистить поле пустым.
Фильтр ng-валюты не выполняет эти требования как есть. Пожалуйста, см. Поведение в plunkers, чтобы понять, что я имею в виду.
My Первый 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;
});
}
};
}]);
Мой Второй плункер имеет input = 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);
}
};
}]);
Как я могу примирить эти решения или адаптировать их для удовлетворения требований? Я хочу избежать дополнительных библиотек или надстроек. Мне сказали, что наилучшим подходом будет изучение источника для фильтра валюты и воссоздание этого фильтра с дополнительными требованиями. Я бы с удовольствием это сделал, но у меня действительно нет навыков для этого прямо сейчас. Эти две директивы - это то, что у меня есть.