React-bootstrap-table2: Custom Filter + Sort in one column

Created on 15 Oct 2018  路  10Comments  路  Source: react-bootstrap-table/react-bootstrap-table2

When I define a column with cell filtering and sorting enabled, clicking the filter input triggers the sorting. Can I somehow compose the header by myself (trigger included)? I tried headerFormatter, but I think the sort function is bound to the th.sortable element itself, and I can't access it from headerFormatter iteself.

I can't find such an example in the Storybook. Sorting and Filtering are occouring independantly only.

bug

All 10 comments

Ok I have found the example, but it appears that the problem lies somewhere else. I have created a custom header formatter like so:

headerFormatter: (column, colIndex, { sortElement, filterElement }) => (
    <div>
        { sortElement }
        { column.text }
        { filterElement }
    </div>
)

and the problem still persists, BUT only with custom filter components. Is there a possibility that i haven't attached something crucial inside of them that prevents this behaviour?

What kind of filter you apply? text, select, date filter?! Because I write a simple demo with a text filter and sort, but when I click on text filter, it doesn't trigger sort.

All of them, on everyone i get the same behaviour. My custom Text filter for example looks like this:

import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { customFilter } from 'react-bootstrap-table2-filter';

import {
    Form,
    Input
} from './../../../../components';

class TextFilter extends React.Component {
    static propTypes = {
        column: PropTypes.object.isRequired,
        onFilter: PropTypes.func.isRequired,
        placeholder: PropTypes.string,
        getFilter: PropTypes.func
    }

    constructor() {
        super();

        this.state = {
            value: ''
        }
    }

    componentDidMount() {
        if (_.isFunction(this.props.getFilter)) {
            this.props.getFilter((value) => {
                this.setState({ value });
            });
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevState.value !== this.state.value) {
            this.props.onFilter(this.state.value);
        }
    }

    render() {
        const { onFilter, placeholder } = this.props;
        return (
            <Form 
                onSubmit={(e) => {
                    e.preventDefault();
                    onFilter(this.state.value) 
                }}
            >
                <Input
                    type="text"
                    bsSize="sm"
                    onChange={(e) => this.setState({value: e.target.value})}
                    value={ this.state.value }
                    placeholder={ placeholder }
                />
            </Form>
        )
    }
}

export const buildCustomTextFilter = ({ placeholder, getFilter, ...other } = {}) => ({
    filter: customFilter(other),
    filterRenderer: function TextFilterWrap(onFilter, column) {
        return (
            <TextFilter
                {...{
                    onFilter,
                    column,
                    placeholder,
                    getFilter
                }}
            />
        )
    }
});

Afterwards the result object of buildCustomTextFilter is merged with the column definition object.

Hi.
Have the same issue: onTableChange with type=sort called if I click on customFilter input.
Column defined as:
{ dataField: 'sent', text: 'Sent', sort: true, filter: customFilter(), filterRenderer: (onFilter, column) => <DateFilter onFilter={onFilter} column={column} />, formatter: (cell) => { return moment(cell).format(UI.DateDefaultFormat); } }

I will check this out, thanks

@owczar1981 @victorkpublic I think if you guys use custom filter, you may need to call stopPropagation manually. to avoid the event bobble up: for example this is how react-bootstrap-table2 avoid to trigger the sort when click on default text filter:

https://github.com/react-bootstrap-table/react-bootstrap-table2/blob/master/packages/react-bootstrap-table2-filter/src/components/text.js#L75-L80

Let me know if above solution is not work for you guys. thanks

I still have this issue with custom filter (react-datepicker2),
I'm using react-bootstrap-table2-filter version 1.3.1

I am using customFilter with react-datepicker, and I am facing the same issue.

function DateTimeFilter(props) {
const { onFilter, column } = props;

const [startDate, setStartDate] = useState();

const handleChange = (date, event) => {
    event.stopPropagation();
    setStartDate(date);
    onFilter(date);
}

return (
    <DatePicker
        dateFormat='dd/MM/yyyy'
        selected={startDate}
        onChange={handleChange}
        isClearable
    />
);

}

this is the code snippet I am using but after preventing also the sorting gets triggered

@AllenFang

I am having a similar issue too for any customFilter and I am using React-select for it.

handleClick(e) {
    e.stopPropagation();
  }

  comparaterFilter(value, e) {
    e.stopPropagation();
    this.props.onFilter(value);
  }
return [
      <div key={i++} style={{ marginBottom: "8px", fontWeight: "normal" }}>
        <Select
          isMulti
          isSearchable
          options={comparators}
          name="comparators"
          onClick={this.handleClick}
          onChange={this.changeComparatorHandler}
          value={selectedOption}
          components={animatedComponents}
        />
      </div>,
    ];

@AllenFang

I am having a similar issue too for any customFilter and I am using React-select for it.

handleClick(e) {
    e.stopPropagation();
  }

  comparaterFilter(value, e) {
    e.stopPropagation();
    this.props.onFilter(value);
  }
return [
      <div key={i++} style={{ marginBottom: "8px", fontWeight: "normal" }}>
        <Select
          isMulti
          isSearchable
          options={comparators}
          name="comparators"
          onClick={this.handleClick}
          onChange={this.changeComparatorHandler}
          value={selectedOption}
          components={animatedComponents}
        />
      </div>,
    ];

@AllenFang

@AllenFang
I figured it out. I added component.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SandeepKapalawai picture SandeepKapalawai  路  3Comments

josefheld picture josefheld  路  3Comments

epsyan picture epsyan  路  4Comments

kamarajuPrathi picture kamarajuPrathi  路  4Comments

eylonronen picture eylonronen  路  3Comments