Create Model for Show Error Message on Submit in React - part 16

 

open modal on button click react functional component



A modal is a simple rectangular box that appears on the screen due to some action; it is also known as a dialogue box.

In other words, it's an attention seeker; no matter what you're doing, if it pops up, it immediately grabs your attention. You have a great reason for using it on websites, such as to alert you of an error, for confirmation, or to request user action, such as a user login or newsletter subscription.

If you want additional details, see this Hubspot post about the modal.

In this tutorial, we'll create a modal popup with the useState hook to alert an error if the user doesn't fill out all fields when submitting the form.

The steps I'll take are as follows:

  1.  We'll make a clear and simple modal user interface that appears above the content.
  2.  We'll add a layer of backdrop effect.
  3. Control modal popups using the useState hook.
  4. Apply event logic to close the pop-up window.


Simple react form validation on submit

Within the submitFormHandler function, I'll add some basic validation to the UserForm component that will stop execution if the input fields are empty. Let's verify that the length is equal to 0 and remove any unnecessary white space.

UserForm.js

const UserForm = () => {
  const submitFormHandler = (e) => {
  e.preventDefault()
  if (name.trim().length === 0 || language.trim().length === 0) {
      return
  }
  
  ....
}

It's basic validation that indicates that both fields are required and that failing to provide them will return a false result. I'll now work on the error modal.

Create Error Modal Component

Create a new file called Modal.js in the component folder and declare the arrow function with the props argument. We implemented a simple modal UI in our react app: a header with a title, a body with an error message, and a footer with a close button.

const Modal = (props) => {
 return (
   <section>
     <FancyBorder className="modal-container">
       <header>
         <h2>An error occured!</h2>
       </header>
       <div className="error-msg">
         <p>All fields are require</p>
       </div>
       <footer className="modal-close">
         <button type="button">close</button>
       </footer>
     </FancyBorder>
   </section>
 )
}

export default Modal

You can use a div element with a className in this place instead of the FancyBorder that I use to wrap my modal. In the composition part, I went into great length on this subject.

I will now create the Modal.css file and use the CSS class selector to apply all of the stylings.

Modal.css
.modal-container {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 350px;
  z-index: 10;
  overflow: hidden;
  background-color: #fff;
}
.error-msg {
  padding: 1rem;
}
.error-msg {
  color: red;
  font-size: 1.25rem;
}
.modal-close {
  padding: 1rem;
  display: flex;
  justify-content: end;
}
.modal-close button {
  background: steelblue;
  color: #fff;
}

We have a form in the UserForm component that we created in the form handling section which has two input fields- name and language, and a dropdown- Level. 

I'll import the error modal in the UserForm component and return the <Modal /> element in JSX for correctly displaying it.

UserForm.js
import Modal from '../Modal'
const UserForm = () => {
  return (
    <section>
      <Modal />
      <form>
         ...... <!-- I handle the form in the form handling section */ -->

      </form>
    </section>
  )
}

Setting backdrop for the modal

In order to prevent users from interacting with other components before taking any action with the modal popup dialogue, we'll develop the background layer that is utilized to generate the fade effect behind the modal popup dialogue.

Let's add a slightly darker background to the main page to give it a fading appearance.  I'll do that by using an empty div element with the CSS class 'backdrop'. To achieve our goal apply CSS to the Modal.css file, it will make the pop-up box more visually appealing.

const Modal = (props) => {
 return (
   <section>
     <div className="modalBackdrop" />
     <FancyBorder className="modal-container">
       <header>
         <h2>An error occured!</h2>
       </header>
       <div className="error-msg">
         <p>All fields are require</p>
       </div>
       <footer className="modal-close">
         <button type="button">close</button>
       </footer>
     </FancyBorder>
   </section>
 )
}

export default Modal

We use the class selector to provide styling to our background, and you can now import the file into Modal.js.

Modal.css

.modalBackdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 2;
  background: rgba(0, 0, 0, 0.5);
}


example of error modal displayed on screen in React


Use the useState hook

The modal is now prepared but is static and visible on the screen. I want it to only appear when the user submits a form that is empty.

