Material Ui Editable Grid

0 views
Skip to first unread message

Do Kieu

unread,
Aug 5, 2024, 2:06:15 AM8/5/24
to quiproffitri
Thedata grid is not only a data visualization tool. It offers built-in editing features for you to manage your data set.The following demo shows a full-featured CRUD (Create, Read, Update, Delete) typically found in enterprise applications.

To enable this behavior, set the editMode prop on the Data Grid to "row". Note that you still need to set the editable property in each column definition to specify which of them are editable; the same basic rules for cell editing also apply to row editing.


By design, when changing the value of a cell all preProcessEditCellProps callbacks from other columns are also called.This lets you apply conditional validation where the value of a cell impacts the validation status of another cell in the same row.If you only want to run validation when the value has changed, check if the hasChanged param is true.


The interactions that start and stop trigger 'cellEditStart' and 'cellEditStop' events, respectively.For row editing, the events are 'rowEditStart' and 'rowEditStop'.You can control how these events are handled to customize editing behavior.


The following demo shows how to prevent the user from exiting edit mode when clicking outside of a cell.To do this, the onCellEditStop prop is used to check if the reason is 'cellFocusOut'.If that condition is true, it disables the default event behavior.In this context, the user can only stop editing a cell by pressing Enter, Escape or Tab.


The editable property controls which cells are editable at the column level.You can use the isCellEditable callback prop to define which individual cells the user can edit in a given row.It is called with a GridCellParams object and must return true if the cell is editable, or false if not.


When the user performs an action to stop editing, the processRowUpdate callback is triggered.Use it to send the new values to the server and save them into a database or other storage method.The callback is called with two arguments:


If you want to delete a row from the internal state of the Data Grid, you can return an additional property _action: 'delete' in the row object from the processRowUpdate callback. This will remove the row from the internal state of the Data Grid.It is a more performant way to delete a row as compared to updating the rows prop or using setRows API method because processRowUpdate uses the updateRows under the hood which doesn't cause a full regeneration of the row tree.


In the example above, shouldDeleteRow is a function that determines whether a row should be deleted based on the updated row data.If shouldDeleteRow returns true, the row will be deleted from the Data Grid's internal state.


The following demo implements the first option: rejecting the promise.Instead of validating while typing, it simulates validation on the server.If the new name is empty, the promise responsible for saving the row will be rejected, and the cell will remain in edit mode.


The following demo shows how this approach can be used to ask for confirmation before sending the data to the server.If the user accepts the change, the internal state is updated with the values.But if the changes are rejected, the internal state remains unchanged, and the cell is reverted back to its original value.The demo also employs validation to prevent entering an empty name.


You can use the valueSetter property of the column definition to customize how the row is updated with a new value.This lets you insert a value from a nested object.It is called with an object containing the new cell value to be saved as well as the row that the cell belongs to.If you are already using a valueGetter to extract the value from a nested object, then the valueSetter will probably also be necessary.


In the following demo, both the valueParser and the valueSetter are defined for the Full name column.The valueParser capitalizes the value entered, and the valueSetter splits the value and saves it correctly into the row model:


If the column definition sets a callback for the preProcessEditCellProps property, then it will be called each time a new value is entered into a cell from this column.This property lets you pre-process the props that are passed to the edit component.The preProcessEditCellProps callback is called with an object containing the following attributes:


Data validation is one type of pre-processing that can be done in this way.To validate the data entered, pass a callback to preProcessEditCellProps checking if props.value is valid.If the new value is invalid, set props.error to a truthy value and return the modified props, as shown in the example below.When the user tries to save the updated value, the change will be rejected if the error attribute is truthy (invalid).


The demo below contains an example of server-side data validation.In this case, the callback returns a promise that resolves to the modified props.Note that the value passed to props.error is passed directly to the edit component as the error prop.While the promise is not resolved, the edit component will receive an isProcessingProps prop with value equal to true.


