0

I don't know if this is possible, but it's an interesting situation I came across in my project today.

A table of checkboxes. One type of checkboxes are hierarchical, which means that if one is checked, all checkboxes of the same type to the left of it are magically checked as well.

We need to send information only about the rightmost checked checkbox. Here's an example for using jQuery code to accomplish it: https://codepen.io/oriadam/pen/Yapodm

$("input").click(function() {
 $(".here").removeClass("here");
 $("tr").each(function(i, tr) {
  $(tr)
   .find(".a:has(input:checked):last input:checked")
   .each(function(i, elem) {
    $(elem).parent().addClass("here");
   });
 });
});
.here {
 background: red;
}
.a input {
 width: 2em;
 height: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td><input type="checkbox" checked></td>
 </tr>
</table>

<br><br> The challange: <br> Use a single jQuery(Sizzle) selector to get the rightmost checked checkbox of every tr, while considering only td that has class a.

Is there a way to use a single jQuery(Sizzle) selector to get the rightmost checked checkbox of every tr, while considering only td of class a.

Maistrenko Vitalii
  • 994
  • 1
  • 8
  • 16
oriadam
  • 7,747
  • 2
  • 50
  • 48

3 Answers3

2

You could use a filter:

$("input").click(function() {
  $(".here").removeClass("here");

  $('.a:has(input:checked)').filter(function() {             // get all .a that have inputs checked in them
    return !$(this).nextAll('.a:has(input:checked)').length; // only return .a that has no following siblings with an input checked in them
  }).addClass("here");
});
.here {
  background: red;
}

.a input {
  width: 2em;
  height: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table>
  <tr>
    <td><input type="checkbox"></td>
    <td class="a here"><input type="checkbox" checked></td>
    <td class="a"><input type="checkbox"></td>
    <td class="a"><input type="checkbox"></td>
    <td><input type="checkbox" checked></td>
  </tr>
  <tr>
    <td><input type="checkbox"></td>
    <td class="a"><input type="checkbox" checked></td>
    <td class="a here"><input type="checkbox" checked></td>
    <td class="a"><input type="checkbox"></td>
    <td><input type="checkbox" checked></td>
  </tr>
  <tr>
    <td><input type="checkbox"></td>
    <td class="a"><input type="checkbox" checked></td>
    <td class="a"><input type="checkbox" checked></td>
    <td class="a here"><input type="checkbox" checked></td>
    <td><input type="checkbox" checked></td>
  </tr>
</table>

<br><br> The challange: <br> Use a single jQuery(Sizzle) selector to get the rightmost checked checkbox of every tr, while considering only td that has class a.
Pete
  • 57,112
  • 28
  • 117
  • 166
1

You can certainly simplify that code:

$("tr").each(function(i, tr) {
    $(tr).find(".a:has(input:checked):last").addClass("here");
});

$("input").click(function() {
 $(".here").removeClass("here");
 $("tr").each(function(i, tr) {
  $(tr).find(".a:has(input:checked):last").addClass("here");
 });
});
.here {
 background: red;
}
.a input {
 width: 2em;
 height: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td><input type="checkbox" checked></td>
 </tr>
</table>

<br><br> The challange: <br> Use a single jQuery(Sizzle) selector to get the rightmost checked checkbox of every tr, while considering only td that has class a.

...but I'm not seeing a way you'd get rid of that last each loop (or something else in its place, like filter), since you want to work within the row.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

Try this, without-.each-loop variant:

$("input").click(function() {

 $(this).closest('tr').find('td.a').removeClass('here')
  .parent().children('.a:has(input:checked):last').addClass('here');
});
.here {
 background: red;
}
.a input {
 width: 2em;
 height: 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox"></td>
  <td><input type="checkbox" checked></td>
 </tr>
 <tr>
  <td><input type="checkbox"></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a"><input type="checkbox" checked></td>
  <td class="a here"><input type="checkbox" checked></td>
  <td><input type="checkbox" checked></td>
 </tr>
</table>
Scaramouche
  • 3,188
  • 2
  • 20
  • 46
  • The only reason that doesn't have `each` is it requires a click. The question clearly doesn't postulate a click. (Your answer gives a misleading impression it doesn't require a click because you've left the `here` class **in the markup** and not removed it as the question did.) – T.J. Crowder Mar 19 '18 at 15:47
  • @T.J.Crowder the OP's question's code shows the class `here` **in the markup** and includes all the javascript inside a click event, so I was just adhering to the scenario the OP stated. don't take *without-each-loop variant* so personal, it's just another way, does not mean better – Scaramouche Mar 19 '18 at 15:55
  • Right -- and the OP's code removes that as the first thing it does. I didn't say anything about taking anything personally. I'm just pointing out that this is not a viable answer to the question. – T.J. Crowder Mar 19 '18 at 15:57