I have a question about custom formatters.
What I try to achieve is a currencyFormatter just for the amount with Locale sent by the server, when locale is not define or supported fall back to British English.
Something like this:
function currencyFmatter(cellvalue, options, rowdata) {
return new Intl.NumberFormat([locale, "en-GB"], {minimumFractionDigits: 2, maximumFractionDigits: 2}).format(cellvalue);
}
My problem is how to pass my variable locale to the formatter, I’m pretty sure it has to be a way to do it but right now I don’t see it.
Thanks
It's an interesting question! There are many ways to implement your requirements.
1) you can extend your input data returned from the server with additional information which specify the locale of data. For example you can returns "de-DE:10.000,04"
instead of "10.000,04"
which represent 1000.04
formatted in German locale (where ,
will be used as the decimal separator and .
used as the thousands separator). It allows you to use cellvalue.split(":")
to get array ["de-DE", "10.000,04"]
with the locale of the number and the number itself
function currencyFmatter(cellvalue, options, rowdata) {
var data;
if (typeof cellvalue === "string") {
data = cellvalue.cellvalue.split(":");
if (data.length === 2) {
return new Intl.NumberFormat([data[0], "en-GB"], {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(data[1]);
}
}
return cellvalue;
}
Alternatively you can place the information about locale of the number in separate field (for example numLocale
) of the input data and use something like rowdata.numLocale
(or rowdata[12]
depend on the input format of the JSON data) to access the locale.
2) It could be that all the data returned from the server will be in the same format. In the case it would be not the best way to prepend all numbers with the same prefix "de-DE:"
. What you can do for example is to extend the data returned from the server with additional field. For example you can use
{
"total": "12",
"page": "1",
"records": "12345",
"localOfNumbers": "de-DE",
"rows" : [
...
]
}
You can access the custom localOfNumbers
field inside of beforeProcessing
callback. It's very practical callback. It allows you to pre-process the data returned from the server before the data will be processed by jqGrid. I recommend you to read the answer and this one for more code example. What you can do for example is to save localOfNumbers
value in some new option of jqGrid (see the answer for more details). Let us you want to have an option gridLocale
for the goal. Then you can do something like the following:
beforeProcessing: function (data) {
if (typeof data.localOfNumbers === "string") {
$(this).jqGrid("setGridParam", {gridLocale: data.localOfNumbers});
}
}
To access the new gridLocale
option you can use
function currencyFmatter(cellvalue, options, rowdata) {
var locale = $(this).jqGrid("getGridParam", "gridLocale"); // this.p.gridLocale
}
3) You can consider to save the information about the locale as column property instead of usage one common gridLocale
grid option. To do this you can define the column in colModel
like below
{ name: 'col2', width: 200, formatoptions: { colLocale: "en-IN" },
formatter: function (cellvalue, options, rowdata) {
// options.colModel.formatoptions.colLocale get you the value
}
One can set the property of formatoptions.colLocale
inside of beforeProcessing
too. You can use
{
"total": "12",
"page": "1",
"records": "12345",
"localOfColumns": {
"col2": "de-DE",
"col5": "en-IN"
},
"rows" : [
...
]
}
and
beforeProcessing: function (data) {
if ($.isPlainObject(data.localOfColumns)) {
if (typeof data.localOfColumns.col2 === "string") {
$(this).jqGrid("setColProp", "col2", {
formatoptions: { colLocale: data.localOfColumns.col2 }
});
}
if (typeof data.localOfColumns.col5 === "string") {
$(this).jqGrid("setColProp", "col5", {
formatoptions: { colLocale: data.localOfColumns.col5 }
});
}
}
}
I'm sure that one can suggest even more ways to implement your requirements.