Domanda

So I have a form that displays a table with 2 checkboxes per row. When the form is submitted, I am trying to ajax the rows which had at least one checkbox selected to the backend.

Markup:

<form id="my_form">
   <table>
     <tr data-id="1">
       <td><input type="checkbox" class="js-option-1"></td>
       <td><input type="checkbox" class="js-option-2"></td>
     </tr> 
     <!-- etc -->
   </table>
</form>

So I have an event handler that attempts to build an array of objects to send to the backend:

$("#my_form").live 'submit', (event) ->
  event.preventDefault()
  rows = []
  $("input:checked").each () ->
    rows.push row
  objects = []
  $.each objects, (index, value) ->
    object = {
      id: $(@).attr("data-id")
      option_1: $(@).find("js-option-1").val()
      option_2: $(@).find("js-option-2").val()
    }
    objects.push object
  # ajax code

The problem, of course, is that if both options are checked, I end up with two objects in the array and thus reduntant data being sent.

I tried to get around this on both arrays by trying to detect duplicates and ignore pushing in that case:

$("input:checked").each () ->
  row = $(@).closest("tr")
  if $.inArray(row, rows) == -1 #if no duplicate
    rows.push row

# or 

if $.inArray(object, objects) == -1
  objects.push object

Both of these approaches failed, however, since I assume the mechanism for comparing object literals and jquery objects results in them being considered not equal even though they are identical in all usual respects. Any other ideas?

È stato utile?

Soluzione

Use selector

$(':checked').closest('tr')

So that your selection logic doesn't include duplicates in the first place. Or if you prefer the logic the other way around, this is more obvious:

$('tr').has(':checked')

Altri suggerimenti

Don't iterate over collection of input:checked, but on tr:has(:checked), that way you'll only process each row that has at least one option checked once.

try: http://jsfiddle.net/NrHQ4/ (sorry, no Coffee)

$('#my_form').on('submit', function(e){
    var $this = $(this), rows = $this.find('tr:has(:checked)'), objects = [];
    rows.each( function(){
        var $row = $(this);
        objects.push({
            id :  $row.data('id'),
            option_1 : $row.find('.js-option-1').is(':checked'),
            option_2 : $row.find('.js-option-2').is(':checked')
        });
    });
    console.log( objects );
    e.preventDefault();
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top