Home > Software engineering >  How can I show/hide a form div in React.Component?
How can I show/hide a form div in React.Component?

Time:01-07

I am creating a CV Application project and I have a button that allows the user to Add Work Experience. When the user clicks the button a form pops up and they are able to fill the information out and click Submit.

I'm trying to make it so once the user hits Submit, the form div stays hidden until the user clicks Add Work Experience again. I've made something similar before in vanilla JS where I simply changed the forms class from display: block to display: none but that doesn't seem possible in React.

import React, { Component } from "react";

class WorkExperience extends Component {
  render() {
    const workExperience = [
      {
        title: "title",
        company: "company",
        location: "location",
        description: "description",
      },
    ];
    return (
      <>
        <div id="content" className="content">
          <h1 className="title">Work Experience</h1>
          <div className="work-experience">
            <p>Job Title: {workExperience[0].title}</p>
            <p>Company: {workExperience[0].company}</p>
            <p>Location: {workExperience[0].location}</p>
            <p>Description: {workExperience[0].description}</p>
          </div>
        </div>
        <button className="form-btn">  Add Work Experience</button>
      </>
    );
  }
}

export default WorkExperience;

And here is the form code I am currently using. This is the form I want to show/hide after clicking the Add Work Experience button shown above.

<form>
  <label for="title">Job Title</label>
  <input id="title" className="form-row" type="text" name="title" />
  <label for="company">Company</label>
  <input className="form-row" type="text" name="company" />
  <label for="location">Location</label>
  <input className="form-row" type="text" name="location" />
  <label for="description">Job Description</label>
  <textarea rows="4" cols="50" name="description"></textarea>
  <button className="save">Save</button>
  <button className="cancel">Cancel</button>
</form>

CodePudding user response:

You can use an if statement or a ternary to return different jsx. That would look something like this. There are other ways as well, however this is a basic example of something you could do.

 <>
   {
    shouldShow ?
   (
     <div id="content" className="content">
      <h1 className="title">Work Experience</h1>
      <div className="work-experience">
        <p>Job Title: {workExperience[0].title}</p>
        <p>Company: {workExperience[0].company}</p>
        <p>Location: {workExperience[0].location}</p>
        <p>Description: {workExperience[0].description}</p>
      </div>
    </div>
  <button className="form-btn">  Add Work Experience</button>
 ) : (
  <form>
    <label for="title">Job Title</label>
    <input id="title" className="form-row" type="text" name="title" />
    <label for="company">Company</label>
    <input className="form-row" type="text" name="company" />
    <label for="location">Location</label>
    <input className="form-row" type="text" name="location" />
    <label for="description">Job Description</label>
    <textarea rows="4" cols="50" name="description"></textarea>
    <button className="save">Save</button>
    <button className="cancel">Cancel</button>
  </form>
 )
}
</>

Where shouldShow is what determines whether the form is showing or not. The benefit to this is that if the form is showing, the other content is not added to the DOM and vice versa.

shouldShow would be a variable you could add to state, and when the button is clicked, you toggle the state variable, causing a re-render.

https://reactjs.org/docs/state-and-lifecycle.html

You could also choose to render styles depending on whether or not that component is showing, the key being that boolean state variable that is re-rendering the component.

CodePudding user response:

Use Repeater Felilds to add User Work Experience. It's so easy to handle like this.

Repeater Component

import React from "react";

const Repeater = ({ inputFields, setInputFields }) => {
  const handleFormChange = (index, event) => {
    let data = [...inputFields];
    data[index][event.target.name] = event.target.value;
    setInputFields(data);
  };

  const removeFields = (index) => {
    let data = [...inputFields];
    data.splice(index, 1);
    setInputFields(data);
  };

  return (
    <div className="row">
      {inputFields.map((input, index) => {
        return (
          <>
            <div className="form-group col-sm-12 col-md-4 mb-3">
              <div className="controls">
                <input
                  type="text"
                  className="form-control inputset"
                  id="title"
                  placeholder="title"
                  name="title"
                  data-validation-required-message="This  field is required"
                  aria-invalid="true"
                  required
                  value={input.title}
                  onChange={(event) => handleFormChange(index, event)}
                />
                <div className="help-block" />
              </div>
            </div>
            <div className="form-group col-sm-12 col-md-4 mb-3">
              <div className="date-picker">
                <input
                  type="text"
                  className="pickadate form-control inputset"
                  value={input.company}
                  onChange={(event) => handleFormChange(index, event)}
                  name="company"
                  id="pass"
                  data-validation-required-message="This  field is required"
                  data-toggle="tooltip"
                  data-trigger="hover"
                  data-placement="top"
                  data-title="Date Opened"
                  data-original-title=""
                  required
                />
              </div>
            </div>
            <div className="form-group col-sm-12 col-md-4 d-flex mb-3">
              <input
                type="text"
                className="form-control inputset"
                id="location"
                placeholder="location"
                name="location"
                data-validation-required-message="This  field is required"
                aria-invalid="true"
                required
                value={input.location}
                onChange={(event) => handleFormChange(index, event)}
              />
               <input
                type="text"
                className="form-control inputset"
            id="description"
                placeholder="description"
                name="description"
                data-validation-required-message="This  field is required"
            aria-invalid="true"
            required
            value={input.description}
            onChange={(event) => handleFormChange(index, event)}
          />
              {inputFields.length === 1 ? null : (
            <button
              type="button"
              className=" d-flex justify-content-center align-items-center ml-1 btn"
              onClick={() => {
                removeFields();
              }}
            >
              <i className="uil-trash-alt" />
            </button>
          )}
        </div>
      </>
        );
      })}
    </div>
  );
};

export default Repeater;

Main Component

use these as states and pass the objects to the Repeater Component. First, the state is empty and when the user clicks on the button Add More Experience The files auto-show.

const [inputFields, setInputFields] = useState([
  { degree_title: "", institue: "", end_date: "" },
]);



 const addFields = () => {
 let newfield = { degree_title: "", institue: "", end_date: "" };

 setInputFields([...inputFields, newfield]);
};

<Repeater
 inputFields={inputFields}
 setInputFields={setInputFields}
 addFields={addFields} />

I wish this solution helps you :) Make sure to change the state object according to your requirements.

  • Related