Sam
Sam

Reputation: 1381

when checkbox is checked not able to fetch data that are against that checkbox

I have data that is displayed in the form of a table and each row has a checkbox. I am trying to fetch the data of each row when the checkbox is clicked against that row.

<tr>
    <td><input type="text" name="child_name"></td>
    <td><input type="text" name="child_age"></td>
    <td><input type="checkbox" ></td>
</tr>
<tr>
    <td><input type="text" name="child_name"></td>
    <td><input type="text" name="child_age"></td>
    <td><input type="checkbox" ></td>
</tr>

These will get generated dynamically, so the naming needs to same for the input box, however when i am fetching the value typed by the user,it fetches the value of only first row, and the values is getting repeated multiple times

$(document).ready(function(){
    $('input[type="checkbox"]').click(function(){
        if($(this).prop("checked") == true){
            $tr = $(this).closest('tr');
            var arr = [];
            var data = $tr.children("td").map(function(){
                
                var one = $("[name='child_name']").val();
                var two = $("[name='child_age']").val();
                
                arr.push(one)
                arr.push(two)
                return arr;

                
                
            }).get();

            console.log(data);
            $('#post-result').append(data);
        }
        else if($(this).prop("checked") == false){
            console.log("Checkbox is unchecked.");
        }
    });
});

Can anyone please tell how to resolve the issue

Upvotes: 0

Views: 200

Answers (2)

Mihail Minkov
Mihail Minkov

Reputation: 2633

The name attribute in this case could complicate things a little bit. What I would do is use data-attributes to have specific identifiers for each row. Something like this:

UPDATED

I changed the behavior to work with dynamically added rows.

Using $(document).on("click"... you can affect future elements of the same type while $("[type='checkbox']").click() works only for currently existing elements.

I also took some liberty in expanding the example.

var children = [];

$(document).on("click", ".child-selector", function() {
  var id = $(this).data("id");
  
  if($(this).is(":checked")) {
      
      var info = [];
      info.push($(".child-name[data-id='"+ id +"']").val());
      info.push($(".child-age[data-id='"+ id +"']").val());
      
      console.log(info);
      
      // An example of using objects to give some structure to the data
      // and then store it to an array with all the checked rows
      var child = {};
      child.id = id;
      child.name = $(".child-name[data-id='"+ id +"']").val();
      child.age = $(".child-age[data-id='"+ id +"']").val();
      
      children.push(child);
      
      console.log(children);
   } else {
      console.log("Checkbox is unchecked.");
      
      // An example of removing the specific children from the array
      children.forEach(function(child, index) {
        if(child.id == id) {
          children.splice(index, 1);
        }
      });
      console.log(children);
   }
});

var clickCounter = 0;
var dataCounter = 13;

$("#add-child").click(function() {
   var html = '<tr>'+
              '<td><input type="text" class="child-name" data-id="'+ dataCounter +'" value="Child '+ clickCounter +'"></td>'+
              '<td><input type="text" class="child-age" data-id="'+ dataCounter +'" value="'+ clickCounter +'"></td>'+
              '<td><input class="child-selector" type="checkbox" data-id="'+ dataCounter +'"></td>'+
              '</tr>';
   $("table").append(html);
   clickCounter++;
   dataCounter++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
      <td><input type="text" class="child-name" data-id="9" value="John Connor"></td>
      <td><input type="text" class="child-age" data-id="9" value="12"></td>
      <td><input class="child-selector" type="checkbox" data-id="9"></td>
  </tr>
  <tr>
      <td><input type="text" class="child-name" data-id="10" value="Jane Connor"></td>
      <td><input type="text" class="child-age" data-id="10" value="12"></td>
      <td><input class="child-selector" type="checkbox" data-id="10"></td>
  </tr>
  <tr>
      <td><input type="text" class="child-name" data-id="11" value="Tom Connor"></td>
      <td><input type="text" class="child-age" data-id="11" value="13"></td>
      <td><input class="child-selector" type="checkbox" data-id="11"></td>
  </tr>
  <tr>
      <td><input type="text" class="child-name" data-id="12" value="T800"></td>
      <td><input type="text" class="child-age" data-id="12" value="1"></td>
      <td><input class="child-selector" type="checkbox" data-id="12"></td>
  </tr>
</table>

<button type="button" id="add-child">Add Child</button>

Now, if you need to send the data via post you should review your usage of name because as it currently is it would only send one value.

Upvotes: 1

blex
blex

Reputation: 25634

You can use the context parameter of $(selector [, context]) to only search inside the current <tr>:

$(document).ready(function() {
  $('input[type="checkbox"]').click(function() {
    if ($(this).prop("checked") == true) {
      $tr = $(this).closest('tr');
      var arr = [];

      var one = $("[name='child_name']", $tr).val();
      var two = $("[name='child_age']", $tr).val();

      arr.push(one)
      arr.push(two);

      console.log(arr);
      $('#post-result').append(arr);
    } else if ($(this).prop("checked") == false) {
      console.log("Checkbox is unchecked.");
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td><input type="text" name="child_name" value="A Name"></td>
    <td><input type="text" name="child_age" value="A Age"></td>
    <td><input type="checkbox"></td>
  </tr>
  <tr>
    <td><input type="text" name="child_name" value="B Name"></td>
    <td><input type="text" name="child_age" value="B Age"></td>
    <td><input type="checkbox"></td>
  </tr>
</table>
<pre id="post-result"></pre>

Upvotes: 1

Related Questions