Issue
I'm using this code:
Number(val).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });
to format currency on my table column. It works, but the currency symbol is not aligned, has I showing in the image below.
This is what I was hoping for:
R$ 10,00
R$ 8,00
R$ 109,00
Solution
There are a few ways of doing this, and ultimately the best way is going to depend on what component you're using to construct your grids. What I'm showing here is one way, mostly manual, since there is little information in the question.
I'm using Intl.NumberFormat directly, which is what toLocaleFormat uses behind the scenes. The reason to use it directly is to get formatToParts, which is a handy function that formats numbers to an array of parts. That way we can get the currency symbol separate from the value. I've included an example as a comment in the code.
Then it's simply a matter of wrapping the currency symbol in a separate HTML element from the value and using CSS to achieve the desired alignment. Setting the table cell's alignment to center, but setting the symbol's alignment to left and the value's alignment to right, along with set widths for both symbol and value, gets the job done.
Note that you may need to play around with the width of the .amount class depending on the values you actually get in your data.
var data = [10, 8, 109];
var table = document.querySelector('table');
var tbody = table.tBodies[0];
for (var i = 0; i < data.length; i++) {
var row = tbody.insertRow();
var cell = row.insertCell();
var datum = Number(data[i]);
var formatter = new Intl.NumberFormat('pt-BR', {
style: 'currency',
currency: 'BRL'
});
var parts = formatter.formatToParts(datum);
/*
[
{
"type": "currency",
"value": "R$"
},
{
"type": "literal",
"value": " "
},
{
"type": "integer",
"value": "10"
},
{
"type": "decimal",
"value": ","
},
{
"type": "fraction",
"value": "00"
}
]
*/
var symbol = document.createElement('span');
symbol.className = "symbol";
// Get the "currency" part's value
symbol.textContent = parts.find(p => p.type === 'currency').value;
cell.appendChild(symbol);
var amount = document.createElement('span');
amount.className = "amount";
// Get all the parts after the "currency" and the "literal"
// Note that this may need to be adjusted depending on the locale and currency used!
// Another way of doing this would be to filter parts of type "integer", "group",
// "decimal", and "fraction" (or all types except "currency" and "literal") and join
// those.
amount.textContent = parts.slice(2).map(p => p.value).join('');
cell.appendChild(amount);
row.appendChild(cell);
tbody.appendChild(row);
}
td {
min-width: 200px;
text-align: center;
border: solid;
}
.symbol {
display: inline-block;
min-width: 20px;
text-align: left;
}
.amount {
display: inline-block;
min-width: 70px;
text-align: right;
}
<table>
<tbody>
</tbody>
</table>
Answered By - Heretic Monkey

0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.