-1

I am trying to create a simple modal form using react. I have achieved something like this:

Click here to view Codesanbox

Index.js

import React from "react";
import ReactDOM from "react-dom";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Modal from "./components/Modal";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      modal1: false,
      modal2: false,
      name: "",
      modalInputName: ""
    };
  }

  handleChange(e) {
    const target = e.target;
    const name = target.name;
    const value = target.value;

    this.setState({
      [name]: value
    });
  }

  handleSubmit(e) {
    this.setState({ name: this.state.modalInputName });
    this.modalClose();
    this.modal2Close();
  }

  modalOpen() {
    this.setState({ modal1: true });
  }

  modalClose() {
    this.setState({
      modalInputName: "",
      modal1: false
    });
  }

  modal2Open() {
    this.setState({ modal2: true });
  }

  modal2Close() {
    this.setState({
      modalInputName: "",
      modal2: false
    });
  }

  render() {
    return (
      <div className="App">
        <h1>Hello!! {this.state.name}</h1>
        <a href="javascript:;" onClick={(e) => this.modalOpen(e)}>
          Open Modal
        </a>
        <Modal show={this.state.modal1} handleClose={(e) => this.modalClose(e)}>
          <h2>Hello Modal</h2>
          <div className="form-group">
            <label>Enter Name:</label>
            <input
              type="text"
              value={this.state.modalInputName}
              name="modalInputName"
              onChange={(e) => this.handleChange(e)}
              className="form-control"
            />
          </div>
          <div className="form-group">
            <button
              onClick={(e) => {
                this.handleSubmit(e);
                this.modal2Open(e);
              }}
              type="button"
            >
              Save
            </button>
            <Modal
              show={this.state.modal2}
              handleClose={(e) => this.modal2Close(e)}
            >
              <h2>Modal 2 - Confirmation</h2>
            </Modal>
          </div>
        </Modal>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

When I click on the 'save' button from the modal, it should save and show a thank you/confirmation message in another modal.

How to deal with multiple modals in such a scenario? Is it something I can achieve it modifying the Modal.js? Can someone guide me on how to implement that in the shared example?

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Geek
  • 127
  • 1
  • 12

4 Answers4

1

Actually, you have only one modal on your code. For showing another Modal by clicking the "Save" button, you can just implement the same way you are showing the "Hello Modal" modal when clicking "Open Modal".

You will need two separate states to handle two separate Modal.

  • I tried and updated the separate states. Am I doing anything wrong here? https://codesandbox.io/s/simple-modal-box-with-react-forked-0nlcr?file=/src/index.js by – Geek Oct 29 '21 at 01:59
  • 1
    You can move your second `` outside of your first ``. As you have nested the second one inside of the first one, due to which the second modal is not displayed. – Sabita Neupane Oct 29 '21 at 05:32
1

You can create as many modals as you need and show/hide setting proper state. E.g.:

...
<Modal show={this.state.shouldShowInputModal} ...>
modal content
</Modal>
<Modal show={this.state.shouldShowConfirmationModal} ...>
confirmation modal content
</Modal>
...
1

Now entering the name and clicking save, will close Modal1 and open Modal2. This may not be useful if you are looking for a Modal above a Modal. You could search for something like Modal above modal in Google if this didn't help.

import React from "react";
import ReactDOM from "react-dom";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Modal from "./components/Modal";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      modal1: false,
      modal2: false,
      name: "",
      modalInputName: ""
    };
  }

  handleChange(e) {
    const target = e.target;
    const name = target.name;
    const value = target.value;

    this.setState({
      [name]: value
    });
  }

  handleSubmit(e) {
    this.setState({ name: this.state.modalInputName });
    this.modalClose();
    this.modal2Close();
  }

  modalOpen() {
    this.setState({ modal1: true });
  }

  modalClose() {
    this.setState({
      modalInputName: "",
      modal1: false
    });
  }

  modal2Open() {
    this.setState({ modal2: true });
  }

  modal2Close() {
    this.setState({
      modalInputName: "",
      modal2: false
    });
  }

  render() {
    return (
      <div className="App">
        <h1>Hello!! {this.state.name}</h1>
        <a href="javascript:;" onClick={(e) => this.modalOpen(e)}>
          Open Modal
        </a>
        <Modal show={this.state.modal1} handleClose={(e) => this.modalClose(e)}>
          <h2>Hello Modal</h2>
          <div className="form-group">
            <label>Enter Name:</label>
            <input
              type="text"
              value={this.state.modalInputName}
              name="modalInputName"
              onChange={(e) => this.handleChange(e)}
              className="form-control"
            />
          </div>
          <div className="form-group">
            <button
              onClick={(e) => {
                this.handleSubmit(e);
                this.modal2Open(e);
              }}
              type="button"
            >
              Save
            </button>
          </div>
        </Modal>
        <Modal
          show={this.state.modal2}
          handleClose={(e) => this.modal2Close(e)}
        >
          <h2>Modal 2 - Confirmation</h2>
        </Modal>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
samcodee
  • 103
  • 13
1

Instead of having 2 nested modals, why not have only one with two sub screens which you can navigate between via state?

import React from "react";
import ReactDOM from "react-dom";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Modal from "./components/Modal";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      modal: false,
      modalScreen: 0,
      name: "",
      modalInputName: ""
    };
  }

  handleChange = (e) => {
    const { name, value } = e.target;
    this.setState({
      [name]: value
    });
  };

  handleSubmit = () => {
    this.setState({ name: this.state.modalInputName, modalScreen: 1 });
  };

  modalOpen = () => {
    this.setState({ modal: true });
  };

  modalClose = () => {
    this.setState({
      modalInputName: "",
      modal: false,
      modalScreen: 0
    });
  };

  render() {
    const { name, modal, modalScreen } = this.state;
    return (
      <div className="App">
        <h1>Hello!! {name}</h1>
        <button onClick={this.modalOpen}>Open Modal</button>
        <Modal show={modal} handleClose={(e) => this.modalClose(e)}>
          {modalScreen === 0 && (
            <>
              <h2>Hello Modal</h2>
              <div className="form-group">
                <label>Enter Name:</label>
                <input
                  type="text"
                  value={this.state.modalInputName}
                  name="modalInputName"
                  onChange={(e) => this.handleChange(e)}
                  className="form-control"
                />
              </div>
              <div className="form-group">
                <button onClick={this.handleSubmit} type="button">
                  Save
                </button>
              </div>
            </>
          )}
          {modalScreen === 1 && (
            <>
              <h2>Modal 2 - Confirmation</h2>
            </>
          )}
        </Modal>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Simple Modal Box with React (forked)

ksav
  • 20,015
  • 6
  • 46
  • 66