How to fix Checkbox bug? - javascript

Whenever I try to click the checkbox on the page it doesn't check the actual box. I know this is something wrong in my ReactJS but I don't know what I am doing wrong. Can you possibly help?
I have tried researching answers on stack and other websites but have turned up with nothing.
class Description extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false,
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
<input
name="Checking Account"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Checking Account
</label>
<label>
<input
name="Savings Account"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Savings Account
</label>
<label>
<input
name="CDs/Money Market Accounts"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
CDs/Money Market Accounts
</label>
<br />
<label>
<input
name="Student Banking"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Student Banking
</label>
<label>
<input
name="Auto Loans"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Auto Loans
</label>
<label>
<input
name="Home Equity"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Home Equity
</label>
<br />
<label>
<input
name="Mortgage"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Mortgage
</label>
<label>
<input
name="Student Loans"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Student Loans
</label>
<label>
<input
name="Saving for Retirement"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Saving for Retirement
</label>
<br />
<label>
<input
name="Investment Account"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Investment Account
</label>
<label>
<input
name="Credit Card"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Credit Card
</label>
<label>
<input
name="Other"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
Other
</label>
</form>
);
}
}
ReactDOM.render(
<Description/>,
document.getElementById('checkbox')
);
I would like for the program to be able to check the box by the end of this!

Here is one example for Student Banking
Change name Student Banking to studentBanking
Change this.state.checked to this.state.studentBanking
Change
<input
name="Student Banking"
type="checkbox"
checked={this.state.checked}
onChange={this.handleInputChange} />
To
<input
name="studentBanking"
type="checkbox"
checked={this.state.studentBanking}
onChange={this.handleInputChange} />
Do the same for other input checkboxes as well

You need to set the checked state value using setState in your onChange event.
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
checked: value
});
}

That is because you are setting state as { "Credit Card": true } when clicking on Credit Card. What you can do is just set the values accordingly.
I have a simple demo using your code itself.

You are setting the State correctly but the check isn't working because of the way the checked is bound.
please change
checked={this.state.checked}
to
checked={this.state.StudentBanking}
also, remove the space in your names
<input
name="CheckingAccount"
type="checkbox"
checked={this.state.CheckingAccount}
onChange={this.handleInputChange} />

Related

How to check whether all the checkboxes are checked in Reactjs?

I am new to react and I got a scenario where I have multiple checkboxes on my form. I want the user to check all the checkboxes only then enable the submit button on the form. On Load, the submit button will be disabled. How to do this?
Here is the code that I have written so far:
const MultipleCheckboxes = () => {
const handleChange = () => {
}
const allChecked = () => {
}
return (
<div>
<form>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Java"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Javascript
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Angular"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Angular
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Python"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Python
</label>
</div> <br />
<button disabled={!allChecked}>Submit</button>
</form>
</div>
);
};
export default MultipleCheckboxes;
Can anybody help me on this? thank you
This is my solution, I hope it helps you
import { useState, useEffect } from "react";
const MultipleCheckboxes = () => {
const [allChecked, setAllChecked] = useState(false);
const [checkboxes, setCheckboxes] = useState({
javaCheckbox: false,
angularCheckbox: false,
pythonCheckbox: false
});
function handleChange(e) {
setCheckboxes({
...checkboxes,
[e.target.id]: e.target.checked
})
}
useEffect(() => {
const result = Object.values(checkboxes).every(v => v);
console.log(result);
setAllChecked(result);
}, [checkboxes]);
return (
<div>
<form>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.javaCheckbox}
id="javaCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Javascript
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.angularCheckbox}
id="angularCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Angular
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.pythonCheckbox}
id="pythonCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Python
</label>
</div> <br />
<button disabled={!allChecked}>Submit</button>
</form>
</div>
);
};
export default MultipleCheckboxes;
You can use react useState hook and set its default value to false.
const [state, setstate] = useState(false)
When the user clicks on an input box set the state to true. You may encounter some problems when the user unchecks the box, so you can use an if statement to handle state change
For example:
if (state === true){
setstate(false)
}else{
setstate(true)
}
or you can just use this code inside the handleChange function:
!state
It inverses the state to true/false accordingly.
After that you can use a ternary operator inside the component to check whether the user has checked all the boxes, if the user hasn't checked all the boxes, disable the button or else do otherwise.
For example, if the state is true (or in other words, if the user has checked the box), render the normal styled button, else render the disabled button:
{state? <button className = "styled"/>: <button disabled className="styled"/>}
Of course, I have only checked the state of one input box. Now you can simply check for multiple conditions by declaring multiple states for each box.
{state1 && state2 && state3 ? <button className = "styled"/>: <button disabled className="styled"/>}
If you are not yet familiar with ternary operators, you should go through this doc Ternary operators.
If you haven't heard of useState and react hooks yet, feel free to look the React's documentation. Welcome to the React ecosystem!

