7

I want to implement a AG grid table with a name, type columns. I want to add one more column "edit" in the table, and allow users to edit&delete the rows from the table. It will look like this:

enter image description here

I get my data from the redux store, this is the way I implement data inside rows.

const members = useSelector(state => state.members) // Get current members 
const data = {
  columnDefs : [
{headerName: 'Name', field: 'name'}, 
{headerName: 'Type', field: 'type'},
{headerName: 'Edit', field: 'edit'}
],
  rowData: []
}

members.map((member) => {
  data.rowData.push({
    name:member.name,
    type:member.type,
    edit: '' // ?? What comes here so I can delete & edit by rows easily with buttons ?? 
  })
})

return ( 
    <div> 
    <div className="ag-theme-material">
        <AgGridReact columnDefs={data.columnDefs} rowData={data.rowData} />            
    </div>
</div>

)

I am new to react-redux, what would be the best implementation? Is it even okay for me to get data inside the table with map function like above? Any suggestions would be appreciated.

mr_nocoding
  • 472
  • 7
  • 16

1 Answers1

3

Apporach 1: Use editing dialog

You can make the edit button open an editing dialog and dispatch the new change to the store after the user closes it:

  • Create a custom cell renderer for the button and dialog. In this example, I'll use Material-UI's Dialog. You can choose whatever dialog library you want however.
function ButtonActionRenderer(props) {
  // props is ICellRenererParams. See:
  // https://www.ag-grid.com/react-grid/component-cell-renderer/#cell-renderer-component-2
  const { id } = props.data;
  const [open, setOpen] = useState(false);
  const [memberPayload, setMemberPayload] = useState(props.data);
  const dispatch = useDispatch();
  const onClose = () => setOpen(false);
  const onSave = () => {
    dispatch(memberAction.update(id, memberPayload);
    onClose();
  }

  return (
    <>
      <button onClick={() => setOpen(true)}>Edit</button>
      <Dialog open={open} onClose={() => setOpen(false)}>
        <DialogContent>
          <EditingForm value={memberPayload} onChange={setMemberPayload} />
        </DialogContent>
        <DialogActions>
          <Button onClick={onSave} color="primary">
            Close
          </Button>
          <Button onClick={onClose} color="primary">
            Save
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
}
  • Register that custom cell renderer in ag-grid
<AgGridReact
  columnDefs={[...columnDefs,
  {
    headerName: "Action",
    field: "action",
    width: 100,
    cellRenderer: "ButtonActionRenderer"
  }]}
  frameworkComponents={{
    ButtonActionRenderer,
  }}
/>

Apporach 2: Use Ag-Grid Cell Editor

Make your table cells editable and dispatch new changes to the store every time the input changes.

const MyEditor = forwardRef((props, ref) => {
    // props is ICellEditorParams. See:
    // https://www.ag-grid.com/react-grid/component-cell-editor/#cell-editor-component-1
    const field = props.colDef.field;
    const member = useSelector(state => state.members.id);
    const value = member[field];
    const onChange = (e) => dispatch(memberAction.updateField(field, e.target.value));

    return (
      <input
        ref={refInput}
        value={value}
        onChange={onChange}
        style={{width: "100%"}}
      />
    );
});
  • Register the custom cell editor in ag-grid
<AgGridReact
  columnDefs={[...columnDefs,
  {
    headerName: "Name",
    field: "name",
    width: 100,
    cellEditor: "MyEditor"
  }]}
  frameworkComponents={{
    MyEditor,
  }}
/>

References

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230