How to correctly check the status of a Checkbox in js?

Asked

Viewed 102 times

0

I need a feature where Checkbox are nestling together.
In this way, the parent element would select all children and so on.

My logic was this:

As I will receive this data externally, I can manipulate the ids and the class that checkbox
So if I create a class father that has in all the attributes that will receive this functionality and concatenate a specific class to the children, I have a relationship between the two.

Example: the element whose class is father and the id is idPai, would have a relationship to all checkbox whose the class be it kiddPai

This is the HTML structure I used:

<div class="form-group row">
    <div class="col-sm-2">Checkbox</div>
    <div class="col-sm-10">
        <div class="form-check">
            <input class="form-check-input pai" type="checkbox" id="idPai">
            <label class="form-check-label" for="gridCheck1">
                Checkbox exemplo
            </label>
        </div>
        <ul style="display: inline-block; text-decoration: none; list-style: none;">
            <li>
                <div class="form-check">
                    <input class="form-check-input filhoidPai"  type="checkbox" id="idOption1">
                    <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo
                    </label>
                </div>
            </li>
            <li>
                <div class="form-check">
                    <input class="form-check-input filhoidPai" type="checkbox" id="idOption2">
                    <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo
                    </label>
                </div>
            </li>
        </ul>
    </div>
</div>

In this code we see that the idPai has the class father, so it controls the state of everyone who has your name (in this case, all kiddPai). That way, for this problem the script below meets my situation:

$(".pai").on("change", function (e) {
    var select = ".filho" + $(this).attr("id")


    var isChecked = $(this).prop('checked');

    $(select).each(function (e) {
        $(this).prop("checked", isChecked);
    })
});

However (that’s where the doubt comes in), when I try to add one more level in this hierarchy (that is, a father who is also a son), things get a little different...

<div class="form-group row">
    <div class="col-sm-2">Checkbox</div>
    <div class="col-sm-10">
        <div class="form-check">
            <input class="form-check-input pai" type="checkbox" id="idPai">
            <label class="form-check-label" for="gridCheck1">
                Checkbox exemplo
            </label>
        </div>
        <ul style="display: inline-block; text-decoration: none; list-style: none;">
            <li>
                <div class="form-check">
                    <input class="form-check-input filhoidPai"  type="checkbox" id="idOption1">
                    <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo
                    </label>
                </div>
            </li>
            <li>
                <div class="form-check">
                    <input class="form-check-input filhoidPai pai" type="checkbox" id="idOption2">
                    <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo
                    </label>
                </div>
                <ul style="display: inline-block; text-decoration: none; list-style: none;">
                    <li>
                        <div class="form-check">
                            <input class="form-check-input filhoidOption2" type="checkbox" id="idOption2SubOption">
                            <label class="form-check-label" for="gridCheck1">
                                Checkbox exemplo
                            </label>
                        </div>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</div>

In my view, the function change would change the status of all the checkbox in the hierarchy, thing that doesn’t happen.

When the idPai is triggered, automatically all kiddPai are also triggered (including what is son and father). In the same way as when the idOption2 is triggered, all the filhoidOption2 are also. The problem is that when idPai was selected, I wanted them to trigger both the children how much the children of children, making it a recursive function.
Any idea how to do that?

1 answer

2


There are some ways:

  • Add class idPai in grandchildren. Ex: class="form-check-input filhoidOption2 idPai"; or
  • Use a class with the name that has all levels.

    Ex: class="pai", class="filho-1", class="filho-2", class="filho-1-1" (grandchild)

  • Traverse all the input:checkbox with the function .find

I chose to make an example using this method. I used the function .parents() to return to the parent element .form-check and, soon after, I used the method next for him to catch the element ul brother.

How structure is always (div.form-check > input:check) + ul, will work properly. With this, we can use the method .find() to fetch the input:checkbox of that specific father.

Example:

$(".pai").on("change", function(e) {
  var filhos = $(this)
    .parents('.form-check') /** Seleciona o elemento pai `.form-check` */
    .next('ul') /** Busca o elemento `ul` irmão do pai */
    .find('input:checkbox') /** Seleciona todos os `input` do tipo `checkbox` */
  
  var isChecked = $(this).prop('checked');

  $(filhos).each(function(e) {
    $(this).prop("checked", isChecked);
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group row">
  <div class="col-sm-2">Checkbox</div>
  <div class="col-sm-10">
    <div class="form-check">
      <input class="form-check-input pai" type="checkbox" id="idPai">
      <label class="form-check-label" for="gridCheck1">
                Checkbox exemplo (Pai)
            </label>
    </div>
    <ul style="display: inline-block; text-decoration: none; list-style: none;">
      <li>
        <div class="form-check">
          <input class="form-check-input filhoidPai" type="checkbox" id="idOption1">
          <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo (Filho)
                    </label>
        </div>
      </li>
      <li>
        <div class="form-check">
          <input class="form-check-input filhoidPai pai" type="checkbox" id="idOption2">
          <label class="form-check-label" for="gridCheck1">
                        Checkbox exemplo (Pai e Filho)
                    </label>
        </div>
        <ul style="display: inline-block; text-decoration: none; list-style: none;">
          <li>
            <div class="form-check">
              <input class="form-check-input filhoidOption2" type="checkbox" id="idOption2SubOption">
              <label class="form-check-label" for="gridCheck1">
                                Checkbox exemplo (Neto e Filho)
                            </label>
            </div>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</div>

  • Does this procedure work if I create a new checkbox hierarchy? (i.e., the next parent will interfere with the other parent’s children?)

  • And I know that’s no longer pertinent to my question, but is there any way to clear the father by having all his children unmarked? And if so, is there any way to mark a child, find the father and mark him too?

  • 1

    @Walterfelipe It works with several levels of hierarchy, provided they have the same structure (I explained it in the third paragraph). It is also possible to mark the father by marking the child and vice versa, but this escapes the main question. I recommend creating another one with the new doubts. Otherwise the moderation of the site may revert your question to the original.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.