2 votes

Impossible de déclencher une modale à partir d'un bouton dans une ligne de tableau en React

J'ai deux fichiers : Modal.js y Users.js . Users.js contient une table à laquelle est associée une requête API get. Dans la dernière colonne de la table se trouve une liste déroulante pour chaque ligne qui contient trois boutons : Afficher, Modifier et Supprimer. J'aimerais que le bouton Supprimer déclenche la modale contenant un message qui se lit en gros comme suit : "Êtes-vous sûr de vouloir supprimer l'utilisateur ?".

J'ai du mal à faire en sorte que la fenêtre modale se déclenche dans l'événement onClick du composant Supprimer dans l'interface utilisateur. Users.js je vais joindre le code des deux fichiers ci-dessous.

Modal.js (Je n'ai pas encore modifié le contenu de la modale).

import {
  CButton,
  CModal,
  CModalHeader,
  CModalTitle,
  CModalBody,
  CModalFooter,
} from "@coreui/react";

const Modal = ({ visible, setVisible }) => {
  return (
    <>
      <CModal visible={visible} onClose={() => setVisible(false)}>
        <CModalHeader onClose={() => setVisible(false)}>
          <CModalTitle>Modal title</CModalTitle>
        </CModalHeader>
        <CModalBody>Woohoo, you're reading this text in a modal!</CModalBody>
        <CModalFooter>
          <CButton color="secondary" onClick={() => setVisible(false)}>
            Close
          </CButton>
          <CButton color="primary">Save changes</CButton>
        </CModalFooter>
      </CModal>
    </>
  );
};

export default Modal;

Utilisateurs.js

<CTableRow v-for="item in tableItems" key={rows.userID}>
  <CTableDataCell className="text-center">{rows.userID}</CTableDataCell>
  <CTableDataCell>{rows.firstName}</CTableDataCell>
  <CTableDataCell>
    <div>{rows.lastName}</div>
  </CTableDataCell>
  <CTableDataCell className="column-overflow">{rows.email}</CTableDataCell>
  <CTableDataCell>{rows.role}</CTableDataCell>
  <CTableDataCell>{rows.createdAt}</CTableDataCell>
  <CTableDataCell>{rows.updatedAt}</CTableDataCell>

  <CTableDataCell>
    <strong>{rows.lastLogin}</strong>
  </CTableDataCell>
  <CTableDataCell>
    <CDropdown>
      <CDropdownToggle color="transparent"></CDropdownToggle>
      <CDropdownMenu>
        <CDropdownItem className="dropdown-item pointer">View</CDropdownItem>
        <CDropdownItem className="dropdown-item pointer">Edit</CDropdownItem>

        <CDropdownItem
          className="dropdown-item text-danger pointer"
          onClick={() => Modal()} <- Issue here
        >
          Delete
        </CDropdownItem>
      </CDropdownMenu>
    </CDropdown>
  </CTableDataCell>
</CTableRow>;

J'apprécierais toute aide à ce sujet. Faites-moi savoir si je peux donner d'autres codes (j'ai réduit le fichier Users.js car il fait un peu plus de 160 lignes et je ne veux pas encombrer, à l'exception de la ligne pour que vous puissiez avoir une idée de l'emplacement du bouton Supprimer).

Merci d'avance !

1voto

Steve Gomez Points 3802

Le site Modal doit se trouver dans la page avec un visible prop contrôlé par le parent (et non appelé comme une fonction). Le site Exemples de CoreUI pour CModal sont un peu trompeuses pour votre cas d'utilisation. Je suggère d'utiliser useState dans votre parent Users et en passant un callback setter au composant Modal pour l'événement de clôture.

Par exemple :

Utilisateurs.js

const Users = () => {
  const [visible, setVisible] = React.useState(false);
  const [selectedUser, setSelectedUser] = React.useState(null);

  const rows = [
    { userID: "1", firstName: "Cameron", lastName: "E" },
    { userID: "2", firstName: "Steve", lastName: "G" }
  ];

  return (
    <>
      <CTable>
        {rows.map((row) => {
          return (
            <CTableRow v-for="item in tableItems" key={row.userID}>
              <CTableDataCell className="text-center">
                {row.userID}
              </CTableDataCell>
              <CTableDataCell>{row.firstName}</CTableDataCell>
              <CTableDataCell>
                <div>{row.lastName}</div>
              </CTableDataCell>
              <CTableDataCell className="column-overflow">
                {row.email}
              </CTableDataCell>
              <CTableDataCell>{row.role}</CTableDataCell>
              <CTableDataCell>{row.createdAt}</CTableDataCell>
              <CTableDataCell>{row.updatedAt}</CTableDataCell>

              <CTableDataCell>
                <strong>{row.lastLogin}</strong>
              </CTableDataCell>
              <CTableDataCell>
                <CDropdown>
                  <CDropdownToggle color="transparent">
                    Dropdown button
                  </CDropdownToggle>
                  <CDropdownMenu>
                    <CDropdownItem className="dropdown-item pointer">
                      View
                    </CDropdownItem>
                    <CDropdownItem className="dropdown-item pointer">
                      Edit
                    </CDropdownItem>

                    <CDropdownItem
                      className="dropdown-item text-danger pointer"
                      onClick={() => {
                        setSelectedUser(row);
                        setVisible(true);
                      }}
                    >
                      Delete
                    </CDropdownItem>
                  </CDropdownMenu>
                </CDropdown>
              </CTableDataCell>
            </CTableRow>
          );
        })}
      </CTable>
      <Modal
        visible={visible}
        user={selectedUser}
        onClose={() => setVisible(false)}
      />
    </>
  );
};

Modal.js

const Modal = ({ visible, onClose, user }) => {
  return (
    <>
      <CModal visible={visible} onClose={onClose}>
        <CModalHeader onClose={onClose}>
          <CModalTitle>Delete {user.firstName}?</CModalTitle>
        </CModalHeader>
        <CModalBody>
          Are you sure you want to delete {user.firstName}? (He's a good guy.)
        </CModalBody>
        <CModalFooter>
          <CButton color="secondary" onClick={onClose}>
            Yeah he is a good guy
          </CButton>
          <CButton color="primary">Nuke 'Em!</CButton>
        </CModalFooter>
      </CModal>
    </>
  );
};

Note : En prime, j'ai ajouté un exemple de transmission de l'utilisateur sélectionné à la fonction Modal donc une seule instance de la Modal existe dans la page.

CodeSandbox de travail : https://codesandbox.io/s/cold-leftpad-l5ivqy?file=/src/Modal.js

Users.js rendu Users.js Rendered

Rendu de Modal.js Modal.js Rendered

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X