uncheck checkbox programmatically in reactjs - javascript

I am messing with checkboxes and I want to know that is there a way in which I can uncheck a checkbox on click of a button by calling a function?? If so? How can I do that?
<input type="checkbox" className="checkbox"/>
<button onClick={()=>this.unCheck()}
How can I uncheck the checkbox programmatically and what if I have multiple checkboxes generated dynamically using map function.
How can I uncheck them If I want to?

There is property of checkbox checked you can use that to toggle the status of check box.
Possible Ways:
1- You can use ref with check boxes, and onClick of button, by using ref you can unCheck the box.
2- You can use controlled element, means store the status of check box inside a state variable and update that when button clicked.
Check this example by using ref, assign a unique ref to each check box then pass the index of that item inside onClick function, use that index to toggle specific checkBox:
class App extends React.Component{
constructor(){
super();
this.state = {value: ''}
}
unCheck(i){
let ref = 'ref_' + i;
this.refs[ref].checked = !this.refs[ref].checked;
}
render(){
return (
<div>
{[1,2,3,4,5].map((item,i) => {
return (
<div>
<input type="checkbox" checked={true} ref={'ref_' + i}/>
<button onClick={()=>this.unCheck(i)}>Toggle</button>
</div>
)
})}
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Check this example of controlled element, means storing the state of checkbox inside state variable, and on click of button change the value of that:
class App extends React.Component{
constructor(){
super();
this.state = {value: []}
}
onChange(e, i){
let value = this.state.value.slice();
value[i] = e.target.checked;
this.setState({value})
}
unCheck(i){
let value = this.state.value.slice();
value[i] = !value[i];
this.setState({value})
}
render(){
return (
<div>
{[1,2,3,4,5].map((item,i) => {
return (
<div>
<input checked={this.state.value[i]} type="checkbox" onChange={(e) => this.onChange(e, i)}/>
<button onClick={()=>this.unCheck(i)}>Toggle</button>
</div>
)
})}
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>

React
Checked
Using State
<input type="radio" name="count" value="minus" onChange={this.handleRadioChange} checked={this.state.operation == "minus"} /> Decrement
2.Using Refs
<input type="radio" name="count" ref="minus" /> Decrement
onSubmit(e){ this.refs.minus.checked = false }

Using plain javascript you can acheive like below.
function unCheck() {
var x = document.getElementsByClassName("checkbox");
for(i=0; i<=x.length; i++) {
x[i].checked = false;
}
}
Small DEMO

I was thinking of a thing like that:
<input onChange={(input) => this.onFilterChange(input)} className="form-check-input" type="checkbox" />
onFilterChange = (input) => { let { value, checked } = input.target;}
unCkeckAll = () => {
[...document.querySelectorAll('.form-check-input')].map((input) => {
if (input.checked) {
let fakeInput = {
target: {
value: input.value,
checked: false
}
}
input.checked = !input.checked;
this.onFilterChange(fakeInput);
}
return null;
})
}

Checkboxes have a checked property, you can hook it to the state and change it dynamically. Check these links:
https://facebook.github.io/react/docs/forms.html#handling-multiple-inputs
http://react.tips/checkboxes-in-react/

Sometime its good to use plain javascript. If you have of checkbox value in any of your state then try this
let checkboxValue = xyz
document.querySelectorAll("input[value="+checkboxValue+"]")[0].checked = false;

Related

Is it possible to disable fileds using th:disabled based on a value from the js file in thymeleaf

I have few fields which need to be disabled based on a value which is being defined in the js file. Is it possible to do so?
Instead of setting disabled through javascript you could add the disabled to the HTML input element:
<input class="form-control" id="form_input" disabled="disabled" .... />
Then in your javascript:
document.getElementById('form_input').onchange = function ()
{
if (this.value == '0')
{
document.getElementById("form_input").disabled = true;
}
else
{
document.getElementById("form_input").disabled = false;
}
}
not sure if it just in JS possible, but with react:
function() {
const [value, setValue] = useState(false)
const handleChange= () => {
setValue(!value)
}
return(
<>
<input type="checkbox" onClick={handleChange}/>
<input type="text" disabled={value}/>
</>
)}
then you validate the value with a function in your script.

how to disable a button if more than once check box is checked in React JS

I have to create a button that activates when a check box is checked and disables when unchecked.
I was able to achieve this by the following code.
import React from "react";
import "./styles.css";
import{useState} from 'react'
export default function App() {
const [change, setChange] = useState(true);
function buttonHandler(){
setChange(!change)
}
return (
<div className="App">
<button disabled={change}>Click Me</button>
<input type="checkbox" onChange={buttonHandler}/>
<input type="checkbox" onChange={buttonHandler}/>
<input type="checkbox" onChange={buttonHandler}/>
</div>
);
}
Now I have another challenge where I have to keep it disabled if more than 1 check box is checked. I tried to use object and array manipulation but it does not work. Any advice on how this can be achieved.
import React from "react";
import{useState} from 'react'
export default function App() {
const [checkboxStatus, setCheckboxStatus] = useState(Array(3).fill(false));
function buttonHandler(index){
let status = [...checkboxStatus];
status[index] = !status[index]
setCheckboxStatus(status)
}
return (
<div className="App">
<button disabled={checkboxStatus.filter(status => status === true).length != 1}>Click Me</button>
{Array(3).fill(0).map((_, index) => <input type="checkbox" checked={checkboxStatus[index]} onChange={() => buttonHandler(index)}/>)}
</div>
);
}
You can do that by keeping track of the status of the checkbox rather than tracking the status of the button. This is because if you know the status of all the checkboxes, you can easily calculate the status of the button.
I have also taken the liberty of converting the checkbox to map it since the content is the same. You can do the same by passing the index to each of them. Something like <input type="checkbox" onChange={() => buttonHandler(0}/> and so on for each of the inputs.
Wrap your input elements in a parent element like form or div.
Maintain state; an array that contains each box status (either true or false). When a box is changed call the handleChange which will update the state.
The button disabled property should call a function called isDisabled which will check to see if there are zero boxes checked or more than one box checked, returning true if the condition is matched.
const { useEffect, useState } = React;
function Example() {
const [boxes, setBoxes] = useState([]);
// In the text I suggested wrapping the inputs in
// a parent element. This was so we could use the following
// code to find its index within the list of inputs
// without adding any more code to the JSX
// Cribbed from https://stackoverflow.com/a/39395069/1377002
function handleChange(e) {
// Destructure the children from the parent of
// the element that was changed (ie all the input elements)
const { parentNode: { children } } = e.target;
// Find the index of the box that was changed
const index = [...children].indexOf(e.target);
// Copy the state
const newState = [...boxes];
// Toggle the boolean at the index of
// the `newState` array
newState[index] = !newState[index];
// Set the state with the updated array
setBoxes(newState);
}
// `filter` the boxes that return true.
// Return true if the length is 0 or > 1.
function isDisabled() {
const len = boxes.filter(box => box).length;
return len === 0 || len > 1;
}
return (
<div className="App">
<button disabled={isDisabled()}>Click Me</button>
<form>
<input type="checkbox" onChange={handleChange}/>
<input type="checkbox" onChange={handleChange}/>
<input type="checkbox" onChange={handleChange}/>
</form>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Additional documentation
Destructuring assignment
Spread syntax

If I use defaultChecked, sorting table columns does not change the position of the checkbox

If I use "defaultChecked", sorting table columns does not change the position of the checkbox.
If use "checked", I can change position but checkbox doesn't work correctly.
How can I fix it?
Here is the code: https://jsfiddle.net/sakanyan/e2a56mbk/29/
enter code here
<input type="checkbox" checked={item.hasItem} /*OR
defaultChecked={item.hasItem} */ />
Missing something like this:
constructor(props) {
//....
this.onCheck = this.onCheck.bind(this);
}
//...
onCheck(event) {
let s = Object.assign({}, this.state);
let d = s.data.find( s => s.id == e.target.name );
if( !d ) return;
d.hasItem = !d.hasItem;
this.setState(s);
}
render() {
//...
<input name = {item.id} type='checkbox' checked={item.hasItems} onChange={this.onCheck} />
//...
}
Previously, you're checkbox were never updated (in state) so the sort appears to be wrong.
Try this,
constructor(props) {
super(props)
state = {
hasItems = false;
}
}
handleCheck = event => {
this.setState({hasItems : !this.state.hasItems })
}
render(){
return(
//....
<input
type="checkbox"
checked={this.state.hasItem}
onChange={this.handleCheck}
>
//....
)
}

Store multiple checkbox inputs in local storage

I have multiple checkbox inputs that look like this:
<input type="checkbox" id="box-1">
<input type="checkbox" id="box-2">
<input type="checkbox" id="box-3">
I want to store their values (checked or unchecked) in the browser's local store.
The javascript that I'm using to do this is:
function onClickBox() {
let checked = $("#box-1").is(":checked");
let checked = $("#box-2").is(":checked");
let checked = $("#box-3").is(":checked");
localStorage.setItem("checked", checked);
}
function onReady() {
let checked = "true" == localStorage.getItem("checked");
$("#box-1").prop('checked', checked);
$("#box-2").prop('checked', checked);
$("#box-3").prop('checked', checked);
$("#box-1").click(onClickBox);
$("#box-2").click(onClickBox);
$("#box-3").click(onClickBox);
}
$(document).ready(onReady);
The first part saves the checkbox's state on the click and the second part loads it when the page refreshes.
This works well if the lines for box 2 and 3 are removed, but I need it to work with all the checkboxes.
Your main issue here is that you're only storing a single value in localStorage, checked, which will be overwritten every time you check a different box. You instead need to store the state of all boxes. An array is ideal for this, however localStorage can only hold strings, so you will need to serialise/deserialise the data when you attempt to read or save it.
You can also simplify the logic which retrieves the values of the boxes by putting a common class on them and using map() to build the aforementioned array. Try this:
<input type="checkbox" id="box-1" class="box" />
<input type="checkbox" id="box-2" class="box" />
<input type="checkbox" id="box-3" class="box" />
jQuery($ => {
var arr = JSON.parse(localStorage.getItem('checked')) || [];
arr.forEach((c, i) => $('.box').eq(i).prop('checked', c));
$(".box").click(() => {
var arr = $('.box').map((i, el) => el.checked).get();
localStorage.setItem("checked", JSON.stringify(arr));
});
});
Working example
function onClickBox() {
let checked1 = $("#box-1").is(":checked");
let checked2 = $("#box-2").is(":checked");
let checked3 = $("#box-3").is(":checked");
localStorage.setItem("checked1", checked1);
localStorage.setItem("checked2", checked2);
localStorage.setItem("checked3", checked3);
}
function onReady() {
let checked1 = "true" == localStorage.getItem("checked1");
let checked2 = "true" == localStorage.getItem("checked2");
let checked3 = "true" == localStorage.getItem("checked3");
$("#box-1").prop('checked', checked1);
$("#box-2").prop('checked', checked2);
$("#box-3").prop('checked', checked3);
$("#box-1").click(onClickBox);
$("#box-2").click(onClickBox);
$("#box-3").click(onClickBox);
}
$(document).ready(onReady);
Of course you could simplify it further by doing
function onClickBox(boxNumber) {
let checked = $("#box-" + boxNumber).is(":checked");
localStorage.setItem("checked" + boxNumber, checked);
}
function onReady() {
[1, 2, 3].forEach( function(boxNumber) {
$("#box-" + boxNumber).prop(
'checked',
localStorage.getItem("checked" + boxNumber)
);
$("#box-" + boxNumber).click( function() {
localStorage.setItem(
"checked" + boxNumber,
$("#box-" + boxNumber).is(":checked")
);
});
})
}
$(document).ready(onReady);
Your check variable is getting overwritten, you can put it inside for loop.
So your code becomes,
function onClickBox() {
for(var i=1;i<=3;i++){
let checked=$("#box-"+i).is(":checked");
localStorage.setItem("checked-"+i, checked);
}
}
function onReady() {
for(var i=1;i<=3;i++){
if(localStorage.getItem("checked-"+i)=="true"){
var checked=true;
}
else{
var checked=false;
}
$("#box-"+i).prop('checked', checked);
onClickBox();
}
}
$(document).ready(onReady);
Please follow the below Code (Very Simple Javascript works)
<input type="checkbox" id="box">checkbox</input>
<button type="button" onClick="save()">save</button>
<script>
function save() {
var checkbox = document.getElementById("box");
localStorage.setItem("box", checkbox.checked);
}
//for loading...
var checked = JSON.parse(localStorage.getItem("box"));
document.getElementById("box").checked = checked;
</script>
with simple modification, you can use it without save button..
Hope this Helps you..

How to organize multiple checkboxes?

I want to organize multiple checkboxes. I decided to keep an array of ids of chosen boxes in state.And using method want to give them statuses "checked".
constructor(props) {
super(props);
this.state = {
checkboxes: []
}
}
for(let i=0; i<checkboxData.length; i++) {
checkboxes.push(
<List.Item key = { checkboxData[i].id }>
<div className="ui checkbox">
<input type="radio"
id={checkboxData[i].id}
checked={ ()=>this.getCheckboxStatus(checkboxData[i].id)}
onChange = { this.setTag }
/>
<label>{checkboxData[i].name}</label>
</div>
<List.Content floated="right" >
<Label>
0
</Label>
</List.Content>
</List.Item>
);
}
getCheckboxStatus = checkBoxId => {
let { checkboxes } =this.props;
console.log('IDS', checkBoxId)
if (checkboxes.length === 0) {
return false;
} else if (checkboxes.indexOf(checkBoxId)!==-1){
return true;
}
return false;
};
setTag = e => {
let { checkboxes } = this.state;
if ( checkboxes.length === 0 ) {
checkboxes.push( e.target.id );
} else {
if(checkboxes.indexOf(e.target.id)!==-1) {
checkboxes.splice(checkboxes.indexOf(e.target.id),1);
} else {
checkboxes.push( e.target.id );
}
}
this.setState({ checkboxes: checkboxes })
}
React renders it and throws in console:
Warning: Invalid value for prop `checked` on <input> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.
How I understand this is because I'm using method for checked attribute. How can I do same thing and not receive warning?
Your input type needs to be checkbox, not radio. You also need to reference state with your checked attribute.
<input
type="checkbox"
id={checkboxData[i].id}
checked={this.state.checkBoxes[i]}
onChange={this.setTag}
/>
This will set state with true or false depending on the state of the checkbox

Categories

Resources