1
votes

I am using material-table to render my data and I am dynamically building lookup

I want to add another lookup column to my table if a certain value is selected from the first lookup

const [state, setState] = useState<TableState>({
  columns: [
    {
      title: 'Name',
      field: 'name',
      editComponent: (tableData) => {
        return <Input autoFocus={true} onChange={(e) => tableData.onChange(e.target.value)} />;
      }
    },
    {
      title: 'Type', field: 'type_id', initialEditValue: 1, editable: 'onAdd',
      lookup: columnTypes,

    }
  ],
  data: []
});

then I would want to add another item to make the tablestate look like this if they chose alignment from the first lookup

const [state, setState] = useState<TableState>({
      columns: [
        {
          title: 'Name',
          field: 'name',
          editComponent: (tableData) => {
            return <Input autoFocus={true} onChange={(e) => tableData.onChange(e.target.value)} />;
          }
        },
        {
          title: 'Type', field: 'type_id', initialEditValue: 1, editable: 'onAdd',
          lookup: columnTypes,

        },
        {
          title: '', field: 'alignment_col', initialEditValue: 1, editable: 'onAdd',
          lookup: alignmentColumns,
        }
      ],
      data: []
    });

this is what my material-table looks like. Seems like there should be some kin of onRowSelected for the lookup for a function to run so I can change my state to add the 3rd column if a certain value is selected. I have not found a solution on how to do this.

 <MaterialTable
                  title="Column Definitions"
                  columns={state.columns}
                  data={state.data}
                  onRowClick={handleClick}
                  editable={{
                    onRowAdd: (newData) =>
                      (async function () {
                        const success = await editorStore.createColumnDefinition(
                          {
                            linkId: linkId,
                            columnName: newData.name,
                            columnType: (state.columns[1].lookup as { [key: number]: string })[newData.type_id],
                            alignmentColumn: (state.columns[2].lookup as { [key: number]: string})[newData.alignment_col]
                          }
                        );
                        if (success) {
                          changeToastValues('success', `Successfully added column '${newData.name}'`);
                          handleOpen();
                        }
                      })(),
                    onRowDelete: (oldData) =>
                      (async function () {
                        const success = await editorStore.deleteColumnsDefinition(linkId, oldData.id);
                        if (success) {
                          changeToastValues('success', `Successfully deleted column '${oldData.name}'`);
                          setState((prevState) => {
                            const data = [...prevState.data];
                            data.splice(data.indexOf(oldData), 1);
                            return { ...prevState, data };
                          });
                        }
                      })(),
                    onRowUpdate: (newData, oldData) =>
                      (async function () {
                        const resData = await editorStore.editColumnDefinition(newData.id, newData.name);
                        if (resData) {
                          changeToastValues('success', `Successfully edited column '${newData.name}'`);
                          setState((prevState) => {
                            const data = [...prevState.data];
                            data[data.indexOf(oldData as Row)] = resData as Row;
                            return { ...prevState, data };
                          });
                        }
                      })()
                  }}
                />

enter image description here

when alignment is selected I want to add another lookup and it should look like this.

enter image description here

I am struggling on how to get a function to run on selection of a lookup in order to reset the state.

1
Take a look at custom render by using editComponent and render the lookup yourself. If you do that, you have all information you need to achieve this. - Domino987
@Domino987 that is exactly what i did and I got all this working. I think it kinda sucks that I had to do that but I will post my solution to my own question. If anyone else has this same issue they can solve it - josh

1 Answers

0
votes

what i did was a custom render to solve this issue. This is inital state using editcomponent to create my drop down I am also using useState to alter what the user selects from my drop down.

export const OptionsHeaderCell = observer(
  (props) => {

    const classes = useStyles();
    const viewerStore = useStorelinkViewerStore();
    const editorStore = useStorelinkEditorStore();
    const columnTypes = editorStore.columnTypes;
    const alignmentColumns = editorStore.alignmentColumns;
    const lookupColumnTypes = editorStore.lookupColumnTypes;
    const [columnSelected, setColumnSelected] = useState<string>('string');
    const [linkId, setLinkId] = useState<number>();
    const [state, setState] = useState<TableState>({
      columns: [
        {
          title: 'Name',
          field: 'name',
          editComponent: (tableData) => {
            return <Input autoFocus={true} onChange={(e) => tableData.onChange(e.target.value)} />;
          }
        },
        {
          title: 'Type', field: 'type_id',
          lookup: lookupColumnTypes,
          editComponent: (tableData) => {
            return <Select value={tableData.value || 'string'} onChange={(e) => {tableData.onChange(String(e.target.value)); setColumnSelected(String(e.target.value));}}>
              {columnTypes.map((type) => <MenuItem value={type.name}>{type.name}</MenuItem>)}
            </Select>;
          }
        }
      ],
      data: []
    });

then I created a useeffect to watch for changes to add the alignment drop down and take it away when the user selects a different option besides alignment.

 useEffect(() => {
      if(columnSelected === 'alignment')
      {
        setState({...state, columns: [...state.columns,
          {
            title: 'Alignment',
            field: 'alignment_col',
            lookup: alignmentColumns,
            initialEditValue: 1
          }
        ]
        });
      }
      else {
        if (state.columns.length > 2)
        {
          setState({...state, columns: [...state.columns].slice(0,2)});
        }
      }
    }, [columnSelected]);

I hope if anyone has this same issue this helps them out. Thank you for looking.