Get "checked=true/false" value of checkbox from inside HTML attributes

crevulus

I want to enable and disable checkboxes based on two variables: 1) Is there already a checked count of 2+, 2) Is the current checkbox enabled or disabled. i.e. I have a list of items, and I want to limit the user to only selecting two out of (potentially) endless options.

I have a handleCheck() function, but I think by the time that's applied it's already too late to control the checked value of the checkbox, right? Because I can successfully call alert() after the user has checked their third box, but then the check appears anyway; I can't stop it from being checked. That's why I'd like to put the control inside the HTML: the checkbox will be disabled if the count is more than two and the user hasn't chosen this checkbox. In order to choose this checkbox, they'd have to deselect another.

What I essentially want to do is this:

disabled={count >= 2 && thisCheckbox.checked === false}

I'm using React to dynamically render checkbox + a whole load of data and visuals on a case-by-case basis, so it's not like all the checkboxes are in one neat form.

I've tried various SO threads but most of them use jQuery or do their handling in JS in the onChange function (handleCheck(), in my case), which is already too late because the check will still be applied (as far as I know).

EDIT

Here's a sandbox link with the basic set up: https://codesandbox.io/s/nameless-sun-3jsmn?file=/src/TestimonialsSettingsUnit.js

Diwakar Singh

I have fixed the issue and you can refer working code here - https://codesandbox.io/s/focused-tereshkova-f95jj?file=/src/App.js

import "./styles.css";

import React, { useState, useEffect } from "react";

import TestimonialsSettingsUnit from "./TestimonialsSettingsUnit.js";

const data = [
  {
    name: "Test1",
    id: 1,
    otherData: "This is a testimonial about Test1",
    show: true
  },
  {
    name: "Test2",
    id: 2,
    otherData: "This is a testimonial about Test2",
    show: true
  },
  {
    name: "Test3",
    id: 3,
    otherData: "This is a testimonial about Test3",
    show: false
  }
];

const App = () => {
  const [selectedTestimonials, setSelectedTestimonials] = useState([]);
  const [testimonials, setTestimonials] = useState(data);

  useEffect(() => {
    const selectedTestimonials = testimonials
      .filter(({ show }) => show)
      .map(({ id }) => id);
    setSelectedTestimonials(selectedTestimonials);
  }, [testimonials]);

  const handleCheckboxChange = (testimonialId, show) => {
    const updatedTestimonials = testimonials.map((testimonial) => {
      if (testimonial.id === testimonialId) {
        return {
          ...testimonial,
          show
        };
      }
      return testimonial;
    });
    setTestimonials(updatedTestimonials);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      {data.map((testimonial, i) => {
        const isSelected = selectedTestimonials.includes(testimonial.id);
        const isDisabled = !isSelected && selectedTestimonials.length === 2;
        return (
          <TestimonialsSettingsUnit
            key={testimonial.id}
            index={i}
            data={testimonial}
            handleCheckboxChange={handleCheckboxChange}
            isSelected={isSelected}
            isDisabled={isDisabled}
          />
        );
      })}
    </div>
  );
};

export default App;

import React from "react";

export default function TestimonialsSettingsUnit({
    data,
    index,
    handleCheckboxChange,
    isSelected,
    isDisabled
}) {
    const handleCheck = (event) => {
        const { target: { checked } } = event
        handleCheckboxChange(data.id, checked)
    };

    return (
        <div className="settings-testimonials-container">
            <h4>Testimonial {index + 1}</h4>
            <div className="settings-testimonial-controls">
                <img
                    className="settings-profile-img"
                    src={data.authorPhoto}
                    alt="User"
                />
                <div className="settings-testimonial-info">
                    <div>
                        <p>Name</p>
                        <h5>{data.authorName}</h5>
                    </div>
                    <div>
                        <p>Company</p>
                        <h5>{data.authorCompany}</h5>
                    </div>
                    <div>
                        <p>Position</p>
                        <h5>{data.authorTitle}</h5>
                    </div>
                </div>
                <div className="settings-testimonial-buttons">
                    <button>Delete</button>
                    <br />
                    <input
                        id="show"
                        type="checkbox"
                        name={`testimonial-${index + 1}`}
                        checked={isSelected}
                        onChange={handleCheck}
                        disabled={isDisabled}
                    />
                    <label htmlFor="show">Show on profile</label>
                </div>
            </div>
            <p>Text</p>
            <p>{data.text}</p>
            <hr style={{ border: "solid 1px purple" }} />
        </div>
    );
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related