Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS decimal input: change comma to dot

Tags:

angularjs

I'm using FCSA Number to handle decimal input in AngularJS.

If I use the maxDecimals option it almost works as expected. For two decimals, inputs like "100.333" are transformed to "100.33".

In my region comma is used as decimal separator, but the input on my website should use dot as decimal separator -- like this plugin does. That's fine. However, I would like that input like "100,33" are converted to "100.33".

How can I do that?

like image 900
dhrm Avatar asked Mar 16 '15 12:03

dhrm


2 Answers

I am afraid I am unfamiliar with FCSA number :(

However, if your goal is to understand how to implement a simple, angular-oriented solution that may well suit your needs, read on... You will find below the price directive I implemented in a plunker. It is quite straightforward, and I recommend you take the time to study it, then implement your own solution, inspired by both the price directive and the FCSA source code.


  1. a filter to convert comma numbers to decimal numbers:

    app.filter('comma2decimal', [ function() { // should be altered to suit your needs     return function(input) {     var ret=(input)?input.toString().trim().replace(",","."):null;         return parseFloat(ret);     }; }]); 

This filter will automatically convert data from view format (with a comma) to model format (your scope, with a decimal).


  1. a filter to convert decimal numbers to comma numbers:

    app.filter('decimal2comma', [ function() {// should be altered to suit your needs     return function(input) {         var ret=(input)?input.toString().replace(".",","):null;         if(ret){             var decArr=ret.split(",");             if(decArr.length>1){                 var dec=decArr[1].length;                 if(dec===1){ret+="0";}             }//this is to show prices like 12,20 and not 12,2         }         return ret;     }; }]); 

This filter will automatically convert data from model format (your scope, with a decimal) to view format (your view, with a comma).


  1. a directive named price that uses those two filters:

    app.directive('price', ['$filter', function($filter) { return {     restrict:'A',     require: 'ngModel',     link: function(scope, element, attrs, ngModelController) {         ngModelController.$parsers.push(function(data) {             //convert data from view format to model format              data=$filter('comma2decimal')(data);              return data;         });          ngModelController.$formatters.push(function(data) {             //convert data from model format to view format              data=$filter('decimal2comma')(data);              return data;         });     } };}]); 

See this working plunker, showing how everything works together.

Initially, a number (e.g. coming from database) has a decimal value in controller scope ($scope.price=25.36;);

In the view, it appears like: 25,36 in the input, and 25.36, as in the database, below.

Now enter any comma number: it is automatically converted to decimal number for insertion in database.

Hoping this answers your question.


Advantage of using a directive: it is reusable, everywhere you need it on your website.

Advantage of using two filters: separation of concerns.


This approach lets users use numbers they are most used to in your views. However, the numbers entered can be altered in the background before insertion into database, so they are formatted properly.

And when you fetch prices/numbers from the database, they are automatically altered, before showing in the view in a way better suited to the reader.

If you need other options like in the FCSA Number directive, you can easily add them in your filters.

You will probably need custom functions and model validation, using ngModelCtrl.$setValidity.

like image 92
Manube Avatar answered Sep 19 '22 11:09

Manube


Add your corresponding locale:

<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-i18n/1.5.0/angular-locale_en-us.min.js"></script> 

You can check the list of available locales here: https://cdnjs.com/libraries/angular-i18n

like image 36
Sebastian Hindberg Berg Avatar answered Sep 18 '22 11:09

Sebastian Hindberg Berg