Как реализовать пользовательский плавающий фильтр ag-grid с помощью Material-UI со стилями HoC? - PullRequest
1 голос
/ 15 мая 2019

Создан пользовательский плавающий фильтр ag-grid с проверкой и необходимостью стилизовать фильтр при сбое проверки с использованием тематического класса material-ui с использованием компонента высшего порядка withStyles (HoC). Однако, когда вы оборачиваете пользовательский плавающий фильтр с помощью HoC onParentModelChanged, он вообще не вызывается.

Использовал жестко заданный стиль для установки свойства стиля элемента, но это не разрешено в тематическом проекте с использованием @ material-ui / core v1.4.0. Ниже представлен пользовательский плавающий фильтр, который я создал с проверкой и жестко запрограммированным стилем.

import { PropTypes } from 'prop-types';

import styles from './styles';

const DEFAULT_MIN_CHARS = 3;
const ENTER_KEY = 13;

export class CustomFloatingFilter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      currentValue: '',
      minChars: props.minChars ? props.minChars : DEFAULT_MIN_CHARS,
      invalidFilter: false,
      styles: styles()
    };
    this.keyPressed = this.keyPressed.bind(this);
    this.valueChanged = this.valueChanged.bind(this);
    this.onParentModelChanged = this.onParentModelChanged.bind(this);
    this.onFloatingFilterChanged = change => {
      const { minChars } = this.state;
      if(change && change.model && (!change.model.filter || change.model.filter.length >= minChars)) {
        return props.onFloatingFilterChanged(change);
      }
      return false;
    };
  }

  keyPressed(event) {
    this.setState(
      { enterPressed: event.which === ENTER_KEY },
      () => {
        const { enterPressed } = this.state;
        if(enterPressed) { //update filter only when enter. valueChanged will handle all other cases
          this.onFloatingFilterChanged(this.buildChanged());
        }
      }
    );
  }

  valueChanged(event) {
    const { minChars } = this.state;
    this.setState(
      {
        currentValue: event.target.value,
        invalidFilter: !!event.target.value && event.target.value.length < minChars
      },
      () => {
        this.onFloatingFilterChanged(this.buildChanged());
      }
    );
  }

  onParentModelChanged(parentModel) {
    this.setState({ currentValue: parentModel ? parentModel.filter : '' });
  }

  buildChanged() {
    const { currentValue, enterPressed, invalidFilter } = this.state;

    return {
      model: {
        filterType: 'text',
        type: 'equals',
        filter: currentValue
      },
      apply: !invalidFilter && (enterPressed || currentValue === '') //for applyButton:true case
    };
  }

  render() {
    const { currentValue, invalidFilter, styles } = this.state;

    return (
      <div style={invalidFilter ? styles.invalid : {} //eslint-disable-line
      //withStyles HoC doesn't work with ag-grid floating filter component
      }
      >
        <input className='ag-floating-filter-input' onKeyPress={this.keyPressed} onChange={this.valueChanged} value={currentValue} />
      </div>
    );
  }
}

CustomFloatingFilter.propTypes = {
  minChars: PropTypes.number,
  onFloatingFilterChanged: PropTypes.func
};

export default CustomFloatingFilter;
...