1

I am trying to conditionally disable the checkbox in react, based on the count. Passing the value through props whether it is checked and greater than the number. I am saving the name in the state to further process it to send to in the backend database. Here is my react code.

class CheckboxComponent extends Component {
        constructor(props) {
            super(props);

            this.state = {
                checkedItems: {}
            };
        }

         handleChange = (event, formKey) => {
            const {checkedItems} = this.state;
            const checkedValues = {...checkedItems};
            checkedValues[event.target.name] = event.target.checked;

            this.setState((prevState, currState) => {
                return {
                    ...prevState,
                    checkedItems: checkedValues
                }
            });
            
        };

        render = () => { 
            const {checkedItems} = this.state;
            const checkedValues = {...checkedItems};
            const checkedCount = Object.values(checkedValues).length;
            const checked = Object.values(checkedValues);
            const disabled = checkedCount >= 3; 

       return (
         <div>
           {checkboxes.map((item, index) => (
                        <label className={`form__field__input__label`} key={item.key}>
                            <Input
                                type={`checkbox`} 
                                name={item.name}
                                checked={this.state.checkedItems[item.name] || false}
                                onChange={this.handleChange}
                                formKey={'subjects'}
                                disabled={(!checked[index] && checked.length > 3)}
                            />
                            {item.name}
                        </label>
                    ))}
         </div>
       )

This is the Array that I am passing to render the values in the checkbox

const checkboxes = [
            {
                name: "Math and economics",
                key: "mathsandeconomics",
                label: "Math and economics"
            },
            {
                name: "Science",
                key: "Science",
                label: "Science"
            },
9
  • do you want to disable checkbox as soon it is mark as checked? Commented Dec 18, 2020 at 13:00
  • I want to disable checkboxes which are not checked and if they are more than 3 checked. Commented Dec 18, 2020 at 13:01
  • i see you storing checked status to state....so all checkboxes will be un-checked initially. Commented Dec 18, 2020 at 13:16
  • 1
    I have provided the complete solution for you with complete logs as well. This one was really really challenging, indeed. :) Any ways enjoy and do vote and accept the answer mate. Thank you :) Commented Dec 18, 2020 at 14:35
  • 1
    You are welcome mate. Life is about accepting challenges, I guess. hehe... NOW ENJOY Buddy. God bless Commented Dec 18, 2020 at 15:33

5 Answers 5

1

The below code snippet will work fine for you. And you can sent object to the backend having maximum of only 3 properties set to true. Get the full code from codesandbox link https://codesandbox.io/s/emmeiwhite-0i8yh

import React from "react";

const checkboxes = [
  {
    name: "Math and economics",
    key: "mathsandeconomics",
    label: "Math and economics",
  },
  {
    name: "Science",
    key: "science",
    label: "Science",
  },
  {
    name: "history",
    key: "history",
    label: "history",
  },
  {
    name: "literature",
    key: "literature",
    label: "literature",
  },
];

class CheckboxComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      checkedItems: {},
      count: 0,
    };
  }

  handleChange = (event, formKey) => {
    const { name, checked } = event.target;
    const updatedCheckedItems = { ...this.state.checkedItems, [name]: checked };

    this.setState({
      checkedItems: updatedCheckedItems,
      count: Object.values(updatedCheckedItems).filter((value) => value).length,
    });
  };

  render = () => {
    const checkedValues = { ...this.state.checkedItems };
    const checkedCount = Object.values(checkedValues).filter((value) => value)
      .length;

    console.log(this.state.checkedItems);

    return (
      <div>
        {checkboxes.map((item, index) => (
          <label className={`form__field__input__label`} key={item.key}>
            <input
              type={`checkbox`}
              name={item.name}
              checked={this.state.checkedItems[item.name] || false}
              onChange={this.handleChange}
              disabled={!checkedValues[item.name] && checkedCount > 2}
            />
            {item.name}
          </label>
        ))}
      </div>
    );
  };
}

export default CheckboxComponent;

Sign up to request clarification or add additional context in comments.

8 Comments

This 1 was really great! Thank you so much !
Oh dear, it's my pleasure.
Can you please let me know how can i disable a checkbox with a particular name from the array ?
Mate Have no energy left to think stuff . Would share a resource for you to learn and build on top of it. scrimba.com/learn/learnreact/react-form-part-2-cGKqZUQ I have completed this full course many times in the past. Give it a try also :) Stay blessed. Would go for Dinner now:)
Hey... I am not able to find out how to disable checkbox if a checkbox with name is checked. Can you please help bro
|
1
  1. Your checked.length counts all touched boxes, not checked only. If you uncheck an input, it still will be counted. Count only true, for example Object.values(checkedValues).filter(value => value).length.
  2. Use names instead of indexes: disabled={!checkedValues[item.name] && checkedCount > 3}

You can see full solution here: https://codesandbox.io/s/confident-http-vlm04?file=/src/App.js

Comments

0
event.target.getAttribute('name'); 

try this to get name attribute, pretty sure event.target.name is 'undefined'

Comments

0

I see one use case is not taken care of. checkedCount should count the number of true values only.

const checkedCount = Object.values(checkedValues).length; // existing
const checkedCount = Object.values(checkedValues).filter(item=>item==true).length //replace with this line

This would solve the problem.

Comments

0

Here is the code and as well as codesandbox link Codesandbox Link

import React from "react";
export class CheckboxComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      checkedItems: {},
      checkedCount: 0
    };
  }

  handleChange = (event, formKey) => {
    const { checkedItems } = this.state;
    const checkedValues = { ...checkedItems };
    checkedValues[event.target.name] = event.target.checked;

    this.setState((prevState, currState) => {
      return {
        ...prevState,
        checkedItems: checkedValues,
        checkedCount: event.target.checked
          ? prevState.checkedCount + 1
          : prevState.checkedCount - 1
      };
    });
  };

  render = () => {
    const { checkboxes } = this.props;
    const { checkedCount } = this.state;
    const disabled = checkedCount >= 3;

    return (
      <div>
        <p></p>
        {checkboxes.map((item, index) => (
          <label className={`form__field__input__label`} key={item.key}>
            <input
              type={`checkbox`}
              name={item.name}
              checked={this.state.checkedItems[item.name] || false}
              onChange={this.handleChange}
              disabled={!this.state.checkedItems[item.name] ? disabled : false}
            />
            {item.name}
          </label>
        ))}
      </div>
    );
  };
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.