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.