J'essaie de créer un masque de saisie pour un champ monétaire européen à l'aide de http://jquerypriceformat.com/
Jusqu'ici dans ma directive, l'entrée montre correctement à l'utilisateur avec le masque appliqué, mais je pense qu'il y a un problème, car les valeurs POST sont envoyées avec un formatage étrange, totalement différent de ce que nous voyons dans le champ d'entrée .
J'inclus le priceformat.js
<script src="js/jquery.price_format.1.8.min.js"></script>
<input type="text" currency-input ng-model...>
Et sur angulaire:
app.directive('currencyInput', function() {
return {
require: '?ngModel',
link: function($scope, element, attrs, controller) {
element.priceFormat({
prefix: '',
centsSeparator: ',',
thousandsSeparator: '.'
});
}
};
});
Mon entrée montre correctement la valeur avec le masque, mais sur les données POST (appelées par angulaire), c'est une valeur différente, que me manque-t-il?
entrée> 2.200,80 | poste> 22 0080
Merci
Из вашего примера я не вижу, что ссылка возвращает что-то.
Бы написал директиву что-то вроде:
.directive('format', ['$filter', function ($filter) {
return {
require: '?ngModel',
link: function (scope, elem, attrs, ctrl) {
if (!ctrl) return;
ctrl.$formatters.unshift(function (a) {
return $filter(attrs.format)(ctrl.$modelValue)
});
ctrl.$parsers.unshift(function (viewValue) {
elem.priceFormat({
prefix: '',
centsSeparator: ',',
thousandsSeparator: '.'
});
return elem[0].value;
});
}
};
}]);
Демо 1 Fiddle
Сли вы хотите при запуске запустить фильтр, используйте $formatters
:
Теперь link
:
link: function (scope, elem, attrs, ctrl) {
if (!ctrl) return;
var format = {
prefix: '',
centsSeparator: ',',
thousandsSeparator: ''
};
ctrl.$parsers.unshift(function (value) {
elem.priceFormat(format);
return elem[0].value;
});
ctrl.$formatters.unshift(function (value) {
elem[0].value = ctrl.$modelValue * 100 ;
elem.priceFormat(format);
return elem[0].value;
})
}
Демо 2 Fiddle
Poussez un $parser
sur le contrôleur et mettez à jour la valeur uniquement si elle ne correspond pas à l'entrée à l'aide de $setViewValue()
et $render()
.
app.directive('currencyInput', function() {
return {
require: '?ngModel',
link: function($scope, element, attrs, controller) {
return ctrl.$parsers.Push(function(inputValue) {
...
if (result != inputValue) {
controller.$setViewValue(res);
controller.$render();
}
});
}
};
});
Voici un tour de passe-passe avec la logique que j'ai utilisée pour ma directive de saisie monétaire: Fiddle
En retard pour la fête, mais je crois que cela mérite une autre réponse! J'utilise le module ng-currency . C'est absolument fantastique.
J'aime l'approche de Dubilla pour sa simplicité et son élégance. J'ai décidé d'ajouter (avec les crédits dus) quelques fonctionnalités en plus pour le rendre assez proche du cas d'utilisation réel.
Je l’utilise sur un projet github pour créer des directives financières utiles github .
Caractéristiques supplémentaires notables:
Il utilise également un POJO comme ngmodel:
function Money() {
this.notional = 0;
this.maxValue = 99999999999.9;
this.maxValueString = "99,999,999,999.9";
this.maxPrecision = 10;
}
vous pouvez l'utiliser avec Bootstrap 3 comme ceci:
<h1>Currency Formatting directive</h1>
<div class="row">
<div class="col-md-6">
<form name="myForm">
<div class="form-group" ng-class="{'has-error': myForm.notional.$invalid && myForm.notional.$touched}">
<input type="text" ng-model="myForm.money.notional " money="money" money-input size="30" required
name="notional"
class="form-control"
placeholder="Enter notional amount"/>
<p class="help-block error" ng-show="myForm.notional.$error.required && myForm.notional.$touched">Required</p>
</div>
<button ng-disabled="myForm.$invalid" type="submit">SAVE</button>
</form>
<h2>Tips</h2>
<ol>
<li> Entering 'k' will multiply the amount by one thousand</li>
<li> Entering 'm' will multiply the amount by one million</li>
<li> Entering 'b' will multiply the amount by one billion</li>
</ol>
</div>
</div>
<p>Form debugger</p>
<pre>
form = {{ myForm | json }}
</pre>
Voici un moyen de gérer cela sans jQuery en utilisant uniquement une directive angulaire. Cet exemple ne supporte pas les décimales. Il est facile de le modifier pour supporter cela, il suffit de changer le $filter
dans la fonction toView()
.
À mon avis, il s'agit d'une meilleure approche pour résoudre le même problème, car vous pouvez éviter le chargement dans jQuery et dans le plug-in de devises mentionné par l'auteur. La prise en charge des paramètres régionaux pour Euro devrait être prise en charge par l’utilisation des propriétés $locale
, mais je l’ai seulement testée pour une utilisation en USD.
(function() {
var app = angular.module('currencyMask', []);
// Controller
app.controller('ctrl', ['$scope', function($scope) {
$scope.amount = 100000;
}]);
// Directive
app.directive('inputCurrency', ['$locale', '$filter', function($locale, $filter) {
// For input validation
var isValid = function(val) {
return angular.isNumber(val) && !isNaN(val);
};
// Helper for creating RegExp's
var toRegExp = function(val) {
var escaped = val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return new RegExp(escaped, 'g');
};
// Saved to your $scope/model
var toModel = function(val) {
// Locale currency support
var decimal = toRegExp($locale.NUMBER_FORMATS.DECIMAL_SEP);
var group = toRegExp($locale.NUMBER_FORMATS.GROUP_SEP);
var currency = toRegExp($locale.NUMBER_FORMATS.CURRENCY_SYM);
// Strip currency related characters from string
val = val.replace(decimal, '').replace(group, '').replace(currency, '').trim();
return parseInt(val, 10);
};
// Displayed in the input to users
var toView = function(val) {
return $filter('currency')(val, '$', 0);
};
// Link to DOM
var link = function($scope, $element, $attrs, $ngModel) {
$ngModel.$formatters.Push(toView);
$ngModel.$parsers.Push(toModel);
$ngModel.$validators.currency = isValid;
$element.on('keyup', function() {
$ngModel.$viewValue = toView($ngModel.$modelValue);
$ngModel.$render();
});
};
return {
restrict: 'A',
require: 'ngModel',
link: link
};
}]);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<div ng-app="currencyMask" ng-controller="ctrl">
<input input-currency ng-model="amount">
<p><strong>Amount:</strong> {{ amount }}</p>
</div>