how to render input values on button click react - javascript

I have two fields and a button. I want to render input values on the click of a button. Can you guys please tell me how to do it?
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const submitForm = () => {
console.log(name, age)
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
)
}
export default Home

You can add a state to track the display state, as
const [visible, setVisible] = useState(false)
Alter it in form submit as:
const submitForm = () => {
setVisible(true)
}
And render it as:
{visible && <><h1>render {name} gere</h1>
<h2>render {age} gere</h2> </>}

I fix it like this.
function Home() {
const [name, setName] = useState('')
const [age, setAge] = useState(0)
const [data, setData] = useState({})
const submitForm = () => {
setData({name, age})
}
return (
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onClick={submitForm}>Submit</button>
<h1>{data.name}</h1>
<h2>{data.age}</h2>
</div>
)
}
export default Home

Try this and see if it helps.
function Home() {
const {register, handleSubmit} = useForm()
const onSubmit = (data) => {
console.log(data)
}
return (
<form onSubmit = {handleSubmit(onSubmit)}>
<div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" value={name} onChange={e => setName(e.target.value)} />
</div>
<div>
<label htmlFor="age">age:</label>
<input type="number" value={age} onChange={e => setAge(e.target.value)} />
</div>
<button onSubmit={submitForm}>Submit</button>
<h1>render "name" gere</h1>
<h2>render "age" gere</h>
</div>
<form/>
);
}

Related

Table closing after populating data passed as props from a modal

