How can I connect between my form and modal?

Viewed 57

I made a form project with react. My form is working well for now but I want add bootstrap modal to my form.

When I click the enter button, I want to show a modal. I found modal example on the web but I can't establish connection between form and modal. This is my form

import React from "react";
import { useState } from "react";


const Contact = () => {
  const [showModal, setShowModal] = useState(false);
  const [inputValue, setInputValue] = useState("");
  const [emailValue, setEmailValue] = useState("");
  const [phoneNumberValue, setPhoneValue] = useState("");
  const [countryValue, setCountryValue] = useState("");

  const buttonOnClick = () => {
    if (inputValue === "" || emailValue === "" || phoneNumberValue === "") {
      setShowModal(false)
    } else {
      setShowModal(true)
      setInputValue("")
    }
    console.log(`Form submitted, ${showModal}`);
  }


  return (
    <div className="main">

      <form >
        <div className="baslik">
          <div className="container center">
            <h1>Contact Form</h1>
          </div>
        </div>
        <div className="field" >
          <label className="text"> Name And Surname: </label>
          <input type="text" className="form" placeholder="Kerem Kurt" required value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
        </div>

        <div className="field">
          <label className="text"> E-mail: </label>
          <input type="email" className="form" placeholder="udenditfy@gmail.com" required value={emailValue} onChange={(e) => setEmailValue(e.target.value)} />
        </div>

        <div className="field">
          <label className="text"> Phone Number: </label>
          <input type="tel" className="form" pattern="[0-9]*" placeholder="+905373199437" required value={phoneNumberValue} onChange={(e) => setPhoneValue(e.target.value)} />
        </div>

        <div className="field">
          <label className="text" required > Country: </label>
          <select className="form" placeholder="Turkiye" required value={countryValue} onChange={(e) => setCountryValue(e.target.value)}>
            <option value="Turkiye">Turkiye</option>
            <option value="Azerbaijan">Azerbaijan</option>
            <option value="Japan">Japan</option>
            <option value="Serbia">Serbia</option>
            <option value="France">France</option>
          </select>
        </div>

        <button type="button" className="button" onClick={() => buttonOnClick()}> Enter </button>
      </form>
    </div>

  );
};
export default Contact;

And this is modal codes;

 import React, { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';


function Example() {
  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <>
      <Button variant="primary" onClick={handleShow}>
        Launch static backdrop modal
      </Button>

      <Modal
        show={show}
        onHide={handleClose}
        backdrop="static"
        keyboard={false}
      >
        <Modal.Header closeButton>
          <Modal.Title>Modal title</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          I will not close if you click outside me. Don't even try to press
          escape key.
        </Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
          <Button variant="primary">Understood</Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

render(<Example />);
2 Answers

If you want to open your modal after the event "click" in your Form component, you have to import the modal in your form.

For example, your Form is in a component called "Form.jsx" and Modal is in "Modal.jsx" :

Inside Form.jsx, you must import your Modal, move the "show" state into your Form.jsx and pass it in Modal props, just like that :

import Modal from '/path/to/Modal.jsx'

const [show, setShow] = useState(false);


<form>
{children}
</form>

<Modal show={show} setShow={setShow}/>

Inside your Modal.jsx, just change a few things :

function Modal(props){
// remove the show State
// Remove the Button with "handleShow" function.
const handleClose = () => props.setShow(false);

<Modal show={props.show}>
<Button onClick={handleClose}>Close</Button>
</Modal>
}


Welcome to world of react development!

Your question is a classic question about sharing state between components. This is what you refer to as "connection" between components.

The solution is generally referred to as "lifting state up". I highly recommend reading through that if you haven't already.

Example:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { useState } from "react";
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';

const root = ReactDOM.createRoot(document.getElementById('root'));

const Contact = ({toggleShow}) => {
  return (
    <div className="main">
      <form >
        <button type="button" className="button" onClick={() => toggleShow()}> Show Modal </button>
      </form>
    </div>
  );
};


const MyModal = ({show, toggleShow}) => {
  return (
    <>
      <Modal
        show={show}
        onHide={toggleShow}
        backdrop="static"
        keyboard={false}
      >
        <Button variant="secondary" onClick={toggleShow}>
          Close
        </Button>
      </Modal>
    </>
  );
}

const App = () => {
    
  const [show, setShow] = useState(false);
  const toggleShow = () => setShow(!show);

  return (
    <>
      <Contact toggleShow={toggleShow}/>
      <MyModal show={show} toggleShow={toggleShow}/>   
    </>
  )
}

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Explanation:

The general idea is to share the show state of the Modal as well as the state toggler toggleShow() between our <Contact> and <MyModal> components.

We can easily achieve this:

  • create a new parent component <App> (the name is arbitrary) where we define the show state and the toggler function.
  • pass the state and toggler into the modal: <MyModal state={state} toggleShow={toggleShow} />.
  • the form only needs the toggler: <Form toggleShow={toggleShow} />

Note that toggleShow can also be split into separate handleShow and handleClose function, but this approach saves us a few lines.

Related