how to Creating a single input handler [duplicate]

This question already has answers here:
Handle change event of all input fields without using refs
(2 answers)
Closed 2 years ago.
I have several inputs ,Each of the inputs has its own value .How can I have a function for (onChange) all of them ?
For example
handleChange1(event) {
this.setState({value1: event.target.value});
}
handleChange2(event) {
this.setState({value2: event.target.value});
}
}
handleChange3(event) {
this.setState({value3: event.target.value});
}
<input type="text" value={this.state.value1} onChange={this.handleChange1} />
<input type="text" value={this.state.value2} onChange={this.handleChange2} />
<input type="text" value={this.state.value3} onChange={this.handleChange3} />
I just want to have one handleChange
When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name.
For example:
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
value1:
<input
name="value1"
type="checkbox"
checked={this.state.value1}
onChange={this.handleInputChange} />
</label>
<br />
<label>
value2:
<input
name="value2"
type="number"
value={this.state.value2}
onChange={this.handleInputChange} />
</label>
<br />
<label>
value3:
<input
name="value3"
type="text"
value={this.state.value3}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
If you add a name to the input you can use that off of the event.
handleChange1(event) {
const {name, value} = event.target
this.setState({[name]: value});
}
<input name="inputone" type="text" value={this.state.value1} onChange={this.handleChange1} />
<input name="inputtwo" type="text" value={this.state.value2} onChange={this.handleChange2} />
<input name="inputthree" type="text" value={this.state.value3} onChange={this.handleChange3} />
You can simply do by using input name:
Code:
import React from "react";
import "./styles.css";
class MyComponent extends React.Component {
state = {
value1: "",
value2: "",
value3: ""
};
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
console.log(this.state);
return (
<>
<input
name="value1"
value={this.state.value1}
type="text"
value={this.state.value1}
onChange={this.handleChange}
/>
<input
name="value2"
value={this.state.value2}
type="text"
value={this.state.value2}
onChange={this.handleChange}
/>
<input
name="value3"
value={this.state.value3}
type="text"
value={this.state.value3}
onChange={this.handleChange}
/>
</>
);
}
}
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<MyComponent />
</div>
);
}
Demo: https://codesandbox.io/s/beautiful-brook-p46zs?file=/src/App.js:0-1092
i always do this by switch case
handleChange(event) {
switch (event.target.name) {
case 'name1':
this.setState({ name1: event.target.value });
break;
case 'name2':
this.setState({ name2: event.target.value });
break;
case 'name3':
this.setState({ name3: event.target.value });
break;
default:
break;
}
}
<input type="text" name="name1" value={this.state.value1} onChange={this.handleChange1} />
<input type="text" name="name2" value={this.state.value2} onChange={this.handleChange2} />
<input type="text" name="name3" value={this.state.value3} onChange={this.handleChange3} />
You can use react hooks useState for each field:
const [value1,setvalue1] = useState();
<input type="text" value={value1} onChange={(e)=>setvalue1(e.target.value)}/>
You still do have handle change to each input but you write less code.
You can also look here for more info about react hooks: https://reactjs.org/docs/hooks-state.html
If all inputs are same, I think we can render them dynamically so we don't need to repeat ourself and also make the code more clean.
I think we can have an array of inputs then render dynamically. By using closure, we can have one handleChange function for all inputs.
state={
inputValues: []
}
handleChange(index){
return (event)=>{
this.state.inputValues[index] = event.target.value;
this.setState({inputValues: this.state.inputValues})
}
}
render(){
return this.states.inputValues.map((inputValue, index)=>
<input type="text" value={inputValue} onChange={this.handleChange(index)} />
)
}

