Выбор строки на клике

Я пытаюсь найти лучшую таблицу для использования с моими приложениями реагирования, и на данный момент таблица реакции предлагает все, что мне нужно (нумерация страниц, управление на стороне сервера, фильтрация, сортировка, строка нижнего колонтитула).

При этом я не могу выбрать строку. Там нет примеров, которые показывают это.

Некоторые вещи, которые я пробовал, включают попытки установить className по щелчку строки. Но я не могу найти вызывающий элемент в e или t. Кроме того, мне не нравится этот подход, потому что это не то, как реагирующее приложение должно делать вещи.

<ReactTable
            ...
            getTrProps={(state, rowInfo, column, instance) => {
                return {
                    onClick: (e, t) => {
                        t.srcElement.classList.add('active')
                    },
                    style: {
                    }
                }
            }}
        />

Некоторым возможным обходным решением может быть рендеринг флажков в качестве первого столбца, но это не оптимально, поскольку ограничивает область, по которой нужно щелкнуть, чтобы "активировать" строку. Также визуальная обратная связь будет менее выразительной.

Я скучаю по слону в комнате? А если нет, знаете ли вы другую библиотеку, которая поддерживает вещи, которые я описал ранее?

Спасибо!

РЕДАКТИРОВАТЬ: Другой вариант, с открытым исходным кодом, это предложить редактирование. И, возможно, это правильная вещь.

РЕДАКТИРОВАТЬ 2

Еще одна вещь, предложенная Даворином Рушевляном в комментариях, но я не могла заставить это работать:

onRowClick(e, t, rowInfo) {
    this.setState((oldState) => {
        let data = oldState.data.slice();
        let copy = Object.assign({},  data[rowInfo.index]);

        copy.selected = true;
        copy.FirstName = "selected";
        data[rowInfo.index] = copy;

        return {
            data: data,
        }
    })
}

....

            getTrProps={(state, rowInfo, column) => {
                return {
                    onClick: (e, t) => { this.onRowClick(e, t, rowInfo) },
                    style: {
                        background: rowInfo && rowInfo.row.selected ? 'green' : 'red'
                    }
                }
            }}

Это устанавливает столбец "FirstName" в "selected", но не устанавливает класс в "green"

Ответ 1

Я нашел решение после нескольких попыток, надеюсь, это поможет вам. Добавьте следующее в ваш компонент <ReactTable>:

getTrProps={(state, rowInfo) => {
  if (rowInfo && rowInfo.row) {
    return {
      onClick: (e) => {
        this.setState({
          selected: rowInfo.index
        })
      },
      style: {
        background: rowInfo.index === this.state.selected ? '#00afec' : 'white',
        color: rowInfo.index === this.state.selected ? 'white' : 'black'
      }
    }
  }else{
    return {}
  }
}

В вашем state не забудьте добавить нулевое selected значение, например:

state = { selected: null }

Ответ 2

В React-Table включен HOC, который позволяет выбирать, даже при фильтрации и разбивке на страницы таблицы, настройка немного сложнее, чем в базовой таблице, поэтому сначала прочтите информацию по ссылке ниже.


enter image description here



После импорта HOC вы можете использовать его следующим образом:

/**
* Toggle a single checkbox for select table
*/
toggleSelection(key: number, shift: string, row: string) {
    // start off with the existing state
    let selection = [...this.state.selection];
    const keyIndex = selection.indexOf(key);

    // check to see if the key exists
    if (keyIndex >= 0) {
        // it does exist so we will remove it using destructing
        selection = [
            ...selection.slice(0, keyIndex),
            ...selection.slice(keyIndex + 1)
        ];
    } else {
        // it does not exist so add it
        selection.push(key);
    }
    // update the state
    this.setState({ selection });
}

/**
* Toggle all checkboxes for select table
*/
toggleAll() {
    const selectAll = !this.state.selectAll;
    const selection = [];

    if (selectAll) {
        // we need to get at the internals of ReactTable
        const wrappedInstance = this.checkboxTable.getWrappedInstance();
        // the 'sortedData' property contains the currently accessible records based on the filter and sort
        const currentRecords = wrappedInstance.getResolvedState().sortedData;
        // we just push all the IDs onto the selection array
        currentRecords.forEach(item => {
            selection.push(item._original._id);
        });
    }
    this.setState({ selectAll, selection });
}

/**
* Whether or not a row is selected for select table
*/
isSelected(key: number) {
    return this.state.selection.includes(key);
}

<CheckboxTable
    ref={r => (this.checkboxTable = r)}
    toggleSelection={this.toggleSelection}
    selectAll={this.state.selectAll}
    toggleAll={this.toggleAll}
    selectType="checkbox"
    isSelected={this.isSelected}
    data={data}
    columns={columns}
/>

Смотрите здесь для более подробной информации:
https://github.com/tannerlinsley/react-table/tree/v6#selecttable

Вот рабочий пример:
https://codesandbox.io/s/react-table-select-j9jvw

Ответ 3

Я не знаком с таблицей реагирования, поэтому не знаю, имеет ли он прямую поддержку для выбора и отмены выбора (было бы неплохо, если бы он имел).

Если этого не произойдет, то с уже имеющимся фрагментом кода вы можете установить обработчик onCLick. Теперь вместо того, чтобы пытаться прикрепить стиль непосредственно к строке, вы можете изменить состояние, например, добавив selected: true к данным строки. Это вызвало бы повторное рендеринг. Теперь вам нужно только переопределить способ отображения строк с выбранным === true. Что-то вроде строк:

// Any Tr element will be green if its (row.age > 20) 
<ReactTable
  getTrProps={(state, rowInfo, column) => {
    return {
      style: {
        background: rowInfo.row.selected ? 'green' : 'red'
      }
    }
  }}
/>

Ответ 4

если u хочет иметь множественный выбор в строке выбора.

import React from 'react';
import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { ReactTableDefaults } from 'react-table';
import matchSorter from 'match-sorter';


class ThreatReportTable extends React.Component{

constructor(props){
  super(props);

  this.state = {
    selected: [],
    row: []
  }
}
render(){

  const columns = this.props.label;

  const data = this.props.data;

  Object.assign(ReactTableDefaults, {
    defaultPageSize: 10,
    pageText: false,
    previousText: '<',
    nextText: '>',
    showPageJump: false,
    showPagination: true,
    defaultSortMethod: (a, b, desc) => {
    return b - a;
  },


  })

    return(
    <ReactTable className='threatReportTable'
        data= {data}
        columns={columns}
        getTrProps={(state, rowInfo, column) => {


        return {
          onClick: (e) => {


            var a = this.state.selected.indexOf(rowInfo.index);


            if (a == -1) {
              // this.setState({selected: array.concat(this.state.selected, [rowInfo.index])});
              this.setState({selected: [...this.state.selected, rowInfo.index]});
              // Pass props to the React component

            }

            var array = this.state.selected;

            if(a != -1){
              array.splice(a, 1);
              this.setState({selected: array});


            }
          },
          // #393740 - Lighter, selected row
          // #302f36 - Darker, not selected row
          style: {background: this.state.selected.indexOf(rowInfo.index) != -1 ? '#393740': '#302f36'},


        }


        }}
        noDataText = "No available threats"
        />

    )
}
}


  export default ThreatReportTable;

Ответ 5

Другим механизмом динамического моделирования является его определение в JSX для вашего компонента. Например, следующее может быть использовано для селективного стиля текущего шага в React крестики-нолики учебник (один из предложенных дополнительных усовершенствований кредита:

  return (
    <li key={move}>
      <button style={{fontWeight:(move === this.state.stepNumber ? 'bold' : '')}} onClick={() => this.jumpTo(move)}>{desc}</button>
    </li>
  );

Разумеется, более чистым подходом было бы добавить/удалить "выбранный" класс CSS, но в некоторых случаях этот прямой подход может оказаться полезным.

Ответ 6

Выбранный вами ответ является правильным, однако, если вы используете таблицу сортировки, она вылетит, так как rowInfo станет неопределенным при поиске, рекомендую использовать эту функцию вместо

                getTrGroupProps={(state, rowInfo, column, instance) => {
                    if (rowInfo !== undefined) {
                        return {
                            onClick: (e, handleOriginal) => {
                              console.log('It was in this row:', rowInfo)
                              this.setState({
                                  firstNameState: rowInfo.row.firstName,
                                  lastNameState: rowInfo.row.lastName,
                                  selectedIndex: rowInfo.original.id
                              })
                            },
                            style: {
                                cursor: 'pointer',
                                background: rowInfo.original.id === this.state.selectedIndex ? '#00afec' : 'white',
                                color: rowInfo.original.id === this.state.selectedIndex ? 'white' : 'black'
                            }
                        }
                    }}
                }

Ответ 7

Несколько строк с флажками и выберите все, используя крючки useState(). Требуется небольшая реализация для адаптации к собственному проекту.

    const data;
    const [ allToggled, setAllToggled ] = useState(false);
    const [ toggled, setToggled ] = useState(Array.from(new Array(data.length), () => false));
    const [ selected, setSelected ] = useState([]);

    const handleToggleAll = allToggled => {
        let selectAll = !allToggled;
        setAllToggled(selectAll);
        let toggledCopy = [];
        let selectedCopy = [];
        data.forEach(function (e, index) {
            toggledCopy.push(selectAll);
            if(selectAll) {
                selectedCopy.push(index);
            }
        });
        setToggled(toggledCopy);
        setSelected(selectedCopy);
    };

    const handleToggle = index => {
        let toggledCopy = [...toggled];
        toggledCopy[index] = !toggledCopy[index];
        setToggled(toggledCopy);
        if( toggledCopy[index] === false ){
            setAllToggled(false);
        }
        else if (allToggled) {
            setAllToggled(false);
        }
    };

....


                Header: state => (
                    <input
                        type="checkbox"
                        checked={allToggled}
                        onChange={() => handleToggleAll(allToggled)}
                    />
                ),
                Cell: row => (
                    <input
                        type="checkbox"
                        checked={toggled[row.index]}
                        onChange={() => handleToggle(row.index)}
                    />
                ),

....

<ReactTable

...
                    getTrProps={(state, rowInfo, column, instance) => {
                        if (rowInfo && rowInfo.row) {
                            return {
                                onClick: (e, handleOriginal) => {
                                    let present = selected.indexOf(rowInfo.index);
                                    let selectedCopy = selected;

                                    if (present === -1){
                                        selected.push(rowInfo.index);
                                        setSelected(selected);
                                    }

                                    if (present > -1){
                                        selectedCopy.splice(present, 1);
                                        setSelected(selectedCopy);
                                    }

                                    handleToggle(rowInfo.index);
                                },
                                style: {
                                    background: selected.indexOf(rowInfo.index)  > -1 ? '#00afec' : 'white',
                                    color: selected.indexOf(rowInfo.index) > -1 ? 'white' : 'black'
                                },
                            }
                        }
                        else {
                            return {}
                        }
                    }}
/>