I'm passing data from am AddItem modal in react to a table in the NewInvoice component. The data is being populated to the table successfully but modal does not close after clicking the save button. Kindly assist on what i could be missing on this.
NewInvoice.js
const [itemOpen, setitemOpen] = useState(false);
<div className="new-invoice-client">
<FormDataTable itemOpen={itemOpen}/>
</div>
<div
className="new-item-links"
style={{ marginLeft: "35px", marginTop: "35px" }}
>
<Button onClick={() => setitemOpen(true)}>
<BsPlus />
Add an Item
{itemOpen && <AddItem setitemOpen={setitemOpen} />}
</Button>
</div>
The <FormInvoiceTable/> is passed to the NewInvoice parent component as shown below.
FormInvoieTable.js
function FormDataTable(props) {
const [tableData, setTableData] = useState([]);
// console.log(tableData)
const tableRows = tableData.map((value, index) => {
return (
<tr key={index}>
<td>{value.item}</td>
<td>{value.amount}</td>
<td>{value.rate}</td>
<td>{value.quantity}</td>
<td>{value.description}</td>
</tr>
);
});
const addRows = (data) => {
const totalData = tableData.length;
data.id = totalData + 1;
const updatedtableData = [...tableData];
updatedtableData.push(data);
setTableData(updatedtableData);
};
return (
<React.Fragment>
<table className="table">
<thead>
<tr>
<th>Item</th>
<th>Description</th>
<th>Qty</th>
<th>Rate</th>
<th>Amount</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</table>
<AddItem func={addRows}/>}
</React.Fragment>
);
}
AddItem.js Modal
function AddItem(props) {
const [item, setItem] = useState("");
const [amount, setAmount] = useState("");
const [rate, setRate] = useState("");
const [quantity, setQuantity] = useState("");
const [description, setDescription] = useState("");
const clearState = () => {
setItem("");
setAmount("");
setRate("");
setQuantity("");
setDescription("");
};
const handleSubmit = (event) => {
event.preventDefault();
const formInputData = {
item,
amount,
rate,
quantity,
description,
};
props.func(formInputData);
// clearState();
props.setitemOpen(false)
};
return (
<div className="modalBackground">
<div className="modalContainer">
<div className="title">
<h1>New Item</h1>
</div>
<div className="modal-form-container">
<form className="register-form">
<input
className="register-input"
name="item"
onChange={(e) => setItem(e.target.value)}
value={item}
placeholder="Item"
/>
<input
className="register-input"
name="amount"
value={amount}
placeholder="Amount"
onChange={(e) => setAmount(e.target.value)}
/>
<input
className="register-input"
placeholder="Rate"
name="rate"
value={rate}
onChange={(e) => setRate(e.target.value)}
/>
<input
className="register-input"
name="quantity"
placeholder="Quantity"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
/>
<input
className="register-input"
style={{ width: "600px", height: "80px" }}
type="text"
value={description}
placeholder="Description"
onChange={(e) => setDescription(e.target.value)}
/>
<div className="modal-buttons" style={{ justifyContent: "center" }}>
<button onClick={handleSubmit}>Save</button>
<button onClick={() => props.setitemOpen(false)}>cancel</button>
</div>
</form>
</div>
</div>
</div>
);
}
Your are creating component <AddItem/> two times.
When you create it in FormDataTable component you don't pass it prop setitemOpen. You are passing only addRows function as a prop :
<AddItem func={addRows}/>
One solution would be to pass setitemOpen={setitemOpen} prop to FormDataTable component and call it in addRow method with argument false. Also, remove AddItem component from NewInvoice component and create it only in FormDataTable component based on itemOpen
Here is code snippet:
NewInvoice.jsx
import React from "react";
import FormDataTable from "./FormInvoieTable";
import { useState } from "react";
import Button from "#mui/material/Button";
export default function NewInvoice(props) {
const [itemOpen, setitemOpen] = useState(false);
return (
<>
<div className="new-invoice-client">
<FormDataTable itemOpen={itemOpen} setitemOpen={setitemOpen} />
</div>
<div
className="new-item-links"
style={{ marginLeft: "35px", marginTop: "35px" }}
>
<Button onClick={() => setitemOpen(true)}>Add an Item</Button>
</div>
</>
);
}
Then in FormDataTable component, modify addRows method like this:
FormDataTable.jsx
import React from "react";
import AddItem from "./AddItem";
import { useState } from "react";
export default function FormDataTable(props) {
const [tableData, setTableData] = useState([]);
const { itemOpen } = props;
const tableRows = tableData.map((value, index) => {
return (
<tr key={index}>
<td>{value.item}</td>
<td>{value.amount}</td>
<td>{value.rate}</td>
<td>{value.quantity}</td>
<td>{value.description}</td>
</tr>
);
});
const addRows = (data) => {
const totalData = tableData.length;
data.id = totalData + 1;
const updatedtableData = [...tableData];
updatedtableData.push(data);
setTableData(updatedtableData);
props.setitemOpen(false);
};
return (
<React.Fragment>
<table className="table">
<thead>
<tr>
<th>Item</th>
<th>Description</th>
<th>Qty</th>
<th>Rate</th>
<th>Amount</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</table>
{itemOpen && <AddItem func={addRows} />}
</React.Fragment>
);
}
AddItem.jsx
import React from "react";
import { useState } from "react";
export default function AddItem(props) {
const [item, setItem] = useState("");
const [amount, setAmount] = useState("");
const [rate, setRate] = useState("");
const [quantity, setQuantity] = useState("");
const [description, setDescription] = useState("");
console.log(props);
const clearState = () => {
setItem("");
setAmount("");
setRate("");
setQuantity("");
setDescription("");
};
const handleSubmit = (event) => {
event.preventDefault();
const formInputData = {
item,
amount,
rate,
quantity,
description,
};
props.func(formInputData);
// clearState();
};
return (
<div className="modalBackground">
<div className="modalContainer">
<div className="title">
<h1>New Item</h1>
</div>
<div className="modal-form-container">
<form className="register-form">
<input
className="register-input"
name="item"
onChange={(e) => setItem(e.target.value)}
value={item}
placeholder="Item"
/>
<input
className="register-input"
name="amount"
value={amount}
placeholder="Amount"
onChange={(e) => setAmount(e.target.value)}
/>
<input
className="register-input"
placeholder="Rate"
name="rate"
value={rate}
onChange={(e) => setRate(e.target.value)}
/>
<input
className="register-input"
name="quantity"
placeholder="Quantity"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
/>
<input
className="register-input"
style={{ width: "600px", height: "80px" }}
type="text"
value={description}
placeholder="Description"
onChange={(e) => setDescription(e.target.value)}
/>
<div className="modal-buttons" style={{ justifyContent: "center" }}>
<button onClick={handleSubmit}>Save</button>
<button onClick={() => props.setitemOpen(false)}>cancel</button>
</div>
</form>
</div>
</div>
</div>
);
}

React form input values in JS

