gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.71k stars 934 forks source link

Filter Options based on Web service when you use asynchronous data loading #1998

Open bart1485 opened 1 year ago

bart1485 commented 1 year ago

I have the same problem here, i have tried many things but without success. Because, if you use server side loading on the table, you need to filter them on all the data that gonna be display in it and not only the one display on the screen. So i tried to put a list options from a web service.

I dont found any documentation with the right way to do it.

Can we have some help to improve this part.

If i tried to declare something like that :

{
  name: 'name',
  label: 'Nom Ordi',
  options: {
      sort: false,
      filter: true,
      filterList: [],
      customFilterListOptions: { render: v => `Name: ${v}` },
      filterOptions: {
          names: getFilterOptionsList('name')
      }
  },
},

And my fonction :

const getFilterOptionsList = async (filter) => {
      await client.get('/'+filter+'/filter').then(res => {
          if(res.data.length > 0) {
              return res.data.map(it => it[filter]);
          }
          return [];
      }).catch(res => {
          return [];
      })
}

I just have an error Failed prop type: Invalid prop columns[1] supplied to o, expected one of type [string] And the list is not the right one.

I tried to do this based on the documentation :

  const getFilterOptions = (filter, filterList, onChange, index, column) => {
      client.get('/'+filter+'/filter').then(res => {
          if(res.data.length > 0) {
              let filterOptions = res.data.map(it => it[filter])
              const optionValues = {...filters, [filter]: filterOptions};
              console.log(optionValues);
              return (
                  <FormControl>
                      <InputLabel htmlFor='select-multiple-chip'>
                          Location
                      </InputLabel>
                      <Select
                          multiple
                          value={filterList[index]}
                          renderValue={selected => selected.join(', ')}
                          onChange={event => {
                              filterList[index] = event.target.value;
                              onChange(filterList[index], index, column);
                          }}
                      >
                          {
                              optionValues[filter].map(item =>
                                  <MenuItem key={item} value="aze">
                                      <Checkbox
                                          color='primary'
                                          checked={filterList[index].indexOf(item) > -1}
                                      />
                                      <ListItemText primary={item} />
                                  </MenuItem>
                              )
                          }
                      </Select>
                  </FormControl>
              );
          }
      }).catch(res => {
          return (
              <FormControl>
                  <InputLabel htmlFor='select-multiple-chip'>
                      Location
                  </InputLabel>
                  <Select
                      multiple
                      value={filterList[index]}
                      renderValue={selected => selected.join(', ')}
                  >
                  </Select>
              </FormControl>
          );
      })
  }

Every time I have a console with the right value.

I call it with this :

 {
        name: 'name',
        label: 'Nom Ordi',
        options: {
            sort: false,
            filter: true,
            filterList: [],
            filterType: 'custom',
            customFilterListOptions: { render: v => `Name: ${v}` },
            filterOptions: {
                names: [],
                display: (filterList, onChange, index, column) => getFilterOptions('name', filterList, onChange, index, column)
            }
        },
    }

Every time it's correctly called but my filter component is always empty. I just have a blank element into the filter form.

If anyone have a possibility for us to complete this.

best regards