AllenFang / react-bootstrap-table

A Bootstrap table built with React.js
https://allenfang.github.io/react-bootstrap-table/
MIT License
2.24k stars 783 forks source link

date filter not working as expected for "=","!=" operators #2070

Closed narendravenkata closed 5 years ago

narendravenkata commented 5 years ago

I am using the latest release of "react-bootstrap-table":"^4.3.1", but i think the issue is not resolved.

Capture-1 Capture-2

narendravenkata commented 5 years ago
import React, { Component } from 'react';
import PropTypes from 'prop-types';

const FILTER_TYPE = 'DateFilter';
const legalComparators = ['=', '>', '>=', '<', '<=', '!='];

function dateParser(d) {
    return `${d.getUTCFullYear()}-${('0' + (d.getUTCMonth() + 1)).slice(-2)}-${('0' + d.getUTCDate()).slice(-2)}`;
}

function parseDate(input) {
    // when input date format is "2019-03-08" i.e., "YYYY-MM-dd"
    if (input != null) {
        var parts = input.match(/(\d+)/g);
        // new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
        return new Date(parts[0], parts[1] - 1, parts[2]); // months are 0-based
    }
}

class CustomDateFilter extends Component {
    constructor(props) {
        super(props);
        this.dateComparators = this.props.dateComparators || legalComparators;
        this.filter = this.filter.bind(this);
        this.onChangeComparator = this.onChangeComparator.bind(this);
    }

    setDefaultDate() {
        let defaultDate = '';
        const { defaultValue } = this.props;
        if (defaultValue && defaultValue.date) {
            // Set the appropriate format for the input type=date, i.e. "YYYY-MM-DD"
            defaultDate = dateParser(new Date(defaultValue.date));
        }
        return defaultDate;
    }

    onChangeComparator(event) {
        let date = this.inputDate.value;

        const comparator = event.target.value;
        if (date === '') {
            return;
        }
        date = parseDate(date);
        date = new Date(date);
        this.props.filterHandler({ date, comparator }, FILTER_TYPE);
    }

    getComparatorOptions() {
        const optionTags = [];
        optionTags.push(<option key='-1'></option>);
        for (let i = 0; i < this.dateComparators.length; i++) {
            optionTags.push(
                <option key={i} value={this.dateComparators[i]}>
                    {this.dateComparators[i]}
                </option>
            );
        }
        return optionTags;
    }

    filter(event) {
        const comparator = this.dateFilterComparator.value;
        const dateValue = event.target.value;
        //console.log("Entered date is",dateValue);

        if (dateValue) {
            var parsed = parseDate(dateValue);
            this.props.filterHandler({ date: new Date(parsed), comparator }, FILTER_TYPE);
        } else {
            this.props.filterHandler(null, FILTER_TYPE);
        }
    }

    cleanFiltered() {
        const value = this.setDefaultDate();
        const comparator = (this.props.defaultValue) ? this.props.defaultValue.comparator : '';
        this.setState(() => { return { isPlaceholderSelected: (value === '') }; });
        this.dateFilterComparator.value = comparator;
        this.inputDate.value = value;
        this.props.filterHandler({ date: new Date(value), comparator }, FILTER_TYPE);
    }

    applyFilter(filterDateObj) {
        const { date, comparator } = filterDateObj;
        this.setState(() => { return { isPlaceholderSelected: (date === '') }; });
        this.dateFilterComparator.value = comparator;
        this.inputDate.value = dateParser(date);
        this.props.filterHandler({ date, comparator }, FILTER_TYPE);
    }

    componentDidMount() {
        const comparator = this.dateFilterComparator.value;
        const dateValue = this.inputDate.value;
        if (comparator && dateValue) {
            this.props.filterHandler({ date: new Date(dateValue), comparator }, FILTER_TYPE);
        }
    }

    render() {
        const { defaultValue, style: { date, comparator } } = this.props;
        return (
            <div className='filter date-filter'>
                <select ref={n => this.dateFilterComparator = n}
                    style={comparator}
                    className='date-filter-comparator form-control'
                    onChange={this.onChangeComparator}
                    defaultValue={(defaultValue) ? defaultValue.comparator : ''}>
                    {this.getComparatorOptions()}
                </select>
                <input ref={n => this.inputDate = n}
                    className='filter date-filter-input form-control'
                    style={date}
                    type='date'
                    onChange={this.filter}
                    defaultValue={this.setDefaultDate()} />
            </div>
        );
    }
}

CustomDateFilter.propTypes = {
    filterHandler: PropTypes.func.isRequired,
    defaultValue: PropTypes.shape({
        date: PropTypes.object,
        comparator: PropTypes.oneOf(legalComparators)
    }),
    style: PropTypes.shape({
        date: PropTypes.oneOfType([PropTypes.object]),
        comparator: PropTypes.oneOfType([PropTypes.object])
    }),
    /* eslint consistent-return: 0 */
    dateComparators: function (props, propName) {
        if (!props[propName]) {
            return;
        }
        for (let i = 0; i < props[propName].length; i++) {
            let comparatorIsValid = false;
            for (let j = 0; j < legalComparators.length; j++) {
                if (legalComparators[j] === props[propName][i]) {
                    comparatorIsValid = true;
                    break;
                }
            }
            if (!comparatorIsValid) {
                return new Error(`Date comparator provided is not supported.
          Use only ${legalComparators}`);
            }
        }
    },
    columnName: PropTypes.any
};

CustomDateFilter.defaultProps = {
    style: {
        date: null,
        comparator: null
    }
};

export default CustomDateFilter;

I made some modifications to the DateFilter and was able to fix the problem I was having.

When the input date is in the format "2019-03-08" it is passed to filter as "Thu Mar 07 2019 19:00:00 GMT-0500 (Eastern Standard Time)"