skip to Main Content

I’m working with a form where I have enclosed Input tags in divs styled as Cards. Currently, the user can select multiple options by clicking on the card. What I want to implement is that the user shall only be able to select a single card. If he selects some other card, the already selected card shall become unselected. How can I achieve this?

Clicking on the card adds the class module-inactive to the div which makes it look unselected by reducing its opacity.

Here is my HTML Code:

<div id="heat-one" class="module d-flex flex-column justify-content-center align-items-center">
    <input type="checkbox" class="module-check" id="card1">
    <p>Comb. Heat and Power</p>
</div>
<div class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
    <input type="checkbox" class="module-check" id="card2">
    <p>Heat Pump</p>
</div>
<div class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
    <input type="checkbox" class="module-check" id="card3">
    <p>Natural Gas Heating</p>
</div>
<div class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
    <input type="checkbox" class="module-check" id="card4">
    <p>Wood Heating System</p>
</div>

Following is the JavaScript that is currently implemented:

const checkBoxes = document.querySelectorAll(".module-check");
        checkBoxes.forEach((checkBox) =>
        checkBox.addEventListener("change", (e) => {
            if (checkBox.checked) {
            e.target.parentElement.classList.remove("module-inactive");
            } else {
            e.target.parentElement.classList.add("module-inactive");
            }
        })
        );

I hope I can explain my problem.

2

Answers


  1. Use radio boxes, as they are mutually exclusive.

    Change all your current checkboxes to:

    <input type="radio" class="module-check" id="card1" value="card1" name="whatever">
    

    You don’t need any JavaScript for this feature to work the way you expect.

    Login or Signup to reply.
  2. What you are describing is the functionality of a <input type="radio"> element (or more input elements with the same name). You can style the "cards" using the :checked pseudo class of the radio button.

    And you can use the <label> for "mapping" a click on the text to the radio button.

    The value attribute on each input element can be used for deciding wish item is selects.

    form {
      display: flex;
      flex-direction: column;
      gap: .5em;
    }
    
    input[type='radio'] {
      display: none;
    }
    
    input[type='radio']:checked + p {
      opacity: 1;
    }
    
    label p {
      border: thin solid black;
      margin: 0;
      opacity: .5;
    }
    <form>
      <label id="heat-one" class="module d-flex flex-column justify-content-center align-items-center">
        <input type="radio" name="group1" value="1" class="module-check" id="card1">
        <p>Comb. Heat and Power</p>
      </label>
      <label class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
        <input type="radio" name="group1" value="2" class="module-check" id="card2">
        <p>Heat Pump</p>
      </label>
      <label class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
        <input type="radio" name="group1" value="3" class="module-check" id="card3">
        <p>Natural Gas Heating</p>
      </label>
      <label class="add module module-inactive d-flex flex-column justify-content-center align-items-center">
        <input type="radio" name="group1" value="4" class="module-check" id="card4">
        <p>Wood Heating System</p>
      </label>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search