Radio button global state for name attribute

I need to be able to have radion buttons or checkboxes to show / hide content if its checked. There will be more radio buttons and checkboxes to show content in the same form, so to distinguish them from each other, it could be based on the name attribute.
So far i can show the hidden fields when i check the radio buttons, but i want one to cancel out the other, but only if it has the same name attribute (something else can also work).
Is there a react genius who can figure this out? I would be forever in your debt :)
class PartnerRoute extends Component {
constructor(props) {
super(props)
this.state = {
showOneTimeFee: '',
showSubscription: ''
};
}
toggleOneTimeFee = () => {
const currentState = this.state.showOneTimeFee;
this.setState({
showOneTimeFee: !currentState
})
}
toggleSubscription = () => {
const currentState = this.state.showSubscription;
this.setState({
showSubscription: !currentState
})
}
render() {
return (
<div className="partner-route">
<ContentContainer>
<div className="form--create-event">
<form>
<h3>Event information</h3>
<GridContainer columnCount="one">
<CustomInput type="text" placeholder="Event name" />
</GridContainer>
<GridContainer columnCount="one">
<CustomTextarea type="text" placeholder="Event description" />
</GridContainer>
<h3>Event date</h3>
<GridContainer columnCount="three">
<CustomInput type="text" placeholder="Day" />
<CustomInput type="text" placeholder="Month" />
<CustomInput type="text" placeholder="Year" />
</GridContainer>
<h3>Payment</h3>
<GridContainer columnCount="one">
<CustomRadio
type="radio"
name="payment"
id="rb1"
value="1"
label="Free, no payment needed"
/>
<CustomRadio
type="radio"
name="payment"
id="rb2"
value="2"
label="1 time fee"
onChange={this.toggleOneTimeFee}
/>
{this.state.showOneTimeFee &&
<div className="hidden-field">
<CustomInput type="text" placeholder="Price" />
</div>
}
<CustomRadio
type="radio"
name="payment"
id="rb3"
value="3"
label="Subscription"
onChange={this.toggleSubscription}
/>
{this.state.showSubscription &&
<div className="hidden-field">
<CustomInput type="text" placeholder="Price" />
</div>
}
</GridContainer>
</form>
</div>
</ContentContainer>
</div>
)
}
}
export default PartnerRoute
Please check this example where I used setState with prevState that is important and also I used changeHandler for all three radio. Moreover, to run this code in my side I changed all Custom input with generic input for ex CustomInput to input. Please revert this your side.
import React, {Component} from "react";
export default class PartnerRoute extends Component {
constructor(props) {
super(props);
this.state = {
showOneTimeFee: false,
showSubscription: false
};
}
handleChange = (event) => {
if (event.target.value == 2) // One Time Fee
this.setState(prevState => {
return {
showOneTimeFee: !prevState.showOneTimeFee,
showSubscription: false
};
});
else if (event.target.value == 3) // Subscription
this.setState(prevState => {
return {
showOneTimeFee: false,
showSubscription: !prevState.showSubscription
};
});
else // Free, no payment needed
this.setState({
showOneTimeFee: false,
showSubscription: false
});
};
render() {
return (
<div className="partner-route">
<div>
<div className="form--create-event">
<form>
<h3>Event information</h3>
<div>
<input type="text" placeholder="Event name"/>
</div>
<div>
<input type="text" multiline="true" placeholder="Event description"/>
</div>
<h3>Event date</h3>
<div>
<input type="text" placeholder="Day"/>
<input type="text" placeholder="Month"/>
<input type="text" placeholder="Year"/>
</div>
<h3>Payment</h3>
<div>
<input type="radio" name="payment" id="rb1" value="1" label="Free, no payment needed"
onChange={this.handleChange}/>
<label htmlFor="rb1">Free, no payment needed</label><br/>
<input type="radio" name="payment" id="rb2" value="2" label="1 time fee"
onChange={this.handleChange}/>
<label htmlFor="rb2">1 time fee</label><br/>
{this.state.showOneTimeFee &&
<div className="hidden-field">
<input type="text" placeholder="One Time Price"/>
</div>
}
<input type="radio" name="payment" id="rb3" value="3" label="Subscription"
onChange={this.handleChange}/>
<label htmlFor="rb3">Subscription</label><br/>
{this.state.showSubscription &&
<div className="hidden-field">
<input type="text" placeholder="Subscription Price"/>
</div>
}
</div>
</form>
</div>
</div>
</div>
)
}
}