I am using NextJS with bulma CSS to create a simple application. I have this following form:
const MyPage = () => {
const [firstName, setFirstName] = useState('')
const [secondName, setSecondName] = useState('')
const updateFirstName = event => {
setFirstName(event.target.value)
}
const updateSecondName = event => {
setSecondName(event.target.value)
}
const createUser = async() => {
// Todo: perform some action with firstName and secondName
}
return (
<section className='mt-5'>
<div className='container'>
<div className='field'>
<label className='label'>My Form</label>
<div className='control'>
<input onChange={updateFirstName} className='input' type='type' placeholder='Enter First Name'></input>
</div>
</div>
<div className='field'>
<div className='control'>
<input onChange={updateSecondName} className='input' type='type' placeholder='Enter Second Name'></input>
</div>
</div>
<button onClick={createUser} className='button is-primary'>Create</button>
</div>
</section>
)
}
export default MyPage
I have to call updateFirstName and updateSecondName on every input change.
I want to get these input field's value on createUser() function call only. Please suggest how to do it or any other better approach. I want to eliminate firstName and secondName variables, and directly access entered input in the createUser() function.
If you don't want a controlled input. You can quit managing the state and access the value old way using plain vanilla JS.
Make sure to add name attribute with all the input fields.
function createUser() {
const inputs = document.querySelectorAll(".field input")
let data = {}
inputs.forEach(input => {
data[input.name] = input.value
})
/**
This would yield you
{
'firstname': 'value',
'secondName': 'value'
}
**/
}
Please change your input fields as shown below:
<input onChange={(e)=>createUser(e,'firstName')} className='input' type='type' placeholder='Enter First Name'></input>
<input onChange={(e)=>createUser(e,'lastName')} className='input' type='type' placeholder='Enter First Name'></input>
Then in your update your createUser function as shown below:
const createUser = (event, element) => {
if(element==='firstName') {
setFirstName(event.target.value)
}
if(element==='lastName') {
setLastName(event.target.value)
}
}
You can try alternatively with this useRef() hook,
const MyPage = () => {
const firstName = useRef();
const secondaName = useRef();
const createUser = async() => {
// Todo: perform some action with firstName and secondName
console.log(firstName.current.value, secondName.current.value) // It will prints the value that is typed by the user in both the textfields
}
return (
<section className='mt-5'>
<div className='container'>
<div className='field'>
<label className='label'>My Form</label>
<div className='control'>
<input ref={firstName} className='input' type='type' placeholder='Enter First Name'></input>
</div>
</div>
<div className='field'>
<div className='control'>
<input ref={secondName} className='input' type='type' placeholder='Enter Second Name'></input>
</div>
</div>
<button onClick={createUser} className='button is-primary'>Create</button>
</div>
</section>
)
}
export default MyPage
You can write a handler function
Firstly, you should add all variables to same state.
const [userInfo, setUserInfo] = useState({
firstName: "",
secondName: ""
});
and you should give a name to inputs like this.
<input
className="input"
onChange={onChangeHandler}
name="firstName" //name attribute must same your state variable
placeholder="Enter First Name"
/>
<input
className="input"
onChange={onChangeHandler}
name="secondName" //name attribute must same your state variable
placeholder="Enter Second Name"
/>
and your handler function should like this
const onChangeHandler = (e) =>
setUserInfo({ ...userInfo, [e.target.name]: e.target.value });
and this function take your input value and set your state who same name.
Full code
export default function App() {
const [userInfo, setUserInfo] = useState({
firstName: "",
secondName: ""
});
const onChangeHandler = (e) =>
setUserInfo({ ...userInfo, [e.target.name]: e.target.value });
const sendData = () => {
console.log(userInfo);
};
return (
<div className="App">
<section className="mt-5">
<div className="container">
<div className="field">
<label className="label">My Form</label>
<div className="control">
<input
className="input"
onChange={onChangeHandler}
name="firstName"
placeholder="Enter First Name"
/>
</div>
</div>
<div className="field">
<div className="control">
<input
className="input"
onChange={onChangeHandler}
name="secondName"
placeholder="Enter Second Name"
/>
</div>
</div>
<button onClick={sendData} className="button is-primary">
Create
</button>
</div>
</section>
</div>
);
}
https://codesandbox.io/s/gallant-pasteur-uglbri?file=/src/App.js:58-1264

I want to reset my form after clicking submit in reactjs. I have tried making another method. but it does not work

