4
votes

Ligne de table Material-ui onCliquez sur contourner pour sélectionner la case à cocher

J'utilise la table de données material-ui pour le tri. Cela incorpore une case à cocher sur chaque ligne. J'ai fait en sorte que chaque ligne renvoie un clic vers un lien.

Cependant, je ne veux pas que la case à cocher agisse comme un clic et je souhaite qu'elle se comporte comme une case à cocher et que j'ajoute la ligne à la sélection. Mais lorsque vous cliquez sur la case à cocher, le lien de ligne est renvoyé.

Je dois exclure cette cellule du lien de ligne ou d'une manière ou d'une autre pour exclure la case.

https://codesandbox.io/s/rlkv87vor4

Voici ce que j'ai essayé pour la logique: p>

Gestionnaire de clics

<TableCell padding="checkbox">
  <Checkbox className="selectCheckbox" checked={isSelected} />
</TableCell>

Dans mon demo lien de ligne est toujours renvoyé lorsque vous cochez la case.

if (event.target.classList.contains('selectCheckbox')) {
  return console.log('checkbox select');
  } else {
  return console.log('row link');
}


0 commentaires

3 Réponses :


1
votes

5 commentaires

il renvoie toujours "lien de ligne" et non "sélection de case à cocher", donc dans mon cas, cela me mènerait à une autre vue plutôt que de simplement cocher la case


d'accord, le titre était un peu trompeur, je pensais que vous vous inquiétiez du fait que le clic soit contourné. laisse moi regarder à nouveau


className est une propriété valide pour tout élément DOM et les documents que vous avez référencés indiquent "Toutes les autres propriétés fournies seront réparties sur l'élément racine (élément natif)."


Je n'ai pas trouvé le className sur la cible de l'événement. Cela pourrait être un bug? J'ai essayé le bon vieux console.log () @RyanCogswell


Le className est appliqué à la span la plus externe qui encapsule l'entrée de la case à cocher. La structure globale créée est .



12
votes

Le moyen le plus simple de résoudre ce problème est d'avoir deux méthodes handleClick distinctes pour la case à cocher et la ligne (par exemple, handleCheckboxClick et handleRowClick ).

Dans handleCheckboxClick , vous pouvez alors appeler event.stopPropagation (); afin d'éviter que handleRowClick ne soit appelé. p >

Ainsi, les parties suivantes de EnhancedTable passeraient de:

  handleCheckboxClick = (event, id) => {
    event.stopPropagation();
    console.log("checkbox select");
    const { selected } = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1)
      );
    }

    this.setState({ selected: newSelected });
  };
  handleRowClick = (event, id) => {
    console.log("row link");
  };
...
<TableRow
  hover
  onClick={event => this.handleRowClick(event, n.id)}
  role="checkbox"
  aria-checked={isSelected}
  tabIndex={-1}
  key={n.id}
  selected={isSelected}
>
  <TableCell className="selectCheckbox" padding="checkbox">
    <Checkbox
      onClick={event =>
        this.handleCheckboxClick(event, n.id)
      }
      className="selectCheckbox"
      checked={isSelected}
    />

à quelque chose comme ce qui suit:

  handleClick = (event, id) => {
    if (event.target.classList.contains("selectCheckbox")) {
      console.log("checkbox select");
    } else {
      console.log("row link");
    }

    const { selected } = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1)
      );
    }

    this.setState({ selected: newSelected });
  };
...
<TableRow
  hover
  onClick={event => this.handleClick(event, n.id)}
  role="checkbox"
  aria-checked={isSelected}
  tabIndex={-1}
  key={n.id}
  selected={isSelected}
>
  <TableCell className="selectCheckbox" padding="checkbox">
    <Checkbox
      onClick={event => this.handleClick(event, n.id)}
      className="selectCheckbox"
      checked={isSelected}
    />
  </TableCell>

Voici un CodeSandbox montrant cette approche:

 Edit Material demo


4 commentaires

@MalikBrahimi Je vous recommande de créer votre propre question distincte qui montre comment reproduire votre problème.


J'ai compris mon problème. J'utilisais onChange au lieu de onClick. Savez-vous quelle est la nuance entre eux pour une case à cocher?


@MalikBrahimi La ligne répond à l'événement de clic. La ligne n'a pas d'événement onChange, donc l'arrêt de la propagation de l'événement onChange pour la case à cocher n'aura aucun effet sur la propagation de l'événement de clic à la ligne.


@MalikBrahimi En ce qui concerne la différence entre les événements pour les cases à cocher, elle est traitée ailleurs (par exemple stackoverflow.com/questions/5575338/... ).



1
votes

Ajoutez simplement onClick sur la case à cocher et appelez e.stopPropagation (); pour éviter d'appeler onClick deux fois depuis la case à cocher et depuis le composant de ligne!

  <TableRow
                      hover
                      onKeyDown={event => this.handleKeyDown(event, n.id)}
                      role="checkbox"
                      aria-checked={isSelected}
                      tabIndex={-1}
                      key={n.id}
                      onClick={event => onMore(event, n.id)}
                      selected={isSelected}
                    >

                      <TableCell padding="checkbox">
                        <Checkbox color="primary" checked={isSelected}
                                  onClick={event => this.handleClick(event, n.id)}/>
                      </TableCell>
</TableRow>
handleClick = (event, id) => {
    event.stopPropagation();

    const {selected} = this.state;
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1),
      );
    }

    this.setState({selected: newSelected});
  };


0 commentaires