简体   繁体   English

AG-Grid 的日期时间过滤器 - 单击按钮时清除输入文本

[英]Datetime filter for AG-Grid - Clear input text on button click

Based on this proposed solution in the AG-Grid Github issues , I am trying to implement a jQuery DateTime Picker as a filter in my React / AG_Grid project.基于AG-Grid Github 问题中提出的解决方案,我正在尝试在我的React / AG_Grid项目中实现jQuery DateTime Picker作为过滤器。

I currently have my table set up so that I can clear the filters that have been applied to my table with a button click.我目前设置了我的表格,以便我可以通过单击按钮清除已应用于我的表格的过滤器。 The desired behavior is that once the Reset Filters button is clicked, the filters AND the text inside of the filter input should be cleared.期望的行为是,一旦单击重置过滤器按钮,过滤器过滤器输入内的文本应被清除。 As it is set up now, the filters are being cleared from the table as desired but when I reopen the filter input, the text from the previous filter is still there.正如现在设置的那样,过滤器正在根据需要从表中清除,但是当我重新打开过滤器输入时,前一个过滤器中的文本仍然存在。


I have a Code Sandbox set up here with a simplified version of my current setup.在这里设置了一个代码沙箱,其中包含我当前设置的简化版本。

Steps to recreate:重建步骤:

  • Open filter for Event Timestamp column打开事件时间戳列的过滤器
  • Apply filter to Event Timestamp column (2020/01/31 00:00 - 2020/06/31 00:00)将过滤器应用于事件时间戳列 (2020/01/31 00:00 - 2020/06/31 00:00)
  • Click 'Reset Filters' at the top of the table点击表格顶部的“重置过滤器”
  • Open filter for Event Timestamp column打开事件时间戳列的过滤器
  • Notice that text from the previous filter still populates the input请注意,来自前一个过滤器的文本仍会填充输入
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;

If anyone can help out or point me in the right direction, it would be greatly appreciated.如果有人可以帮助或指出我正确的方向,将不胜感激。 TIA!蒂亚!

While I was trying to figure this out on my own, I came across this Stack Overflow article that explains why you should NOT use React and jQuery together.当我试图自己解决这个问题时,我偶然发现了这篇 Stack Overflow 文章,它解释了为什么应该同时使用 React 和 jQuery。 This is great advice since you can see in the above example, the state wasn't being managed properly among other issues.这是一个很好的建议,因为您可以在上面的示例中看到,state 在其他问题中没有得到正确管理。

After further reading of the AG-Grid docs' custom date component section and this post on AG-Grid's blog , I was able to implement a solution that uses react-datetime-picker as the custom filter component.在进一步阅读 AG-Grid 文档的自定义日期组件部分和AG-Grid 博客上的这篇文章后,我能够实现一个使用react-datetime-picker作为自定义过滤器组件的解决方案。 You then have to pass it to the table's frameworkComponents prop.然后,您必须将其传递给表的 frameworkComponents 道具。

LIVE DEMO ON STACK BLITZ Stack BLITZ 上的现场演示

DTPicker.jsx 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应用程序.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
    }}
    ...
/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM