3

In my template I want to display the value (of type number) with commas as a decimal separator instead of dot. I have:

<p-column field="power" header="Power [MW]" [editable]="true">
  <ng-template let-col let-data="rowData" pTemplate="editor">
    <div>
      <input type="text" [(ngModel)]="data[col.field]" numbersOnly digits="35" decimals="3">
    </div>
  </ng-template>
  <ng-template let-col let-data="rowData" pTemplate="body">
    <div>
      <span>{{ data[col.field] }}</span>
    </div>
  </ng-template>
</p-column>

But this displays the numbers with dots, like "10.3" in both: editor and display mode. What I need is to display the values with comma, like "10,3". How can I do that?

Antikhippe
  • 6,316
  • 2
  • 28
  • 43
Mateusz Moroz
  • 312
  • 2
  • 6
  • 19

3 Answers3

3

I had to struggle with this with an app that received all data from SAP with numbers formatted with . instead of , as well. Here is the pipe I made to solve this, it is more overhead than adding a locale id and using the native angular decimal pipe

Here is a working stackblitz example of the pipe

/**
 * @Pipe
 * @description pipe to format numeric values to argentina readable currency values
 * @input number
 * @output formatted numeric value
 */

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ 
    name: 'numberFormat'
 })
export class NumberFormatPipe implements PipeTransform {
    transform(value: any): number {
        return this.localeString(value);
    }

    missingOneDecimalCheck(nStr) {
        nStr += '';
        const x = nStr.split(',')[1];
        if (x && x.length === 1) return true;   
        return false;
    }

    missingAllDecimalsCheck(nStr) {
        nStr += '';
        const x = nStr.split(',')[1];
        if (!x) return true;    
        return false;
    }

    localeString(nStr) {
        if (nStr === '') return ''; 
        let x, x1, x2, rgx, y1, y2;
        nStr += '';
        x = nStr.split('.');
        x1 = x[0];
        x2 = x.length > 1 ? ',' + x[1] : '';
        rgx = /(\d+)(\d{3})/;
        while (rgx.test(x1)) {
            x1 = x1.replace(rgx, '$1' + '.' + '$2');
        }

        /** If value was inputed by user, it could have many decimals(up to 7)
            so we need to reformat previous x1 results */
        if (x1.indexOf(',') !== -1) {
            y1 = x1.slice(x1.lastIndexOf(',')).replace(/\./g, '');

            y2 = x1.split(',');
            x = y2[0] +  y1;
        } else {
            x = x1 + x2;
            if (this.missingOneDecimalCheck(x)) return x += '0';
            if (this.missingAllDecimalsCheck(x)) return x += ',00';
        }

        return x;
    }
}

And use it in your template like this:

{{ data[col.field] | numberFormat }}

Or in your component

constructor(private format: NumberFormatPipe) {}
...
let result = this.format.transform(some_number);

Dont forget to import and add to module declarations:

declarations: [NumberFormatPipe]

A heads up, this pipe includes some code to check decimals as well, since for my case I got values with and without decimals and in some cases up to 7 decimals so you could use it as is or edit it for your needs... but my guess is this will point you in the right direction at least.

Lucas
  • 9,871
  • 5
  • 42
  • 52
2

You can always change the input field type to number

  <input type="number" [(ngModel)]="data[col.field]" numbersOnly digits="35" decimals="3">

it will automatically force it to only accept numbers.

Then if you don't need the up and down arrows you can use this piece of CSS to hide the arrows

input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin: 0;

}

And then you can force angular to use a specific locale setting.

app.module.ts (for swedish locale)

import localeSv from '@angular/common/locales/sv';
import localeSvExtra from '@angular/common/locales/extra/sv';
registerLocaleData(localeSv, 'sv-SE', localeSvExtra)

and now all digits are magically represented with ',' and if you bind it to your model it will be bindable to a field of number type without any problems

SebOlens
  • 519
  • 3
  • 15
-3

You can do it simply by writing one angular filter which will replace dot with a comma for you like I mentioned in my fiddle.

Note: For now I have used a static value for demo purpose. You can replace it with your original model value.

var app = angular.module('myapp',['angular.filter'])
app.controller('myController',['$scope',function($scope){
$scope.my_modal = 0;
}])
app.filter('replaceWithComma', function () {
return function (text) {
if(text != undefined) {
var str = text.toString().replace(".", ",");
return str;
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.11/angular-filter.min.js"></script>
<div ng-app="myapp" ng-controller="myController">
<p-column field="power" header="Power [MW]" [editable]="true">
  <ng-template let-col let-data="rowData" pTemplate="editor">
    <div>
      <input type="text" ng-model="my_modal" numbersOnly digits="35" decimals="3">
    </div>
  </ng-template>
  <ng-template let-col let-data="rowData" pTemplate="body">
    <div>
      <span>{{ my_modal | replaceWithComma }}</span>
      <br>Also check with static value:<br>
      <span>{{ 10.30 | replaceWithComma }}</span>
    </div>
  </ng-template>
</p-column>
</div>