React validation on multiple checkboxes - reactjs

anyone can point me to an example of a react multiple checkboxes validation? I have some questions, every one of them has a checkbox when it's done and when all are checked, a continue button must be activated.. I know how to do this with only one checkbox, but don't know how to handle more of them. I would rather do this in plain react and not by installing any package. Any help will be appreciated.

You can control all your inputs using useState. Example for two inputs.
import React, { useState } from "react"
const ControlledCheckboxes = () => {
const [ firstCheckbox, setFirstCheckbox ] = useState(false);
const [ secondCheckbox, setSecondCheckbox ] = useState(false);
return(
<form>
<div >
<div className="form-check">
<input type="checkbox" id="first" className="form-check-input"
onClick={()=>setFirstCheckbox(!firstCheckbox)}
value={firstCheckbox}
/>
<label className="form-check-label" htmlFor="first">FIRST</label>
</div>
<div className="form-check">
<input type="checkbox" id="second" className="form-check-input"
onClick={()=>setSecondCheckbox(!secondCheckbox)}
value={secondCheckbox}
/>
<label className="form-check-label" htmlFor="second">SECOND</label>
</div>
</div>
<button type="submit" className="btn btn-outline-success" disabled={ !(firstCheckbox && secondCheckbox) } >SUBMIT</button>
</form>
)
};

You can achieve this by using controlled inputs.
Basically you would make the value of the checkboxes correspond to variables in the state of your component. After that it is as simple as if (boolean1 && boolean2) with a conditionally rendered save button.
Controlled inputs
Conditional rendering

You can achieve most of what you want with just HTML.
<form>
<input type="checkbox" required />
<input type="checkbox" required />
<button>submit</button>
</form>
The form cannot be submitted until all checkboxes are checked.
Let's say that's not enough, you want to access the form validity in your render logic to apply styles or whatever so you need component state.
const [valid, setValid] = useState(false);
All form control change events bubble up to their form (unless explicitly stopped). We can spy on form control changes by adding a change event listener that updates component state to the form element.
event => setValid(event.target.form.checkValidity())
If your form isn't as simple as my example and you need to specifically check certain checkboxes you can find all form controls in event.target.form.elements. You can use the elements property to not even need HTML form validation.
event => setValid(Array.from(event.target.form.elements).every(
input => input.type !== 'checkbox' || input.checked
))
You can then pass valid as a prop to your submit button.

Related

React useForm get value from TextBox

I am using React useForm hook to submit data from my form. The requirement is the user should see the sample data in a preview div before he submits. How can i get the value from input text boxes and display it in a div next to the input. In the documentation there is getValue method can that be used?
<form>
<div class="mb-6">
<label class="block mb-2">Enter Title: </label>
<input type="text" id="page_text" class="text-white" placeholder="Enter Title" {...register('page_Title',{ required: "Enter Your Title", maxLength: {value:255,message:"Cannot Exceed more 255 Characters" } })}/>
</div>
</form>
<div className= "text-white text-center rounded-xl shadow-xl">
<h1>Preview</h1>
<h3>{getValues("page_Title")}</h3>
</div>
I've created a sandbox here: https://codesandbox.io/s/angry-wave-nef2jo
Basically the issue is getValues doesn't automatically update when you enter text (onChange). You need to use the watch method as described in the documentation here: https://react-hook-form.com/api/useform/watch
For example:
const pageTitle = watch("page_Title", false);
Then:
<h3>{pageTitle}</h3>
inside the form put a button and trigger the getValues() method. like below
<button
type="button"
onClick={() => {
const values = getValues(); // { page_title: "someValue", test1: "test1-input", ... }
console.log({values});
}}
>
Get Values
</button>
Have a look at this basic example from the docs link too

URL search parameters gets replaced - Remix Run

