We’re passing objects into our table data, of the format:
{
quantity: 20,
stock: {
shortName: 'TSLA',
currency: 'USD',
price: 34.7,
}
},
The columns will be:
- stock.shortName
- quantity
- value
We need to calculate the value using the following formula:
stock.currency + " " + (stock.price * quantity)
EUR 43.10
The table will render something like this:
What would be the best way to do this?
I see there are:
Formulas don’t seem to give us access to the cell object’s content.
I know renderers are powerful - is it possible / performant to get the data for the row in each renderer? I created a test renderer and see it can fire up to as many times as there are cells in the table.
Callbacks look like another option - but we would probably need to pre-calculate the value for all cells when adding data to a table, and then use the same function when we update cells.
Here’s a fiddle if it’s easier to demonstrate:
So just looking for advice on the best approach.
Thank you.
I think that there are a couple of approaches that you can take
- Make value as
ROUND(B1 * 4.31, 2, false)
and add EUR
inside a renderer
- Attach a function that does it using
Math
but as long as it works for you and doesn’t lower the performance it is a good choice.
Hi Aleksandra,
The problem we face is that 4.31
(price) and EUR
(currency) are both sub-properties of the stock
Is it possible to reference them in a formula?
Also - you mention “Attach a function that does it using Math”. Can you elaborate?
In either case, we would need to reference the sub-properties from the stock
object.
OK, I came up with this:
import numbro from 'numbro'
const symbols = {
EUR: '€',
USD: '$',
GBP: '£',
YEN: '¥',
}
export default function (instance, td, row, col, prop, values, cellProperties) {
const data = instance.getSourceData()
const datum = data[row]
const quantity = datum.quantity
const stock = datum.stock
const price = stock.price
if (quantity && price) {
const currency = stock.currency
const symbol = symbols[currency] || currency
const text = numbro(quantity * price).format({
thousandSeparated: true,
mantissa: 2
})
td.className = 'htValue'
td.innerHTML = `<span class="symbol">${symbol}</span><span class="value">${text}</span>`
}
}
The key was getSourceData()
.
It looks great too:
The only down side is that each time any cell changes, it will run as many times as there are cells in a column, or cells in a table.
It would be cool if we could optimise this, as we may end up with tables that are 1000+ rows.
Any suggestions?
we’re working on eco-renderers that will run only when cells get changed. Here’s a link to follow EcoRenderers feature · Issue #5769 · handsontable/handsontable · GitHub
Currently whatever change you make or add metadata you get extra calls.But… I like your approach.
1 Like