Home > other >  How to make modal step by step in react
How to make modal step by step in react

Time:02-04

I wrote a modal form in react using bootstrap and I want this modal to be in 2 steps

I also wrote the functions, but I don't know how to use it

  const [formStage, setFormStage] = useState(0)

  function nextStage(e) {
    e.preventDefault()
    setFormStage(() => formStage   1)
  }

  function previousStage(e) {
    e.preventDefault()
    setFormStage(() => formStage - 1)
  }

When you click on next, the next modal will open and when you click on back, the previous modal will open

But I don't know how to do this using state

This is the first modal and I want it to go to the next modal when next is clicked:

    <>
      <div className="btn btn-primary" data-toggle="modal" data-target="#Profile">
        button
      </div>

      <div  id="Profile" aria-hidden="true">
        <div >
          <div >
            <div >
              <h5 >Header</h5>

              <button
                type="button"
                
                data-dismiss="modal"
                aria-label="Close"
              >
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            <div>
              <form>
                <div >
                  <div className="input-group mt-2">
                    <label for="recipient-name" className="input-label">
                      name
                    </label>
                    <input
                      name="myName"
                      type="text"
                      className="input-element"
                    />
                  </div>
                </div>
              </form>
            </div>
            <div >
              <button type="button"  data-dismiss="modal" aria-label="Close">
                Close
              </button>
              <button type="button"  onClick={() => {}} >
                Next
              </button>
            </div>
          </div>
        </div>
      </div>
    </>

the below form will replace the previous one , and replace the back button instead of the close button

              <form>
                <div >
                  <div className="input-group mt-2">
                    <label for="recipient-name" className="input-label">
                      Family
                    </label>
                    <input
                      name="myFamily"
                      type="text"
                      className="input-element"
                    />
                  </div>
                </div>
              </form>
            </div>
            <div >
              <button type="button"  onClick={() => {}}>
                Back
              </button>
              <button type="button"  onClick={() => {}} >
                submit
              </button>
            </div>

CodePudding user response:

For that, you need to add an if else condition during form rendering inside react.

I have checked complete single page app with full code to your solution and it will be:

<>
      <div className="btn btn-primary" data-toggle="modal" data-target="#Profile">
        button
      </div>

      <div  id="Profile" aria-hidden="true">
        <div >
          <div >
            <div >
              <h5 >Header</h5>

              <button
                type="button"
                
                data-dismiss="modal"
                aria-label="Close"
              >
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
            {formStage === 0 && (
              <div>
                <form>
                  <div >
                    <div className="input-group mt-2">
                      <label for="recipient-name" className="input-label">
                        name
                      </label>
                      <input
                        name="myName"
                        type="text"
                        className="input-element"
                      />
                    </div>
                  </div>
                </form>
              </div>
            )}
            {formStage === 1 && (
              <div>
                <form>
                  <div >
                    <div className="input-group mt-2">
                      <label for="recipient-name" className="input-label">
                        Family
                      </label>
                      <input
                        name="myFamily"
                        type="text"
                        className="input-element"
                      />
                    </div>
                  </div>
                </form>
              </div>
            )}
            <div >
              {formStage === 0 && (
                <button type="button"  data-dismiss="modal" aria-label="Close">
                  Close
                </button>
              )}
              {formStage === 1 && (
                <button type="button"  onClick={previousStage}>
                  Back
                </button>
              )}
              {formStage === 0 && (
                <button type="button"  onClick={nextStage}>
                  Next
                </button>
              )}
              {formStage === 1 && (
                <button type="button"  onClick={() => {}} >
                  submit
                </button>
              )}
            </div>
          </div>
        </div>
      </div>
    </>

CodePudding user response:

You would need a switch/case function to handle which form need to be rendered, based on the formStage state, and put this function into JSX.

You would also need to set the condition for your nextStage() and previousStage() functions, so the state won't in/decrease over its range.

I would suggest this structure for the code, you can fill in your JSX and CSS classes. Demo on CodeSandbox

import { useState } from "react";

export default function Modal() {
  const MAX_STAGE_FORM_INDEX = 1;
  const [formStage, setFormStage] = useState(0);

  function nextStage(e) {
    e.preventDefault();
    if (formStage < MAX_STAGE_FORM_INDEX) {
      setFormStage(() => formStage   1);
    }
  }

  function previousStage(e) {
    e.preventDefault();
    if (formStage > 0) {
      setFormStage(() => formStage - 1);
    }
  }

  function handleRenderFormStage() {
    switch (formStage) {
      case 0:
        return <Form1 />;
      case 1:
        return <Form2 />;
      // ADD MORE FORM HERE
      default:
        return null;
    }
  }

  return (
    <form style={{ display: "flex", flexDirection: "column" }}>
      {/* DYNAMIC CHANGING PART */}
      {handleRenderFormStage()}

      {/* NON-DYNAMIC CHANGING PART */}
      <button onClick={nextStage}>Next</button>
      <button onClick={previousStage}>Prev</button>
    </form>
  );
}

// UPDATE THE CONTENTS OF THE FORM HERE
function Form1() {
  return <>Form1 Content</>;
}

function Form2() {
  return <>Form2 Content</>;
}

  • Related