user5467433
user5467433

Reputation: 21

Increment/decrement count of checked checkboxes

I want the toggles to be counted and they are not. When I press one of them the counter is increased to 1 and stuck. When I decrease the counter it's -1.

The expected result is when a toggle is on the counter is increased (counter++) and when it is off the counter should be decreased (counter--).

The toggles are created in Bootstrap.

(function() {
  $(() => {
    let counter = 0
    for (let index = 1; index < 10; index++) {
      let div = $("<div>").addClass("custom-control custom-switch");
      let myLabel = createLabel("toggle" + index);
      let myCheckbox = createCheckbox("toggle" + index, counter);

      $(div).append(myCheckbox, myLabel);
      $("#container").append(div);
    }
  });
})();

function createLabel(id) {
  return $(`<label for=${id} class=custom-control-label>${id}&nbsp;</label>`);
}

function createCheckbox(id, counter) {
  return $(`<input type=checkbox class=custom-control-input id=${id}>`).click(() => {
    onCheckBoxSwitchToggled(id, counter);
  });
}

function onCheckBoxSwitchToggled(id, counter) {
  $(`input[id=${id}`).on("change", function() {
    if (counter < 6) {
      if ($(this).prop("checked") === true) {
        counter++
        $("#text").text(counter)
      } else {
        counter--
        $("#text").text(counter)
      }
    } else {
      alert("over than 5")
    }
  });
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<div id="container"></div>
<p id="text"></p>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">Open modal</button>
<div class="container" data-toggle="modal" data-target="#myModal">
  <div class="modal fade" id="myModal">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title">The chosen coins</h4>
        </div>
        <div class="modal-body">
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Views: 835

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337590

There's quite a few issues in your code.

  • You're using an IIFE instead of a document.ready handler
  • You're placing a function inside a jQuery object. Don't do that. You don't need it in this case anyway, just put the logic within the document.ready handler to be executed when the DOM loads.
  • You're selecting an id using an attribute selector instead of an actual id selector. That attribute selector is also missing the closing ]
  • div already holds a jQuery object, you don't need to put it in another one.
  • The checkbox inputs you create are missing the name and value attributes.
  • Use the change event on checkbox and radio inputs, not click. This is for accessibility reasons.
  • Use a single delegated event handler on dynamic content instead of attaching a new event handler clone every time the element is created
  • Remove the nested event handler in onCheckBoxSwitchToggled. You don't need it as that event already runs when the checkbox is interacted with anyway.

However the main issue with your logic is that you're relying on the counter argument which is defined globally. Instead just use the length property along with the :checked selector to get the number of checked boxes.

Below is a working example. Note that the createLabel() and createCheckbox() methods are now almost entirely redundant and can be removed. Try this:

jQuery($ => {
  for (let index = 1; index < 10; index++) {
    let $div = $("<div>").addClass("custom-control custom-switch");
    let $label = createLabel("toggle" + index);
    let $checkbox = createCheckbox("toggle" + index);
    $div.append($checkbox, $label);
    $("#container").append($div);
  }
  
  $('#container').on('change', ':checkbox', function() {
    let counter = $(':checkbox:checked').length;
    $('#text').text(counter);
  
    if (counter > 5)
      console.log("over  5")
    });
});

function createLabel(id) {
  return $(`<label for="${id}" class="custom-control-label">${id}&nbsp;</label>`);
}

function createCheckbox(id) {
  return $(`<input type="checkbox" class="custom-control-input" id="${id}" name="foo" value="${id}">`)
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<div id="container"></div>
<p id="text"></p>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">Open modal</button>
<div class="container" data-toggle="modal" data-target="#myModal">
  <div class="modal fade" id="myModal">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <h4 class="modal-title">The chosen coins</h4>
        </div>
        <div class="modal-body">
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

Related Questions