import React,{ useState} from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react';
import axios from 'axios';
const Create = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
Here I am sending data to a mock api I created
const postData = () =>{
axios.post(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData`,{
firstName,
lastName,
checkbox
})
}
This is the method I created to reset the form but it does not work.
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
}
This is my form where on click i am calling resetForm function but it is not resetting it
is sending the data but not resetting the form.
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder='First Name' onChange={(e)=>setFirstName(e.target.value) } />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder='Last Name' onChange={(e)=>setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox id="c1" label='I agree to the Terms and Conditions' onChange={(e)=>setCheckBox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={resetForm}>Submit</Button>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Create;
Actually it will reset the form, the problem is you do not use Controlled Components to show the latest update value in UI
you should bind the value like this:
<input type="text" value={this.state.value} onChange={this.handleChange} />
You can refer the doc here:
https://reactjs.org/docs/forms.html
You can reset your form using the native form.reset() method.
const Create = () => {
const ref = React.useRef(null);
const resetForm = () => ref.current.reset();
return (
<div>
<Form ref={ref}>
<Form.Field>
<label>First Name</label>
<input id="f1" placeholder="First Name" onChange={(e) => setFirstName(e.target.value)} />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input id="last1" placeholder="Last Name" onChange={(e) => setLastName(e.target.value)} />
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
<br></br>
<Button onClick={() => navigate(-1)}>Go Back</Button>
</div>
);
};
export default Create;
For that, you have to set value property in your input. Try this
const Create = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [checkbox, setCheckBox] = useState(false);
const postData = () => {
console.log(firstName, lastName, checkbox);
};
const resetForm = () => {
postData();
setFirstName(" ");
setLastName(" ");
setCheckBox(false);
};
return (
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input
id="f1"
placeholder="First Name"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input
id="last1"
placeholder="Last Name"
value={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<Checkbox
id="c1"
label="I agree to the Terms and Conditions"
checked={checkbox}
onChange={(e) => setCheckBox(!checkbox)}
/>
</Form.Field>
<Button type="submit" onClick={resetForm}>
Submit
</Button>
</Form>
</div>
);
};

How can I disable an input textbox when a checkbox is checked?

I'm new to React and looking for a clue to disable an input text box when a corresponding checkbox is ticked. Below is my code:
const [checked, setChecked] = useState(false);
const [disable, setDisable] = useState(true);
<div>
<div>
<input
type="checkbox"
value={!checked}
onChange={() => setDisable(!disable)}
disable={!disable}
/>
</div>
<div>
<input
type="text"
placeholder="Enter correct detail"
disabled={!disable}
onChange={() => setChecked(true)}
/>
</div>
</div>;
The above code works for only a row. How do I implement this logic to be able to work for several other rows.
You can create an another component and isolate the state to that
Component: InputWithCheckBox
const InputWithCheckBox = () => {
const [checked, setChecked] = useState(false);
const [disable, setDisable] = useState(true);
return (
<>
<div>
<input
type="checkbox"
value={!checked}
onChange={() => setDisable(!disable)}
disable={!disable}
/>
</div>
<div>
<input
type="text"
placeholder="Enter correct detail"
disabled={!disable}
onChange={() => setChecked(true)}
/>
</div>
</>
)
}
Import the InputWithCheckBox where you want to display it. Then you can add multiple rows as you want
<div>
<InputWithCheckBox/>
<InputWithCheckBox/>
</div>;

ReactJS: onSubmit depending on API response close modal box

Why the state value is not updating after the form submit ? As i need to close the model after the successfully login.
I have tried to check with this useCallback hook but not able to close the dialogbox.
function HeaderComponent(props) {
const [loggedIn, setIsLoggedIn] = useState(false);
const [show, setShow] = useState(false);
const [modelShow, setmodelShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const registerUser = async event => {
event.preventDefault()
axios.post(`{api_url}/user/login`, data, {
})
.then((response) => {
localStorage.setItem("token", userDetails.auth_token);
setmodelShow(true)
router.push('/')
})
.catch((error)) => {
setmodelShow(false)
}
}
return (
<Modal show={show} onHide={handleClose} className={show ? 'intro' : ''}>
<form onSubmit={registerUser}>
<input type="email" />
<div className="form-group">
{
modelShow ? <input type="submit" name="" value="Login" onClick={handleClose}/>
: <input type="submit" name="" value="Login" />
}
</div>
</form>
</Model>
)
}
export default React.memo(HeaderComponent);
There are needs a little modification in your code like
return ( !modelShow ? <Modal show={show} onHide={handleClose} className={show ? 'intro' : ''}>
<form onSubmit={registerUser}>
<input type="email" />
<div className="form-group">
{
modelShow ? <input type="submit" name="" value="Login" onClick={handleClose}/>
: <input type="submit" name="" value="Login" />
}
</div>
</form>
</Model> : null )

Categories

Resources