I'm working on a search UI where I have quite a few filters which I want as URL parameters when someone selects/checks the options. I've used the technique as advised on the Remix.run docs to come up with multiple forms within the filters. Each time a group of Filters gets submitted, the selected old parameters get disappeared. Heres my code,
<Panel header="Status" key="status">
<Form
name="search"
action='/search'
method="get"
onChange={(e) => submit(e.currentTarget, { replace: false })}
>
<ul>
<li>
<Checkbox
name="status"
value="buy_now"
defaultChecked={status.includes('buy_now')}
>
Buy Now
</Checkbox>
</li>
<li>
<Checkbox
name="status"
value="on_auction"
defaultChecked={status.includes('on_auction')}
>
On Auction
</Checkbox>
</li>
</ul>
</Form>
</Panel>
<Panel header="Price" key="price">
<Form name="search" action='/search' method="get">
<Select
name="blockchain"
value={
blockchain
? options.filter((a) => a.value === blockchain)
: undefined
}
options={options}
placeholder="Blockchain"
type="white"
/>
<div className="d-flex align-center price">
<TextInput
value={min ? min : undefined}
name="min"
placeholder="Min"
/>
<span>to</span>
<TextInput
value={max ? max : undefined}
name="max"
placeholder="Max"
/>
</div>
<button
onClick={(e) => {
e.stopPropagation()
submit(e.currentTarget, { replace: false })
}}
className="btn primary-btn btn-lg w-100"
>
Apply
</button>
</Form>
</Panel>
How Can I get around this to have all the parameters without having to manage them on my own using React state?
Edit:- I want the first filter to be submitted automatically and the latter to be submitted on a button click.
Bit of a UI of what I'm trying to achieve,
Answer: After investing enough time to look through for shortcuts, finally understood that it's not one of the magic that remix.run does. use something like formik and update the state imparatively.
When you submit a form, the only values included are the one under the submitted form. The values from any other form are not included (fortunately!).
So I'd use a single Form with all the inputs under it (checkboxes as well as text inputs).
Then instead of a onChange on the Form, you can add something like an onChange handler on the checkboxes and submit the form inside imperatively (using a ref click on the submit button or something, I think using a ref on the form you need to submit all values in the submit function so a button ref click may be simpler).
Keep in mind that if you want to "restore" the field values after submitting, you need to return them from the loader function like this:
// Loader function
const url = new URL(request.url);
return {
results: [...],
values: Object.fromEntries(url.searchParams.entries())
};
Then in the component, use values from useLoaderData:
<input type="text" name="max" defaultValue={values.max || ""}/>
Added benefit: if you come back to this page (by clicking browser back for example), your search parameters and search results are still there!
I actually put up a stackblitz for you but I lost all my changes :(
It seems like you could just keep all fields in a single form and submit that form when the submit button is pressed.
Then onChange, check if the target's name is 'status', and submit the form anyway.
export default function App() {
const submit = (form) => {
form.submit();
};
return (
<form
name="search"
action="/search"
method="get"
onChange={(e) => {
if (e.target.name === "status") {
submit(e.currentTarget);
}
}}
>
<fieldset>
<legend>status</legend>
<label>
<input type="checkbox" name="status" value="buy_now" />
buy_now
</label>
<label>
<input type="checkbox" name="status" value="on_auction" />
on_auction
</label>
</fieldset>
<fieldset>
<legend>price</legend>
<label>
<div>blockchain</div>
<select name="blockchain">
<option value="option_1">Blockchain Option 1</option>
<option value="option_2">Blockchain Option 2</option>
</select>
</label>
<label>
min <input type="number" name="min" />
</label>
<label>
max <input type="number" name="max" />
</label>
</fieldset>
<button type="submit">Apply</button>
</form>
);
}
demo
Note: not sure what your motivation is to want to separate this into separate forms, but I think the magic you're referring to is that server state, URLSearchParams, FormData and UI are all aligned because they are using the same underlying data using only common web APIs.

Reactjs checkbox check from button click

<input className="form-control"
type="text"
/>
<input type="button" onClick={()=>clickHandle()}/>
When I click the button, I want to change the check property of the checkbox. But the checked property or defaultChecked properties do not work in this regard. What can I do about it?
As far as I understand, you want the status of the checkbox to change when the button is clicked.
If I understood correctly, this is probably what you wanted.
export default function App() {
const [chkValue, setChkValue] = useState(false);
return (
<div className="App">
<input className="form-control" type="checkbox" checked={chkValue}/>
<input type="button" value="click" onClick={()=>setChkValue(!chkValue)} />
</div>
);
}
You have a type text input and a type button input. There is no checkbox there. You'd need a type checkbox input and then try this answer How to set default Checked in checkbox ReactJS?
Edit:
Wrong link for setting checked value. The link explains how to set the default. This code snippet has an example of setting a checkbox value dynamically.

Make checkbox field mandatory using React

I want to make the checkbox field mandatory to select atleast 1 using react js.
Below is my code:
renderCheckboxes() {
const { zones_to_render_to_render, filter } = this.state;
console.log(zones_to_render_to_render, filter)
return zones_to_render_to_render
.filter(checkbox =>
filter === 'ALL' ||
filter === 'CHECKED' && checkbox.checked ||
filter === 'UNCHECKED' && !checkbox.checked
)
.map((checkbox, index) =>
// console.log(checkbox, index)
<div key={index}>
<label>
<input
type="checkbox"
checked={checkbox.checked}
onChange={this.toggleCheckbox.bind(index)}
/>
{checkbox.zone_name}
</label>
</div>
);
}
Any help would be appreciated...
Please add a required property to the checkbox.
required="required"
And wrap the input boxes into a form element. Define an onSubmit handler to the form which can make an ajax call with the input filled data.
More references here
Reactjs - Form input validation
You can use Required property it is used to set or return whether the input checkbox field should be checked or not before submitting the form.
for more details check https://www.geeksforgeeks.org/html-dom-input-checkbox-required-property/
<form >
<input
type="checkbox"
checked={checkbox.checked}
onChange={this.toggleCheckbox.bind(index)}
required="required"
/>
</form >

React use form for img radio buttons

I am trying to create a rock, paper and scissor game in react. I would assume that it makes sense to use a form for this, I would atleast use a form haven't it been for react.
I figured that the simplest way of doing this, would be three radio inputs and a submit.
However, since I want to use three pictures as the actual radio buttons. Would it even make sense to use a form since react aims to take the state out of the form. This is the point in my code where i realized that I might be on a sidetrack.
onChangeHandler = (event) => {
this.setState({ [event.target.name]: event.target.value });
}
render() {
return (
<div>
<div>
<form>
<input type="radio" value="Rock" name="gender" onChange={this.onChangeHandler} /> Rock
<input type="radio" value="Paper" name="gender" onChange={this.onChangeHandler} /> Paper
<input type="radio" value="Scissor" name="gender" onChange={this.onChangeHandler} /> Scissor
<input type="submit" value="Submit" onClick = () => {submit()}/>
</form>
</div>
<div>
<img id="r" value="rock" src="http://www.jerrylow.com/demo/rps/rock.svg" alt="a rock" />
<img id="p" value="paper" src="http://www.jerrylow.com/demo/rps/paper.svg" alt="a piece of paper" />
<img id="s" value="scissor" src="http://www.jerrylow.com/demo/rps/scissor.svg" alt="a scissor" />
</div>)
}
Should I use this form, even though the form serves no particular purpose. If yes, how should i integrate it with the img elements?
You have a few ways of going about it. You can forgo the form entirely and attach onClick listeners to each of the images that would modify the state when clicked and then have a button that when clicked would call your submit function.
Or, if you wish to retain the form, you could either wrap the radio buttons and images in labels, hide the radio buttons such that when the image is clicked, it would trigger the onChange. Or, you could specify a for prop on the label that matches the id of a radio button and have the image in that and it would behave as the previously described, something like
<input type="radio" id="myButton" onChange={handleChange} />
<label for="myButton"><img src="img.png" /></label>
I guess it really comes down to the solution you want because either way would be fine. I would personally prefer not using a form for this scenario purely because it's not that necessary and the code would be smaller.

Resources