Reputation: 1
this is my first question on the website so i hope i will do it well. I try to use the edit mode of MUI datagrid but i'm stuck since a few days on a problem that seems pretty simple :
I would like to update a total that is not on the datagrid to display it to the user but i can't update it correctly when i edit a cell :
import {
DataGrid,
GridColDef,
GridCellParams,
gridClasses,
useGridApiRef, MuiEvent
} from "@mui/x-data-grid";
import {Box} from "@mui/material";
import * as React from "react";
import {DetailCommande, Ligne} from "../../../../app/models/commande";
import {useState} from "react";
type row = {
id: number,
reference: string | null,
qte: number,
qteLivree: number,
designation: string,
prixUnitaire: number,
}
const TableauValidationBL = ({commande}: { commande: DetailCommande }) => {
const apiRef = useGridApiRef()
const columns: GridColDef[] = [
{field: 'reference', headerName: 'Référence', width: 120, headerClassName: 'header'},
{field: 'designation', headerName: 'Désignation', flex: 1, headerClassName: 'header'},
{
field: 'qteLivree',
headerName: 'Qté validé',
width: 120,
headerClassName: 'header',
editable: true,
type: 'number'
},
{field: 'prixUnitaire', headerName: 'Prix Unitaire', width: 120, headerClassName: 'header'},
{
field: 'prixTotal', headerName: 'Prix Total', width: 120, headerClassName: 'header',
valueGetter: (value, row) => {
return (row.prixUnitaire * row.qteLivree).toFixed(3);
}
},
];
const rows = commande ? commande.lignes.map((ligne: Ligne) => {
return {
id: ligne.idPackaging,
reference: ligne.refFournisseur,
qte: ligne.qteCmd,
qteLivree: ligne.qteCmd,
designation: ligne.nomArticle,
prixUnitaire: ligne.prixUnitaire,
}
}
)
: [];
const [total, setTotal] = useState(rows.reduce((acc, row) => acc + row.prixUnitaire * row.qteLivree, 0));
return (
<Box
sx={{
'.header': {backgroundColor: 'lightgrey', fontSize: '1.2em'},
[`.${gridClasses.cell}.changed`]: {
backgroundColor: '#76CDCD',
},
[`.${gridClasses.cell}.unchanged`]: {
backgroundColor: '#7AA95C',
},
}}
>
<p>{total}</p>
<DataGrid
autoHeight
hideFooter
getRowHeight={() => 'auto'}
rows={rows}
columns={columns}
apiRef={apiRef}
showCellVerticalBorder
getCellClassName={(params: GridCellParams) => {
if (params.field === 'qteLivree' && params.value !== params.row.qte) {
return 'changed';
}
if (params.field === 'qteLivree' && params.value === params.row.qte) {
return 'unchanged';
}
return '';
}}
// checkboxSelection
/>
</Box>
);
};
export default TableauValidationBL;
What i try to do is make possible to the user to changed the actual quantity of a delivery, and update the total. The total for each individual row work when i'm editing.
I'm pretty sure i'm doing wrong already by the way i get the total at first, but it work this way. But when i edit a cell, i don't know how i can get the total to update.
I already tried to use onCellEditStop but i don't get the last value. I tried aswell with processRowUpdate : it work when i update one row, but if i update an other one, the first row i updated go back to the initial value.
help for you :
Hope you can help me and sorry for the french name of the values.
Upvotes: 0
Views: 187
Reputation: 6163
You can hook into the processRowUpdate callback which will allow you to access the updated object. You can then loop through your rows
data and update the object which the user has changed, then update the total
state.
You will first of all need to move your rows
into a useState
:
const [rows, setRows] = useState([
{
id: 1,
reference: 'Item 1',
qteLivree: 3,
prixUnitaire: 10,
prixTotal: 1,
},
{
id: 2,
reference: 'Item 2',
qteLivree: 2,
prixUnitaire: 5,
prixTotal: 1,
},
{
id: 3,
reference: 'Item 3',
qteLivree: 4,
prixUnitaire: 20,
prixTotal: 1,
},
]);
Then you can modify your <DataGrid>
to add the processRowUpdate
callback:
<DataGrid
rows={rows}
columns={columns}
...
processRowUpdate={editFinished}
/>
Then implement the function as follows:
const editFinished = (updatedRow, originalRow) => {
const rowId = updatedRow.id;
for (let i = 0; i < rows.length; i++) {
if (rows[i].id === rowId) {
rows[i].qteLivree = updatedRow.qteLivree;
}
}
setTotal(
rows.reduce((acc, row) => acc + row.prixUnitaire * row.qteLivree, 0)
);
return updatedRow;
};
For some reason this function must return the row with the id
property in it, otherwise it will throw an error (which can be caught by the onProcessRowUpdateError
callback if you choose to implement it).
Now, when you edit the value of a cell in the Qté validé
column, it will update the total above the data grid. See this StackBlitz for a working demo.
Upvotes: 0