Search code examples
javascriptjqueryjquery-selectorsnextuntil

jQuery nextUntil with child


my html structure is like

<table>
  <tr>
    <td class="">
      <input type="checkbox" data-id="1" data-permission="a1" value="true" onchange="documentSetup.handleClick(this);" checked="">
    </td>
    <td class="">
      <input type="checkbox" data-id="1" data-permission="a2" value="true" onchange="documentSetup.handleClick(this);" checked="">
    </td>
    <td class="">
      <input type="checkbox" data-id="1" data-permission="a3" value="true" onchange="documentSetup.handleClick(this);" checked="">
    </td>
    <td class="">
      <input type="checkbox" data-id="1" data-permission="a4" value="true" onchange="documentSetup.handleClick(this);" checked="">
    </td>
    <td class="">
      <input type="checkbox" data-id="1" data-permission="a5" value="true" onchange="documentSetup.handleClick(this);" checked="">
    </td>
  </tr>
</table>

these check boxes depend on the exact previous checkbox to be enabled that is

a2 is enable if a1 is selected till a4 a5 is always enable.

I have handled this using

ruleMap(a1->a2,a2->a3,a3->a4) 

But if user deselects any previous check a2 I want all of the right side check-boxes to be deselected and disabled until data-permission is a5(excluding a5). Can I do this with nextUntil on child of td? I can not add class name to td. Please suggest a solution thanks a lot.


Solution

  • The issue you have is that the checkboxes are not siblings, so DOM traversal methods such as next() and prev() won't work.

    Instead you can place all the checkboxes in the row in to a single collection and work with them by index. When one is selected you know that all lesser indexes should be checked and all higher indexes should be unchecked. To do that you can use slice() like this:

    $(':checkbox').on('change', function(e) {
      // documentSetup.handleClick(this);
      
      var $checkboxes = $(this).closest('tr').find(':checkbox');
      var index = $checkboxes.index(this);
      $checkboxes.slice(0, index).prop('checked', true);
      $checkboxes.slice(index + 1).prop('checked', false);
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <tr>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a1" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a2" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a3" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a4" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a5" value="true">
        </td>
      </tr>
      <tr>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a1" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a2" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a3" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a4" value="true">
        </td>
        <td class="">
          <input type="checkbox" data-id="1" data-permission="a5" value="true">
        </td>
      </tr>
    </table>

    Also note that documentSetup.handleClick(this) is called from within the unobtrusive click handler, instead of the outdated onclick attribute, which should be avoided where possible.