Hello support,
My data contains price and currency for various objects.
In my Data Grid, the price column should be formatted as a price (C2) using the price's currency.
For example, if my data is { price: 10.20, price_currency: 'USD' }
Then the column should show : Price: $10.20
Of course this can be easily done using { format: 'C2', currency: 'USD' }
Can you help me create a column definition where the currency code comes from the datarow itself ?
Thanks in advance
Hello Rajapandi,
Thanks for your reply.
I have data which has for every row: price, quantity, currency, and product reference.
My goal is to display product ref, price (using currency), quantity (editable), total (USD), and a footer aggregation of total (USD).
<e-column
field="price"
type="number"
header-text="Price"
:allow-editing="false"
:value-accessor="currencyFormatter"
/>
...
currencyFormatter (field, data, column) {
return Number(data.price).toLocaleString(undefined, { style: 'currency', currency: `${data.currency}` })
}
This works well, but uncovered another issue: when I edit the "quantity" value, the price gets undefined in the currencyFormatter function.
<e-columnBut of course, I need to apply a currency rate to transform the price * quantity from its original currency into USD. Here comes the problem. I have an exchange rate API which works ok and returns exchange rates from input currency to output currency. The value-accessor becomes:
field="Total"
type="number"
header-text="Total Price"
:allow-editing="false"
:value-accessor="totalPrice"
:format="{format:'C2', currency: 'USD'}"
></e-column>
...totalPrice (field, data) {
return data.price * data.quantity
}
totalPrice (field, data) {
this.$axios.get(`/rates?from=${data.currency}&to=USD`)
.then((response) => {
if (response.data) {
const rate = Number(response.data)
return data.price * data.quantity * rate
}
})
}
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column column-name="Total" type="Custom" :custom-aggregate="customAggregateFn" :footer-template="footTemplate" :format="{format:'C2', currency: 'USD' }"></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
...customAggregateFn (data) { var sum = 0 const grid = document.getElementsByClassName('e-grid')[0].ej2_instances[0] grid.dataSource.filter((e) => { sum = sum + e.priceexw * e.quantity return sum }) return sum }
Here too, I need the exchange rate to be applied. But I admit I gave up at this point.
Hi there,
Thanks for the follow up.
Here is a small data set:
[
{ product_ref: t-shirt, price: 15.00, currency: USD, quantity: 2 },
{ product_ref: shoes, price: 25.00, currency: EUR, quantity: 4 },
{ product_ref: blouse, price: 4530.00, currency: YEN, quantity: 1 }
]
And this is the expected result:
The total column shows total in USD.
Total = price(currency) * quantity * rate(usd)
The exchange rates are obtained through an axios query to an API.
The only column which is editable is the quantity.
Thanks for any help,
Julien
|
queryCellInfo: function (args) { //queryCellInfo event
if (args.column.field === "price") {
args.cell.innerText = args.data.price.toLocaleString("en-US", {
style: "currency",
currency: `${args.data.currency}`, //set the currency format based on the respective datasource
});
}
}
|
|
queryCellInfo: function (args) { //queryCellInfo event
if (args.column.field === "Total") {
args.cell.innerText = "$" + args.data.price * args.data.Quantity;
}
}
actionBegin: function (args) { //actionBegin event
if (args.requestType === "beginEdit") {
args.rowData.Total = +args.row.lastElementChild.innerText.replace(/^\D+/g, "");
}
}
|
|
<template>
<div id="app">
<ejs-grid
:dataSource="data"
:allowFiltering="true"
:filterSettings="filterSettings"
:allowPaging="true"
:pageSettings="pageSettings"
:editSettings="editSettings"
:queryCellInfo="queryCellInfo"
:actionBegin="actionBegin"
:actionComplete="actionComplete"
>
<e-columns>
. . . . . . . . . . . .
. . . . . . . . . . . .
<e-column
field="Total"
:allowEditing="false"
type="number"
headerText="Total"
></e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column
field="Total"
type="Custom"
:customAggregate="customAggregateFn"
:footerTemplate="footerTemp"
></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</div>
</template>
<script>
import Vue from "vue";
import {
GridPlugin,
Page,
Edit,
Aggregate,
Filter,
} from "@syncfusion/ej2-vue-grids";
Vue.use(GridPlugin);
export default {
data() {
return {
data: [
{ id: 1, price: 10.2, Quantity: 10, currency: "USD" },
{ id: 2, price: 20.3, Quantity: 20, currency: "EUR" },
{ id: 3, price: 12.23, Quantity: 2, currency: "USD" },
],
footerTemp: function () {
return {
template: Vue.component("footerTemplate", {
template: `<span>$ {{data.Custom}}</span>`,
data() {
return { data: {} };
},
}),
};
},
};
},
methods: {
actionComplete: function (args) { //actionComplete event of Grid
if (args.requestType === "save") {
var grid = document.getElementsByClassName("e-grid")[0]
.ej2_instances[0];
grid.aggregateModule.refresh();
}
},
customAggregateFn: function (data) {
var sum = 0;
var grid = document.getElementsByClassName("e-grid")[0].ej2_instances[0];
var val = grid.dataSource.filter((e) => {
let new_val = e.price * e.Quantity;
sum = sum + new_val;
});
return sum;
},
},
provide: {
grid: [Filter, Page, Edit, Aggregate],
},
};
</script>
<style>
@import "https://cdn.syncfusion.com/ej2/material.css";
</style> |
Hello Rajapandi,
Thank you very much for this.
I still have a small requirement, is to have prices changed into USD when they are in another currency.
In your example, the id 2 is in EUR, the total should be converted into USD.
In the queryCellInfo, that would mean this change: price * quantity * rate
queryCellInfo: function (args) {
if (args.column.field === "price") {
args.cell.innerText = args.data.price.toLocaleString("en-US", {
style: "currency",
currency: `${args.data.currency}`,
});
}
if (args.column.field === "Total") {
var rate_eur_usd = getExchangeRateFromAPIUsingAxios()
args.cell.innerText = "$" + args.data.price * args.data.Quantity * rate_eur_usd;
}
},
I get the exchange rates on the fly using an external api like in the above. When I create such a solution, the Total column values are empty (not null, not zero, just empty).
Can you help again ? To get fake rate from a real api, you can try GETing a number from here : https://www.random.org/integers/?num=1&min=1&max=10&col=1&base=10&format=plain&rnd=new
Thanks in advance,
Julien
Thank you very much !
Hello there,
While this solution works great, I now must export results in Excel, but the "Total" column doesn't get exported and I get an error.
Can you help again ?
Thank you.
Julien
Btw, I think I found a bug in
@syncfusion\ej2-grids\src\grid\actions\excel-export.js (v 18.4.41) line 719
it should read
if (!isNullOrUndefined(column) && !isNullOrUndefined(style.type)) { style.type = column.type.toLowerCase();
}
|
excelQueryCellInfo: function (args) {
if (args.column.field === "Total") {
//you can perform your action here
args.value = args.data.price * args.data.Quantity;
}
}
|