Неопределенный флажок не работает при фильтрации реагирующих MUI-Datatables

#javascript #reactjs #debugging #redux #mui-datatable

#javascript #reactjs #отладка #redux #mui-datatable

Вопрос:

Информация

У меня есть проект, который использует React, Redux и MUI-Datatables. Простую демонстрацию этого проекта можно найти в этом CodeSandbox .

В этом приложении есть два основных компонента: карта и таблица данных. Они взаимодействуют через redux, так что при выборе строки в таблице соответствующий круг на карте выделяется и наоборот.

Проблема

Моя проблема связана с неопределенным переключением флажка выбора в таблице. Когда пользователь выбрал строку, а затем применяет фильтр, флажок selectAll показывает неопределенный символ ‘-‘, но при нажатии на него ничего не происходит.

Шаги для воссоздания:

  • Пользователь выбирает первую строку в таблице, circle1.
  • Пользователь открывает диалоговое окно фильтра в правом углу таблицы.
  • Из выпадающего меню маркера в диалоговом окне фильтра пользователь выбирает circle3 в качестве значения фильтра.
  • Пользователь закрывает диалоговое окно фильтра
  • Пользователь нажимает на флажок selectAll в верхней части столбца select row. В нем будет отображаться символ ‘-‘.
  • Обратите внимание, что ничего не меняется. Ни одна строка не выбрана или не отменена.

Желаемое поведение:

Когда пользователь выбрал строку в таблице, а затем применяет фильтр, флажок selectAll по-прежнему должен выбирать все видимые строки при первом щелчке и отменять выбор всех при втором щелчке так же, как обычно.

Код

Live: CodeSandbox

Компонент таблицы:

 import React, { useEffect, useState } from "react";
import MUIDataTable from "mui-datatables";

import { connect } from "react-redux";

import { handleSelection } from "./redux";

import circles from "./assets/data/circles";

import { addToOrRemoveFromArray } from "./utils";

// Table component
const Table = ({ handleSelection, selections }) => {
  const [selectionIndexes, setSelectionIndexes] = useState([]);

  // When 'selections' changes in redux store:
  useEffect(() => {
    let indexes = [];
    // Iterate selections:
    selections.forEach((selection) => {
      // Push the index of the selected
      // circle into index arr:
      let index = circles.indexOf(selection);
      indexes.push(index);
    });
    // Set selections to local state hook:
    setSelectionIndexes(indexes);
  }, [selections]);

  // Table options:
  const options = {
    rowsSelected: selectionIndexes, // User provided array of numbers (dataIndexes) which indicates the selected rows
    selectToolbarPlacement: "none",
    selectableRows: "multiple", // Enable selection of multiple rows
    setRowProps: (row, dataIndex, rowIndex) => {
      return {
        style: {
          padding: ".5rem",
          margin: ".5rem auto"
        }
      };
    },
    // When a row(s) is/are selected:
    onRowSelectionChange: (
      currentRowsSelected,
      allRowsSelected,
      rowsSelected
    ) => {
      let temp = [];
      let indexes = [];
      // Iterate rowsSelected:
      rowsSelected.forEach((row) => {
        // Add or remove row index to/from indexes arr:
        indexes = addToOrRemoveFromArray(row, indexes, "indexes");
        // Circle data:
        let circle_data = circles[row];
        // Add or remove circle_data to/from temp arr:
        temp = addToOrRemoveFromArray(circle_data, temp, "temp");
      });
      // Set indexes to local hook:
      setSelectionIndexes(indexes);
      // Send the circle data to redux:
      handleSelection(temp);
    }
  };

  const columns = [
    {
      name: "marker",
      label: "Marker",
      options: {
        filter: true,
        sort: false
      }
    },
    {
      name: "lat",
      label: "Latitude",
      options: {
        filter: true,
        sort: false
      }
    },
    {
      name: "lon",
      label: "Longitude",
      options: {
        filter: true,
        sort: false
      }
    },
    {
      name: "radius",
      label: "Radius",
      options: {
        filter: true,
        sort: false
      }
    }
  ];

  const table_name = `Circle Markers`;

  return (
    <>
      <div style={{ display: "table", tableLayout: "fixed", width: "100%" }}>
        <MUIDataTable
          title={<h3>{table_name}</h3>}
          data={circles}
          columns={columns}
          options={options}
        />
      </div>
    </>
  );
};

const mapStateToProps = (state) => {
  return {
    selections: state.selection.selections
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    handleSelection: (selections) => dispatch(handleSelection(selections))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Table);
 

Как я могу заставить флажок selectAll работать должным образом, когда выбрана строка за пределами отфильтрованных данных?

Ответ №1:

Можно ли отменить выбор выбранной строки при применении фильтров? Я сделал обходной путь для достижения желаемого поведения.

Живой код: CodeSandbox

Я добавил дополнительный код в строку 34 Table.jsx

 onFilterChange: (changedColumn, changedColumnIndex, displayData) => {
  changedColumnIndex.forEach((data, key) => {
    if (Array.isArray(data) amp;amp; data.length) {
      setSelectionIndexes([]);
    }
  });
},
 

Комментарии:

1. Это одно из решений, но оно, к сожалению, не соответствует тому, что мне нужно. Мне нужно, чтобы строка за пределами фильтров оставалась выбранной и чтобы ее можно было переключать с помощью флажка selectAll во время применения фильтров. У React-tables есть функциональность, но мне действительно нравятся MUI Datatables, и я уже проделал большую работу по его настройке для моего проекта, поэтому я бы предпочел не переключаться 😅.

2. Я вижу. Вы пытались добавлять выбранную строку в фильтры всякий раз, когда она была открыта? Возможно, это может сработать.