The cellModesModel prop accepts an object containing the mode (and additional options) for a given column field, in a given row, as in the following example.The options accepted are the same available in apiRef.current.startCellEditMode and apiRef.current.stopCellEditMode.


The options passed to both model props only take effect when mode changes.Updating the params of a cell or row, but keeping the same mode, makes the cell or row to stay in the same mode.Also, removing one field or row ID from the object will not cause the missing cell or row to go to "view" mode.


Each of the built-in column types provides a component to edit the value of the cells.To customize column types, or override the existing components, you can provide a new edit component through the renderEditCell property in the column definition.This property works like the renderCell property, with the difference that it is rendered while cells are in edit mode.


The renderEditCell property receives all params from GridRenderEditCellParams, which extends GridCellParams.Additionally, the props added during pre-processing are also available in the params.These are the most important params to consider:


Once a new value is entered into the input, it must be sent to the data grid.To do this, pass the row ID, the column field, and the new cell value to a call to apiRef.current.setEditCellValue.The new value will be parsed and validated, and the value prop will reflect the changes in the next render.


It's important to also handle the accessibility of custom edit components.When a cell enters edit mode, an element must be focused to provide access via keyboard and for screen readers.Since multiple cells may be in edit mode at the same time, the hasFocus prop will be true on the cell that should have focus.Use this prop to focus the appropriate element.


By default, each call to apiRef.current.setEditCellValue triggers a new render.If the edit component requires the user to type a new value, re-rendering the data grid too often will drastically reduce performance.One way to avoid this is to debounce the API calls.You can use apiRef.current.setEditCellValue to handle debouncing by setting the debounceMs param to a positive integer that defines a set time period in milliseconds.No matter how many times the API method is called, the data grid will only be re-rendered after that period of time has passed.


When the data grid is only set to re-render after a given period of time has passed, the value prop will not be updated on each apiRef.current.setEditCellValue call.To avoid a frozen UI, the edit component can keep the current value in an internal state and sync it once value changes.Modify the edit component to enable this feature:


An edit component has "auto-stop" behavior when it stops edit mode as soon as the value is changed.To picture better, imagine an edit component with a combo, created following the normal steps.By default, it would require two clicks to change the value of the cell: one click inside the cell to select a new value, and another click outside the cell to save.This second click can be avoided if the first click also stops the edit mode.To create an edit component with auto-stop, call apiRef.current.stopCellEditMode after setting the new value.Since apiRef.current.setEditCellValue may do additional processing, you must wait for it to resolve before stopping the edit mode.Also, it is a good practice to check if apiRef.current.setEditCellValue has returned true.It will be false if preProcessEditProps set an error during validation.


Avoid using edit components with auto-stop in columns that use long-running preProcessEditCellProps because the UI will freeze while waiting for apiRef.current.setEditCellValue.Instead, use the provided interactions to exit edit mode.


Consider an example below. Is it possible to make the angular material data table with inline editing feature? Or making cells under specific columns as editable on load itself (see the image below where Email column fields are editable). If so could you share the sample code?


This is actually an open issue in Angular Material: Table: Add inline editing for inputs. Unfortunately, it's currently not implemented, but you can find some ideas for solutions in the comments to that issue.


I find inline edit risky as there can be numerous alternate scenarios you need to handle if the user starts triggering multiple row updates and the design would start wobbling due to the inline fields. Alternatively, I have designed a table which will focus on one row at a time using a drawer because using dialogs for your form will detach the form and the table and logically the form should be a part of the table. So, its better not to use dialogs for preserving context.


Hi

I have read a number of posts about editing tables in perspective, tried them all, and all failed. These posts were from over a year ago.

Has there been changes to perspective in the last year?

The most common error message is:

Error running action 'component.onEditCellCommit' on F3 Views/F3_1@D/root/root/materials container/Table: Traceback (most recent call last): File "function:runAction", line 4, in runAction TypeError: 'com.inductiveautomation.ignition.gateway.datasource.BasicStreamingDataset' object is unsubscriptable

3a8082e126
Reply all
Reply to author
Forward
0 new messages