9

I have a filter component:

export const PostsFilter = (props) => (
  <Filter {...props}>
    <TextInput label='Post ID' source='id' alwaysOn />
    <TextInput label='User ID' source='user_id' alwaysOn />
  </Filter>
);

I need to add a reset button that will clear input values. I understand that in should be done via dispatching smth to redux. So maybe somebody already solved this problem? Thanks!

Sasha Kos
  • 2,480
  • 2
  • 22
  • 37
  • 1
    Have your form use redux-form? If have you can see https://stackoverflow.com/a/42726072/7034009 .Use `this.props.reset()` or `this.props.initialize({})` in action of button reset – Thanh Ngo Oct 31 '18 at 04:40
  • yep, `react-admin` uses `redux-form` [under the hood](https://github.com/marmelab/react-admin/blob/master/packages/ra-core/package.json#L57), so it's also the correct direction to investigate – Alejandro Nov 07 '18 at 08:08

5 Answers5

9

There is a setFilters prop in your filter component, you can use it:

export const PostsFilter = (props) => (
  <div>
    <Filter {...props}>
      <TextInput label='Post ID' source='id' alwaysOn />
      <TextInput label='User ID' source='user_id' alwaysOn />
    </Filter>
    <Button onClick={() => props.setFilters({
          id: '',
          user_id: ''
     })}>Clear fields</Button>
  <div>
);
Alejandro
  • 5,834
  • 1
  • 19
  • 36
  • Thanks, Alex for your reply. I was full of hope that resetForm will solve my problem, but i've checked and it's not. I see that by button click there is `RA/RESET_FORM` event dispatching, but it actually do nothing. But i feel that the answer is somewhere very near... – Sasha Kos Nov 02 '18 at 12:48
  • @SashaKos, np. Can you check with `setFilter` action? I've updated the answer – Alejandro Nov 02 '18 at 13:01
  • Thanks, @Alex for your suggest, but it's not possible to call `setFilter` directly. It causes error `Actions must be plain objects. Use custom middleware for async actions.` So i have tried dispatch directly `dispatch({type: CRUD_SET_FILTER, payload: { field, value }, meta: { resource }})` and I see that event is dispatching, but filter still not clearing – Sasha Kos Nov 06 '18 at 11:08
  • @SashaKos I updated answer, hope it'll finally work for you (I checked, it should!) :) – Alejandro Nov 07 '18 at 08:06
  • Thanks, @Alex. I'll check it, but looks like that's it. – Sasha Kos Nov 07 '18 at 11:48
1

Unfortunately, setFilters does nothing for me. Here is the solution to the problem:

<FormDataConsumer form={'filterForm'} alwaysOn source='stateId'>
      {({ formData, dispatch, ...rest }) => (
        <ReferenceInput
          resource={props.resource}
          source='stateId'
          reference='states'
          onChange={value => {
            dispatch(change('filterForm', 'districtId', null));
          }}
          allowEmpty>
          <SelectInput optionText='name' />
        </ReferenceInput>
      )}
    </FormDataConsumer>

    {(props.filterValues.stateId || props.filterValues.districtId) && (
      <ReferenceInput
        key={props.filterValues.stateId}
        source='districtId'
        reference='districts'
        filter={{ stateId: props.filterValues.stateId }}
        alwaysOn>
        <SelectInput optionText='name' />
      </ReferenceInput>
    )}
Alexander M.
  • 3,308
  • 2
  • 20
  • 31
1

const PostActions = ({
  bulkActions,
  basePath,
  currentSort,
  displayedFilters,
  exporter,
  filters,
  filterValues,
  onUnselectItems,
  resource,
  selectedIds,
  showFilter,
  total,
  setFilters,
}) => (
  <CardActions>
    {/* Add your custom actions */}
    <Button variant="text" onClick={() => setFilters({})}>
      Clear Filters
    </Button>
    {bulkActions &&
      React.cloneElement(bulkActions, {
        basePath,
        filterValues,
        resource,
        selectedIds,
        onUnselectItems,
      })}
    {filters &&
      React.cloneElement(filters, {
        resource,
        showFilter,
        displayedFilters,
        filterValues,
        context: 'button',
      })}
    <ExportButton
      disabled={total === 0}
      resource={resource}
      sort={currentSort}
      filter={filterValues}
      exporter={exporter}
    />
  </CardActions>
); 

<List
    {...props}
    filters={<LeadTimeFilter />}
    bulkActions={false}
    actions={<PostActions />}
  >
you can add a reset button in the actions.In the action can get the 'setFilters'method which can reset filters from the props.
Anew
  • 61
  • 5
1

Here's how I created a "Clear Filters" button ("react-admin": "3.10.2").

Extending upon the custom ListActions toolbar example...

import { FilterList } from "@material-ui/icons";
import React from "react";
import {
    Button,
    sanitizeListRestProps,
    TopToolbar
} from "react-admin";

const ListActionsTopToolbar = (props) => {
  const {
    className,
    exporter,
    filters,
    maxResults,
    setFilters,
    ...rest
  } = props;
  return (
    <TopToolbar className={className} {...sanitizeListRestProps(rest)}>
        
        {/* Clear Filters Button */}
      <Button onClick={() => setFilters({})} label="Clear Filters">
        <FilterList />
      </Button>

    </TopToolbar>
  );
};

Traceback: https://github.com/marmelab/react-admin/issues/816#issuecomment-734030723

Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
0

It sounds like you want to clear the value in the TextInput, which doesn't need redux looking at what you've given us.

One of the approaches to use is saving the filter input to state through the onChange() function - which is maybe where you are also calling the action to hit the backend or change state for the posts that are in your props.

To reset, you can have another button that has in onClick() call to a handleReset(inputId) which you can call setState({filterUser: 'testUser123'}) on that will do what you are asking.

Though it depends how you are wanting to handle it all, there isn't enough information to see how you're doing that, so i'm just speculating on a common way people go about things.

mewc
  • 1,253
  • 1
  • 15
  • 24