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'); }
3 Réponses :
Il y a donc plusieurs problèmes ici.
1) Le className n'est pas une propriété valide pour l'API Checkbox https://material-ui.com/api/checkbox/#checkbox-api < / a>
2) console.log (event.target)
montre que le clic réel se produit sur une étiquette svg utilisée pour styliser l'entrée et non l'entrée elle-même. Ainsi, vous ne pouvez pas non plus utiliser directement inputProps = {{className: "selectedCheckbox"}} et capturer le même depuis la classList
Vous pouvez faire référence à ce bac à sable et voir comment obtenir le résultat souhaité si vous cliquez réellement sur input
: https://codesandbox.io/s/r7j4j638qn
Donc, une réponse possible est de modifier la propriété icon
du composant Checkbox
et de la définir sur une icône personnalisée avec la classe spécifiée? Ensuite, cela devrait fonctionner comme prévu.
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
.
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:
@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/... ).
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}); };