Home > Software design >  How can I connect between my form and modal?
How can I connect between my form and modal?

Time:08-10

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="[email protected]" 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 />);

CodePudding user response:

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


CodePudding user response:

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