Inside the <UserForm> component, I'll define a useState hook to trigger the modal in the functional component to dynamically open and close the modal. Ensure that the UserForm component imports useState from the React library at the top.


import { useState } from 'react;

const [error, setError] = useState()

Pass dynamic data to make modal component reusable

Although I may utilize this simple modal dialogue box exactly as it was created earlier, I want to take things a step further and make the content of the modal dynamic. Why? We can make it reusable and utilize it across our application if we want to use it to confirm some actions or for some other behavior.

I'll use setError as an object in the validation code to pass the title and error message. You could also use these properties for different errors or behaviors; the choice is entirely yours, and you could use it in a modal.


UserForm.js

const UserForm = () => {
  const [error, setError] = useState()
  
  const submitFormHandler = (e) => {
    e.preventDefault()
    if (name.trim().length === 0 || language.trim().length === 0) {
      setError({
        title: 'An error occurred!',
        message: 'All fields are required'
      })
      return
    }
  }
}

Declare the attributes title and message, and then pass the arguments, error.title and error.message to the Modal element.

<Modal title={error.title} message={error.message} />

Now apply it in place of the content by passing the props as an argument to the modal component.

Modal.js

const Modal = (props) => {
 return (
   <section>
     <FancyBorder className="modal-container">
       <header>
         <h2>{props.title}</h2>
       </header>
       <div className="error-msg">
         <p>{props.message}</p>
       </div>
       <footer className="modal-close">
         <button type="button">close</button>
       </footer>
     </FancyBorder>
   </section>
 )
}

Render modal conditionally

I want to conditionally hide this modal and have it appear only when an error occurs. We've already declared state management for the error modal, which will update the UI if an error occurs.

We'll use the && operator in JSX to check whether the expression is true, and if it is, the error will be displayed. Ensure that the expression is enclosed in curly braces.

{ error && <ErrorModal title={error.title} message={error.message} /> } 

If you submit an empty form, it will re-render the user interface; if not, it will add the person to the list.

Close modal on button click

The modal is functioning as expected, so we'll write event logic to dismiss the form when the close button is clicked. 

Declare the function errorHandler and call setError inside it with the value null so that when this function is called, the modal will disappear.

UserForm.js

const UserForm = () => {
  const [error, setError] = useState()
  
  const submitFormHandler = (e) => {
    e.preventDefault()
    if (name.trim().length === 0 || language.trim().length === 0) {
      setError({
        title: 'An error occurred!',
        message: 'All fields are required'
      })
      return
    }
  }
  const errorHandler = () => {
    setError(false)
  }
}


Because the button is inside the Modal component, we must declare props to the Modal element in order to pass the errorHandler function. I'll name the props onClose and pass the callback function as a value to this.

UserForm.js

const UserForm = () => {
  const [error, setError] = useState()
  
  const submitFormHandler = (e) => {
    e.preventDefault()
    if (name.trim().length === 0 || language.trim().length === 0) {
      setError({
        title: 'An error occurred!',
        message: 'All fields are required'
      })
      return
    }
  }
  const errorHandler = () => {
    setError(null)
  }
  
  return (
    <section>
      { error && <ErrorModal title={error.title} message={error.message} onClose={errorHandler} /> } 
      <form> 
      
         ........
         
      </form>
    </section>
  )
}

Inside the Modal component call the onClick event in the button and set props.onClose to it. This will trigger an event and take the modal off the page.

Modal.js

<button type="button" onClick={props.onClose}>close</button> 

Close the modal on click outside

We have a background style on the div, and when the modal appears on the screen, the backdrop style also applies. Now I want the modal to close if I click on the background. 

Call the onClick event on the empty div element. Now, on this event, pass the props so that it will also trigger the function and clear the error if you click anywhere other than within the modal.

Modal.js

<div className="modalBackdrop" onClick={props.onClose}/> 

Conclusion

We learned how to create modal using React. It's just a simple validation modal that appears on the screen when an error occurs. I hope you enjoyed this article; please share your thoughts in the comment box.




0 Comments:

Post a Comment