【问题标题】:Datetime filter for AG-Grid - Clear input text on button clickAG-Grid 的日期时间过滤器 - 单击按钮时清除输入文本
【发布时间】:2021-06-12 23:43:58
【问题描述】:

基于this proposed solution in the AG-Grid Github issues,我正在尝试在我的React/AG_Grid 项目中实现jQuery DateTime Picker 作为过滤器。

我目前已设置好我的表,以便我可以通过单击按钮清除已应用于我的表的过滤器。期望的行为是,一旦单击重置过滤器按钮,过滤器 AND 过滤器输入内的文本应被清除。正如现在设置的那样,过滤器正在根据需要从表中清除,但是当我重新打开过滤器输入时,前一个过滤器中的文本仍然存在。


我有一个Code Sandbox set up here,其中包含我当前设置的简化版本。

重建步骤:

  • 为事件时间戳列打开过滤器
  • 将过滤器应用于事件时间戳列(2020/01/31 00:00 - 2020/06/31 00:00)
  • 点击表格顶部的“重置过滤器”
  • 为事件时间戳列打开过滤器
  • 请注意,来自上一个过滤器的文本仍会填充输入
const App = () => {
  const [gridApi, setGridApi] = useState([]);
  const [gridColumnApi, setGridColumnApi] = useState([]);
  const [rowData, setRowData] = useState([]);

  useEffect(() => {
    const formattedDates = dataSet.map((data) => {
      return {
        id: data.id,
        eventTimestamp: new Date(data.eventTimestamp)
      };
    });
    setRowData(formattedDates);
  }, []);

  // ***************************************************
  // The Handle Click logic for the reset filters button:
  // ***************************************************
  const resetAppliedFilters = () => {
    gridApi.setFilterModel(null);
    CustomDateComponent.prototype.setDate(null);
  };

  const cols = [
    {
      field: "id",
      headerName: "ID",
      minWidth: 100,
      maxWidth: 150
    },
    {
      field: "eventTimestamp",
      headerName: "Event Timestamp",
      minWidth: 225,
      filter: "agDateColumnFilter",
      filterParams: {
        defaultOption: "inRange",
        // ***************************************************
        // Comparator function for datetime picker:
        // ***************************************************
        comparator: function (filterLocalDate, cellValue) {
          filterLocalDate.setMilliseconds(0);
          cellValue.setMilliseconds(0);
          let filterBy = filterLocalDate.getTime();
          let filterMe = cellValue.getTime();
          if (filterBy === filterMe) {
            return 0;
          }

          if (filterMe < filterBy) {
            return -1;
          }

          if (filterMe > filterBy) {
            return 1;
          }
        }
      }
    }
  ];

  const onGridReady = (params) => {
    setGridApi(params.api);
    setGridColumnApi(params.columnApi);
    // ***************************************************
    // Table event listener:
    // ***************************************************
    params.api.addGlobalListener((type, event) => {
      switch (type) {
        case "filterChanged":
          console.log(event);
          return;
        default:
          return null;
      }
    });
  };

  return (
    <div className="App">
      <Button onClick={resetAppliedFilters} variant="outlined">
        Reset Filters
      </Button>
      <hr />
      <div
        className={"ag-theme-balham"}
        style={{ height: "86vh", width: "100%" }}
      >
        <AgGridReact
          onGridReady={onGridReady}
          rowData={rowData}
          rowSelection="multiple"
          defaultColDef={{
            flex: 1,
            minWidth: 100,
            resizable: true,
            sortable: true,
            filter: true
          }}
          pagination
          columnDefs={cols}
          components={{
            agDateInput: CustomDateComponent
          }}
        />
      </div>
    </div>
  );
};

// ***************************************************
// Custom datetime picker component:
// ***************************************************
function CustomDateComponent() {}

CustomDateComponent.prototype.init = function (params) {
  this.params = params;
  this.eGui = document.createElement("div");
  this.eInput = document.createElement("input");
  this.eGui.appendChild(this.eInput);
  jQuery(this.eInput).datetimepicker({
    mask: true, // '9999/19/39 29:59' - digit is the maximum possible for a cell
    onChangeDateTime: this.onDateChanged.bind(this)
  });
};

CustomDateComponent.prototype.onDateChanged = function (currentDateTime) {
  this.date = currentDateTime;
  this.params.onDateChanged();
};

CustomDateComponent.prototype.getGui = function () {
  return this.eGui;
};

CustomDateComponent.prototype.getDate = function () {
  return this.date;
};

CustomDateComponent.prototype.setDate = function (date) {
  this.date = date;
};

CustomDateComponent.prototype.destroy = function () {
  jQuery(this.eInput).datetimepicker("destroy");
};

export default App;

如果有人可以提供帮助或指出正确的方向,将不胜感激。蒂亚!

【问题讨论】:

    标签: javascript reactjs debugging ag-grid jquerydatetimepicker


    【解决方案1】:

    当我试图自己解决这个问题时,我遇到了this Stack Overflow article,它解释了为什么你应该同时使用 React 和 jQuery。这是一个很好的建议,因为您可以在上面的示例中看到,在其他问题中没有正确管理状态。

    在进一步阅读 AG-Grid 文档的 custom date component 部分和 this post on AG-Grid's blog 之后,我能够实现一个使用 react-datetime-picker 作为自定义过滤器组件的解决方案。然后,您必须将其传递给表格的 frameworkComponents 属性。

    LIVE DEMO ON STACK BLITZ

    DTPicker.jsx

    import DateTimePicker from "react-datetime-picker";
    
    export default forwardRef((props, ref) => {
      const [selectedDate, setSelectedDate] = useState(null);
    
      function handleDateChange(d) {
        if (d) {
          d = new Date(d);
          setSelectedDate(d);
        } else {
          setSelectedDate(null);
        }
      }
    
      // props.onDateChanged must be called after updating our component's internal state:
      useEffect(props.onDateChanged, [selectedDate]);
    
      // getDate and setDate are required by AG-Grid to sync ag-Grid's date 
      // filter value with that of our components:
      useImperativeHandle(ref, () => {
        return {
          getDate: () => {
            return selectedDate;
          },
          setDate: d => {
            handleDateChange(d);
          }
        };
      });
    
      return (
        <>
          <DateTimePicker
            onChange={handleDateChange}
            value={selectedDate}
            maxDetail="second"
            disableCalendar={true}
            disableClock={true}
          />
        </>
      );
    });
    

    App.jsx

    import DTPicker from './DTPicker'
    
    // Add your custom filter logic in your column:
    const cols = [
        ...,
        {
          field: "eventTimestamp",
          headerName: "Event Timestamp",
          filter: "agDateColumnFilter",
          filterParams: {
            defaultOption: "inRange",
            comparator: function(filterLocalDate, cellValue) {
              let filterBy = filterLocalDate.getTime();
              let filterMe = cellValue.getTime();
              if (filterBy === filterMe) {
                return 0;
              }
    
              if (filterMe < filterBy) {
                return -1;
              }
    
              if (filterMe > filterBy) {
                return 1;
              }
            }
          }
        },
        ...
      ];
    
    <AgGridReact
        ...
        frameworkComponents={{
            agDateInput: DTPicker
        }}
        ...
    />
    

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 2021-04-07
      • 2014-02-27
      • 1970-01-01
      • 2021-09-13
      • 2016-08-26
      • 1970-01-01
      • 2019-04-12
      • 2018-03-14
      相关资源
      最近更新 更多