Angular, champ d'entrée avec une directive de masque de devise pour le format de monnaie à la volée
j'essaie de créer un masque d'entrée pour un champ de monnaie de L'UE en utilisant http://jquerypriceformat.com/
Jusqu'à présent dans ma directive, l'entrée se montre correctement à l'utilisateur avec le masque appliqué, mais je crois qu'il y a quelque chose qui ne va pas, parce que les valeurs de POST sont envoyées avec un formatage bizarre, totalement différent de ce que nous voyons dans le champ d'entrée.
- je inclure 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: '.'
});
}
};
});
<!-- 2 - input montre la valeur avec le masque correctement, mais sur les données POST (appelé par angular) c'est une valeur différente, qu'est-ce que je manque?
entrée > 2.200,80 | post > 22,0080
Merci
5 réponses
de votre exemple Je ne vois pas que le lien renvoie quelque chose.
je voudrais écrire directive quelque chose comme:
.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;
});
}
};
}]);
Démo 1 Tripoter
Si vous voulez sur le début de l'incendie du filtre, utilisez $formatters
:
link
est:
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;
})
}
Démo 2 Tripoter
appuyer sur $parser
au controller, et ne mettre à jour la valeur que si elle ne correspond pas à l'entrée en utilisant $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 la logique que j'ai utilisée pour ma directive d'entrée de devises:Tripoter
Fin de la partie, mais je crois que cela mérite une autre réponse! J'ai été en utilisant le ng-devise module. C'est absolument fantastique.
J'aime L'approche de Dubilla à cause de sa simplicité et de son élégance. J'ai décidé d'ajouter (en crédits) certaines fonctionnalités sur lui pour le rendre assez proche du monde réel de cas d'utilisation.
Je l'ai utilisé sur un projet github pour créer quelques directives financières utiles github.
Notable supplémentaire caractéristiques:
- il effectue une vérification rigoureuse des entrées pour donner une réponse valide.
- il y a des raccourcis clavier à faire entrée de grands nombres plus rapide.
- je montre comment l'intégrer aux mises à jour CSS de bootstrap et ngmodel.
- en bonus, j'ai sorti le ngmonel du formulaire comme JSON pour aider les gens à voir comment la validation du formulaire fonctionne en temps réel
function Money() {
this.notional = 0;
this.maxValue = 99999999999.9;
this.maxValueString = "99,999,999,999.9";
this.maxPrecision = 10;
}
<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 une façon de gérer cela sans jQuery en utilisant seulement une directive angulaire. Cet exemple ne supporte pas les décimales. Il est facile de le modifier pour le supporter, il suffit de changer le $filter
dans le toView()
fonction.
à mon avis, c'est une meilleure approche pour résoudre le même problème, car vous pouvez éviter de charger dans jQuery et le plugin monnaie mentionné par l'auteur. La prise en charge Locale de L'Euro doit être supportée par l'utilisation de $locale
propriétés, mais j'ai seulement testé ceci 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>