I'm using react-hook-form and I have to create a radio buttons form that submits when clicking an option. This is the code
const Form0 = () => {
const { register, handleSubmit } = useForm();
const submitFunction = (data) => {
console.log("submitted:", data);
};
return (
<form onSubmit={handleSubmit(submitFunction)}>
<label>
<input type="radio" value="foo" {...register("radio-button")} />
foo
</label>
<label>
<input type="radio" value="bar" {...register("radio-button")} />
bar
</label>
<label>
<input type="radio" value="foobar" {...register("radio-button")} />
foobar
</label>
</form>
);
};
I tried adding onClick={() => handleSubmit(submitFunction)} on each label but didn't work. Also I tried changing all the input types to type="submit", but when clicking an input always submit the value of the first input.
I created a sandbox https://codesandbox.io/s/react-hook-form-radio-p4p9o9
Thanks in advance
One solution would be to add a ref in your form tag and use this to dispatch the submit event from your radio buttons.
Add the ref:
const formRef = React.useRef(null);
<form ref={formRef} ...
Add the onClick to your radio buttons:
onClick={handleRadioButtonClick}
and dispatch the submit event:
const handleRadioButtonClick = () => {
formRef.current.dispatchEvent(new Event("submit", { cancelable: true }));
};
EDIT:
For you sandbox example, you can use watch and subscribe to the changes like:
useEffect(() => {
const subscription = watch(handleSubmit(submitFunction));
return () => subscription.unsubscribe();
}, [handleSubmit, watch]);
Related
I have a form in which I do not need to track the changes in real time for part of the data and only need the final data.
I want to know how to submit a controlled <select> and an uncontrolled <input> in the same form.
my code for states and handlers:
const [ethValue, setEthValue] = useState("");
const ethValueRef = useRef();
const handleBet = (e) => {
const newEthValue = ethValueRef.current.value;
setEthValue(newEthValue);
e.preventDefault();
};
const [formData, setFormData] = React.useState({
userTeamChosen: "",
eventNumber: 0,
})
function handleChange(event) {
const { name, value, type, checked } = event.target
setFormData(prevFormData => {
return {
...prevFormData,
[name]: type === "checkbox" ? checked : value
}
})
}
my forms:
<form onSubmit={handleBet}>
<select
onChange={handleChange}
name="userTeamChosen"
value={formData.userTeamChosen}>
<option>--choose---</option>
<option value={a}>{a}</option>
<option value={b}>{b}</option>
<option value={c}>{c}</option>
</select>
<input
type="number"
defaultValue={ethValue}
ref={ethValueRef}
name="value"
/>
<button>Submit</button>
</form>
How do I submit both forms?
I would recommend not using refs in this case and instead going for a completely state based form.
There were also some inconsistencies that are fixed now.
Your number input matches the name of your form and is being handled by your existing handleChange function.
<input
type="number"
name="eventNumber"
value={formData.eventNumber}
onChange={handleChange}
/>
Additionally I've added a little debug submit function to your form:
const submit = () => {
alert(JSON.stringify(formData));
};
...
<form onSubmit={submit}>
...
I'm new to React and have been trying to make a registration form, but I couldn't find a way to get data from my input when a button is clicked (onClick)
function App() {
const userData = []
function handleClick() {
//get input data here
}
return (
<div className="form-main">
<div className='em'>
<label className='label '> User e-mail </label>
<Input type="email" />
</div>
<div className='pw'>
<label className='label '> Password </label>
<Input type="password" />
</div>
<button type="submit" className="submit-btn" onClick={handleClick}>Signup</button>
</div>
);
}
I've shared my input component below in case that helps (I've shortened the code while posting)
function Input(props) {
return (
<input type={props.type} className="input"></input>
);
}
Your form inputs are uncontrolled - https://reactjs.org/docs/forms.html#controlled-components
Updates to the value of the input aren't being registered by React. A quick stripped down working version to give you an idea of how it works:
const Form = () => {
const [email, setEmail] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
// ... do something with email
}
return (
<form onSubmit={handleSubmit}>
<input type='email' value={email} onChange={(e) => { setEmail(e.target.value) }} />
<button type='submit'>Submit</button>
</form>
);
}
In this way React is 'controlling' the input and you can do whatever you like with the email value in the handleSubmit() function.
You can make use of useRef here . Just call handleSubmit when submit button is clicked as shown below .
const Form = () => {
const emailRef = React.useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
// ... make use of your email data entered inside input
console.log(emailRef.current.value) // consoles the email
}
return (
<form onSubmit={handleSubmit}>
<input type='email' ref={emailRef} />
<button type='submit' onClick={handleSubmit}>Submit</button>
</form>
);
}
You can get more clarity on useRef here official doc
I new to React. I have two input fields which are filled when the pages loads via axios but when I want to change the Values I am unable to change them even I can not type anything on them.
function MainView() {
const [InputFields, setInputFields] = useState({
name: "",
fullURL: "",
});
const changeHandler = (e) => {
setInputFields({
...InputFields,
[e.target.name]: e.target.value,
});
};
const [links, setLinks] = useState([]);
const getLinks = () => {
axios.get('../sanctum/csrf-cookie').then(response => {
axios.get("/userlinks/getdata").then((res) => {
console.log(res);
setLinks(res.data);
}).catch((err) => {
console.log(err);
});
});
};
useEffect(() => {
getLinks();
}, []);
return (<div>
{links.map((link) => {
return (<div className="card" key={link.id}>
<form>
<input className="form-control" value={link.name} type="text" name="name" placeholder="name" onChange={changeHandler} />
<input className="form-control" value={link.fullURL} type="text" name="fullURL" placeholder="fullURL" onChange={changeHandler} />
</form>
</div>);
})}
</div>
);
}
export default MainView;
This happens because in your onChange method, you are changing InputFields variable, where as your getLinks method changes links variable, which is being rendered on the screen.
If you want to set an initial value, and then allow the user to change it, change your input to :
<input className="form-control" defaultValue={link.name}
value={InputFields.name} type="text" name="name" placeholder="name" onChange={changeHandler} />
Likewise change for your other input, if you do not want the user to change the value later on, it's often better to add disable in the input to avoid confusing people. 🙂
I know that this has been done so that you can create a minimal reproducible example for us, but I would have directly called setInputFields in the axios.get section to avoid this problem in the first place, however, if not possible, use the defaultValue and value as I've shown above.
I want to send a form so I created a function for that. I have a submit form , and the button should not enable until all fields of the form are fully filled.
All validations are working but this is not a problem, I need it for an onclick event.
My code works but when I click the checkbox one time to make it true and click again to make it false, the button should be disabled, but again it will be enabled.
...
const [name, setName] = useState("");
const [surname, setSurname] = useState("");
const [email, setEmail] = useState("");
const [checkbox, setCheckbox] = useState(false);
let handleSubmit = async (e) => {
e.preventDefault();
try {
...
}
};
return(
<Input
required
type="text"
value={name}
placeholder="İsim"
onChange={(e) => setName(e.target.value)}
/>
<Input
required
type="text"
value={surname}
placeholder="Soyisim"
onChange={(e) => setSurname(e.target.value)}
/>
<Input
required
type="email"
placeholder="E-mail"
onChange={(e) => setEmail(e.target.value)}
/>
<Input
type="checkbox"
required
value={checkbox}
onChange={(e) => setCheckbox(e.target.value)}
/>
<input
type="submit"
name="Onaylıyorum"
disabled={!name || !surname || !email || !checkbox}
/>
For the checkbox you have to change from value prop to the checked prop and access event.target.checked instead i.e
<input type="checkbox" checked={checkbox} onChange={(e) => setCheckbox(e.target.checked)} />
The react docs have an example too
Checkboxes are special and don't have a .value, rather, you want to be looking for .checked in your checkboxes onChange function.
Like this...
onChange={(e) => setCheckbox(e.target.checked)}
I am quite new to Redux-form and I am trying to access the form values inside the function of onChange handler on a checkbox.
I can alert the values/ console log the values. However, I want to access the values when I check the checkbox.
Also this checkbox is checked by default. Please advise/help. thanks in advance.
onClickOnLoanInsurence = (CheckBox1) =>{
//here i can access the value of checkbox, however, the value is inverted, what it means is, it shows false when true and true when false
}
<Field
name="CheckBox1"
component="input"
type="checkbox"
defaultChecked={true}
component={renderCheckBoxField}
onChange ={this.onClickOnLoanInsurence.bind(this,CheckBox1)}
label="Some Label"
/>
const selector = formValueSelector("myForm");
MyForm= connect(state => {
const values = selector(
state,
"FormField1",
"FormField2",
"FormField3",
"FormField4",
"CheckBox1",
"FormField5",
"FormField6",
"FormField7",
);
console.log("values of the form");
console.log(values);
//window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`);
return {
values
};
})(MyForm)
const mapStateToProps = (state,props) => {
const checkBox1= selector(state, "CheckBox1")
return {
checkBox1: !state.CheckBox1,
}
}
//CheckBox component
import React from 'react';
export const renderCheckBoxField = props => {
const { input: { onBlur,onFocus, ...rest } } = props;
return(
<div className="form-group">
<div className="checkbox">
<label className="container-checkbox">{props.label}
<input {...rest} type="checkbox" />
<span className="checkmark"></span>
</label>
</div>
</div>
)
}