Reactjs redux-form fields - custom checkbox/radiobox component - bug in initial checked

I am working on a custom radiobutton/checkbox component -- based off the renderField. The component appears to render fine, but when I've added a "checked" parameter to this it breaks. The field is selected correctly - but when toggling options it looks like it tries to force check the old item.
//renderField
import React from 'react'
const renderField = ({input, label, type, meta: {touched, error, warning}}) => (
<div className='field'>
<label>
{touched &&
<span>
{label}
</span>
}
{touched &&
((
error &&
<span className="error">
: {error}
</span>) ||
(
warning &&
<span className="warning">
: {warning}
</span>
))}
</label>
<div>
<input {...input} placeholder={label} type={type} />
</div>
</div>
)
export default renderField
here is the new field -- the markup is different to the standard input fields.
//renderRadioCheckField
import React from 'react'
import _ from 'underscore';
function renderRadioCheckField({input, label, type, checked, meta: {touched, error, warning}}) {
const randId = _.uniqueId('radiocheck_');
return (
<div className='field'>
<div>
<input {...input} placeholder={label} type={type} id={randId} checked={checked} />
<label className="group-label" htmlFor={randId}>
{label}
</label>
</div>
</div>
);
}
export default renderRadioCheckField
--
on my form component I am importing these in and calling them as such
<Field name="test" type="text" component={renderField} label="test" />
<br/><br/>
<Field name="radio-group1" type="radio" component={renderRadioCheckField} value="check1" label="Apple2" />
<Field name="radio-group1" type="radio" component={renderRadioCheckField} value="check2" label="Peach2" checked="true" />
<Field name="radio-group1" type="radio" component={renderRadioCheckField} value="check3" label="Orange2" />
<br/><br/>
<Field name="check-group1" type="checkbox" component={renderRadioCheckField} value="check1" label="Yes" />
<Field name="check-group1" type="checkbox" component={renderRadioCheckField} value="check2" label="No" checked="true" />
Don't use the checked="true". Instead do following in your componentDidMount() method of React Redux Form component.
componentDidMount(){
const {radio-group1} = this.props;
//Sets initial default checked value
this.props.change('radio-group1','check2');
}
You can do same for checkboxes.

ReactJS - Waiting for user to finish multiple inputs

I just started learning ReactJS so any help would be appreciated. I'm trying to make a form where user inputs his/her address into multiple input fields. When the user finishes typing into ALL input fields, then a function will be triggered to validate the address. Through research, I found out about onChange and onBlur but it seems like that only works for one input field. Is there any other way to keep track of all five inputs and trigger a function after the user finishes? Or if there is any way to use onChange to do so, I would love to know. The following is the code for my form. Thank you in advance.
<form>
<label>
<DebounceInput
name="addressLine1"
placeholder="Address Line 1"
debounceTimeout={300}
onChange={ (e) => this.handleChange(e, name)}
/>
</label>
<label>
<DebounceInput
name="addressLine2"
placeholder="Address Line 2"
debounceTimeout={300}
onChange={ (e) => this.handleChange(e, name)}
value={this.state.address.addressLine2}
/>
</label>
<label>
<DebounceInput
name="city"
placeholder="City"
debounceTimeout={300}
onChange={ (e) => this.handleChange(e, name)}
value={this.state.address.city}
/>
</label>
<label>
<br />
<DebounceInput
name="state"
placeholder="State"
debounceTimeout={300}
onChange={ (e) => this.handleChange(e, name)}
value={this.state.address.state}
/>
</label>
<label>
<DebounceInput
name="postalCode"
placeholder="Postal Code"
debounceTimeout={300}
onChange={ (e) => this.handleChange(e, name)}
value={this.state.address.postalCode}
/>
</label>
</form>
Maybe you can incorporate a condition inside of your handleChange function, where you check if your currentstate is sufficient to do a validation, if so you can trigger the validation.

Categories

Resources