web-dev-qa-db-fra.com

Sélectionnez la ligne sur la table de réaction au clic

J'essaie de trouver la meilleure table à utiliser avec mes applications de réaction et pour l'instant, le react-table offre tout ce dont j'ai besoin (pagination, contrôle côté serveur, filtrage, tri, rangée de pied de page).

Ceci étant dit, je n'arrive pas à sélectionner une ligne. Il n'y a pas exemples qui le montrent. 

Certaines choses, que j'ai essayées, incluent d'essayer de définir un nom de classe en cliquant sur la ligne. Mais je n'arrive pas à trouver l'élément appelant dans e ni t. De plus, je n'aime pas cette approche, car ce n'est pas comme ça qu'une application de réaction devrait faire les choses.

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

Une solution de contournement possible consisterait à afficher les cases à cocher dans une première colonne, mais cela n’est pas optimal car cela limite la zone à cliquer pour «activer» la ligne. En outre, le retour visuel sera moins expressif. 

Est-ce que je manque l'éléphant dans la pièce? Et si non, connaissez-vous une autre bibliothèque qui supporte les choses que j'ai décrites précédemment?

Je vous remercie! 

EDIT: Une autre option, celle-ci étant open source, consiste à suggérer une modification. Et peut-être que c'est la bonne chose à faire.

EDIT 2

Une autre chose, suggérée par Davorin Ruševljan dans les commentaires, mais je ne pouvais pas le faire fonctionner était:

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'
                    }
                }
            }}

Ceci définit la colonne 'Prénom' sur 'sélectionnée', mais ne définit pas la classe sur 'vert'

27
gyosifov

J'ai trouvé la solution après quelques essais, j'espère que cela pourra vous aider. Ajoutez les éléments suivants à votre composant <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 {}
  }
}

Dans votre state, n'oubliez pas d'ajouter une valeur null selected, comme:

state = { selected: null }
38
Constantin Guidon

Il existe un HOC inclus pour React-Table qui permet la sélection, même lors du filtrage et de la pagination du tableau. La configuration est légèrement plus avancée que le tableau de base. Lisez donc les informations dans le lien ci-dessous en premier.


 enter image description here



Après avoir importé le HOC, vous pouvez l’utiliser comme ceci avec les méthodes nécessaires:

/**
* 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}
/>

Voir ici pour plus d'informations:
https://github.com/react-tools/react-table/tree/master/src/hoc#selecttable

Voici un exemple de travail:
https://react-table.js.org/#/story/select-table-hoc

5
Alex

Je ne connais pas bien, react-table, donc je ne sais pas qu’il dispose d’un appui direct pour la sélection et la désélection (ce serait bien Nice si c’était le cas).

Si ce n'est pas le cas, avec le morceau de code que vous avez déjà, vous pouvez installer le gestionnaire onCLick. Désormais, au lieu d’essayer d’attacher un style directement à une ligne, vous pouvez modifier l’état, en ajoutant par exemple selected: true aux données de la ligne. Cela déclencherait le re-rendu. Maintenant, il vous suffit de remplacer les lignes avec le rendu sélectionné === true. Quelque chose dans les lignes de:

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

si vous voulez avoir plusieurs sélections sur la ligne sélectionnée ..

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;
2
Jun Bin

Un autre mécanisme de style dynamique consiste à le définir dans le fichier JSX pour votre composant. Par exemple, les éléments suivants pourraient être utilisés pour styliser de manière sélective l’étape en cours dans le didacticiel Reactic-Tac-Toe (l’une des améliorations de crédit supplémentaires suggérées:

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

Certes, une approche plus propre consisterait à ajouter/supprimer une classe CSS "sélectionnée", mais cette approche directe pourrait être utile dans certains cas.

1
eric gilbertson

La réponse que vous avez sélectionnée est correcte. Toutefois, si vous utilisez une table de tri, elle plantera, car rowInfo deviendra indéfinie au fur et à mesure de votre recherche. Il est donc recommandé d'utiliser cette fonction.

                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'
                            }
                        }
                    }}
                }
0