Do a post call depend on datatable values

I have my dataTable script below working and bringing data very well, but i want to perform some tasks. like when i click the button the post call for ajax get executed

my problem is that when i click the Button

$('td:eq(1)', row).html('<button type="button" id="showup"> Submit </button>');

nothing happens its like not normal, not picking any event. its not working to do the post call for ajax

my datatable output is like this

<tr>
<td><input type="text" name="Country" value='Italy' /></td>
<td><button type="button" class="showup"> Submit </button></td>
</tr>

<tr>
<td><input type="text" name="Country" value='Spain' /></td>
<td><button type="button" class="showup"> Submit </button></td>
</tr>

Now i want when i press the button to do a post call to send the value of the actual input name=“Country” in tr

$(document).ready(function() {
    $('.showup').on('click', function() {
        execute($(event.target).prev("input"));
        $(this).html("Clicked");
        $(this).attr("disabled", true);

        function execute($input) {
            $.ajax({
                type: "POST",
                url: "file2.php",
                data: {
                    Country: $input.val(),
                },
                success: function(response) {},
                error: function() {
                    alert("Error");
                },
            });
        }
    });
    var table = $("#information").dataTable({

        "pagingType": "simple",
        "stripeClasses": [],
        "bLengthChange": false,
        sDom: "ltipr",
        oLanguage: {
            sEmptyTable: '',
            sProcessing: '',
            oPaginate: {
                sNext: 'Next',
                sPrevious: 'Previous',
            },
        },
        responsive: {
            details: {
                display: $.fn.dataTable.Responsive.display.modal({}),
                renderer: $.fn.dataTable.Responsive.renderer.tableAll({
                    tableClass: "table",
                }),
            },
        },
        "processing": true,
        "ajax": {
            "url": "file.php",
            "type": "GET",
            "dataType": "json"
        },
        rowCallback: function(row, data) {
            $('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');
            $('td:eq(1)', row).html('<button type="button" id="showup"> Submit </button>');

        },
    });
});

You are not passing your event to your function…

$('.showup').on('click', function(event) {

still nothing happens after passing event to the function

You have specified a Class selector, and given the button an ID instead of a class.

(Also you will almost certainly need to delegate this event, as the buttons wont exist when document.ready)

later i changed to $('td:eq(1)', row).html('<button type="button" class="showup"> Submit </button>');

but still nothing was happening, the button not active on click

(Also you will almost certainly need to delegate this event, as the buttons wont exist when document.ready)

To expand on m_hutley’s comment, you may want to have a read through this.

Then for jquery
https://learn.jquery.com/events/event-delegation/

The obvious candidate to attach this listener to is the #information element, and I’m guessing that the code would be as follows.

$('#information').on('click', '.showup', function(event) {
...
})

I don’t think this line is going to work

execute($(event.target).prev("input"));

The event target, which is the .showup button, has no siblings. No previous sibling and no next sibling.

If you add some indentation to your html this becomes more obvious.

<tr>
    <td>
        <input type="text" name="Country" value='Spain' />
    </td>
    <td>
        <!-- no previous sibling -->
        <button type="button" class="showup"> Submit </button>
        <!-- no next sibling either -->
    </td>
</tr>

What you are actually needing to select is the parent of the button (the table cell), then it’s previous sibling ( the previous table cell), then it’s child element (the input element). Whilst doable this is a bit convoluted.

Would it be possible to put the input and button inside the same table cell? e.g.

<tr>
    <td>
        <input type="text" name="Country" value='Spain' />
        <button type="button" class="showup"> Submit </button>
    </td>
</tr>

With this arrangement, your code should work.

One last one, and this is maybe somewhat opiniated.

With your current code each time .showup is clicked you are defining an inner function called execute, which is unnecessary.

Furthermore the name execute doesn’t tell us much about what that function is — all functions are executable.

If you come back to this code in a few months time, you are going to have to read through your code to figure out what it does. You could make your life easier with a more descriptive name.

So I would arrange that code as follows.

// defined outside of the handler just the one time
function updateCountry (country) {
  $.ajax({
    type: 'POST',
    url: 'file2.php',
    data: {
      Country: country
    },
    success: function (response) {},
    error: function () {
      alert('Error');
    }
  });
}

$('.showup').on('click', function () {
  $(this).html('Clicked');
  $(this).attr('disabled', true);
  // passing in the value instead of the input
  updateCountry($(event.target).prev('input').val());
});

your not really getting my question. the data is not referenced in html. am trying to access the data which is return from ajax get method and ouput to datatable, thats why when i click the button nothing happens.

What am looking for is to access button and peform some task in browser DOM
because the data am trying to access is within browser DOM

i want to access the button returned in browser dom
$('td:eq(1)', row).html('<button type="button" id="showup"> Submit </button>');
and perform tasks…

$(document).ready(function() {
    $('.showup').on('click', function() {
        execute($(event.target).prev("input"));
        $(this).html("Clicked");
        $(this).attr("disabled", true);

        function execute($input) {
            $.ajax({
                type: "POST",
                url: "file2.php",
                data: {
                    Country: $input.val(),
                },
                success: function(response) {},
                error: function() {
                    alert("Error");
                },
            });
        }
    });
    var table = $("#information").dataTable({

        "pagingType": "simple",
        "stripeClasses": [],
        "bLengthChange": false,
        sDom: "ltipr",
        oLanguage: {
            sEmptyTable: '',
            sProcessing: '',
            oPaginate: {
                sNext: 'Next',
                sPrevious: 'Previous',
            },
        },
        responsive: {
            details: {
                display: $.fn.dataTable.Responsive.display.modal({}),
                renderer: $.fn.dataTable.Responsive.renderer.tableAll({
                    tableClass: "table",
                }),
            },
        },
        "processing": true,
        "ajax": {
            "url": "file.php",
            "type": "GET",
            "dataType": "json"
        },
        rowCallback: function(row, data) {
            $('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');
            $('td:eq(1)', row).html('<button type="button" id="showup"> Submit </button>');

        },
    });
});

this is what i wanted, tho am still checking if will sort my problem, with below i can click the button and perform the tasks

"render": function (data, type, full) {
                    return '<button type="button" class="btnClick" data-status="replace">Send</button>'.replace("replace", data);
                }
            }
        ]
} );

$(document).on('click','.btnClick', function() {
   var statusVal = $(this).data("status");
   console.log(statusVal);
   //do the AJAX call...
});
1 Like

Did you look at the links I posted?

The datatable is added to the #information element right?

var table = $("#information").dataTable({
     ...
        rowCallback: function(row, data) {
            $('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');
            $('td:eq(1)', row).html('<button type="button" id="showup"> Submit </button>');

        },
    });

I might have got this wrong, but m_hutleys point was that this data is added after the document is loaded/ready. Therefore you are adding event listeners to elements that don’t exist yet. Again I could be wrong.

That said, adding an eventlistener to the information element should be reliable as it is already in the dom and events from the child elements will bubble up to it.

Edit: I just want to add, we don’t have access to your php files/data so can only really go on theory rather than giving a fully tested answer.

this is the full working code example. its what i need

Reference - working example on jsfiddle

that following example each button u click. will return the value of that column or td

 <table id="mytable" class="display" style="width:100%">
  <thead>
      <tr>
          <th>ITEM</th>
          <th>STATUS</th>
          <th>PRICE</th>
          <th>Status</th>
      </tr>
  </thead>
</table>
var dataSet = [
[  "item1", "closed", "2.55", "closed" ],
[  "item2", "open", "3.55", "open" ],
[  "item3", "pending", "4.55", "pending" ],
[  "item4", "closed", "5.55", "closed" ],
[  "item5", "closed", "6.55", "closed" ]
    ];

$('#mytable').DataTable( {
    data: dataSet,

    "columns": [
      {"title": "item"},
      {"title": "status"},
      {"title": "price"},
      {"title": "status"}
  ],
  "columnDefs": [
            {
                "targets": [3],
                "searchable": false,
                "orderable": false,
                "render": function (data, type, full) {
                    return '<button type="button" class="btnClick" data-status="replace">Send</button>'.replace("replace", data);
                }
            }
        ]
} );

$(document).on('click','.btnClick', function() {
   var statusVal = $(this).data("status");
   console.log(statusVal);
   //do the AJAX call...
});

Just to point out. This appears to work too and is isolated to the table, rather than the whole document.

$('#mytable').on('click','.btnClick', function() {
   var statusVal = $(this).data("status");
   console.log(statusVal);
   //do the AJAX call...
});

Atleast as pointed out, delegation is a step in the right direction.

It’s tough to help debug things without a live web page to analyze (at least for me).

One more food for thought… give up on jQuery and try to use vanilla JS as much as possible. You will be better for it in the long run.

1 Like

the difference is that me i dont want to include this

"render": function (data, type, full) {
                    return '<button type="button" class="btnClick" data-status="replace">Send</button>'.replace("replace", data);

i want to access the buttons which is returned from our data request

$('td:eq(1)', row).html('<button type="button" class="showup"> Submit </button>');

and then get each value of in td where is

$('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');

and final should be

$(document).ready(function() {
$('#showup').on('click', function() {
        execute($(event.target).prev("input"));
        $(this).html("Clicked");
        $(this).attr("disabled", true);
		
         var CountryVal = $(this).data[0];
		 
        function execute() {
            $.ajax({
                type: "POST",
                url: "file2.php",
                data: {
                    Country: CountryVal(),
                },
                success: function(response) {},
                error: function() {
                    alert("Error");
                },
            });
        }
    });

var table = $("#information").dataTable({

        "pagingType": "simple",
        "stripeClasses": [],
        sDom: "ltipr",
        oLanguage: {
            sEmptyTable: '',
            sProcessing: '',
            oPaginate: {
                sNext: 'Next',
                sPrevious: 'Previous',
            },
        },
        responsive: {
            details: {
                display: $.fn.dataTable.Responsive.display.modal({}),
                renderer: $.fn.dataTable.Responsive.renderer.tableAll({
                    tableClass: "table",
                }),
            },
        },
        "processing": true,
        "ajax": {
            "url": "file.php",
            "type": "GET",
            "dataType": "json"
        },
        rowCallback: function(row, data) {
            $('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');
            $('td:eq(1)', row).html('<button type="button" class="showup"> submit </button>');

        },
    });
});

I have to say, this had crossed my mind too.

Event delegation should still apply, regardless of how or when these elements are added to the DOM/page.

like how?

Maybe I have the wrong end of the stick.

Is this part of your code adding inputs and buttons to the page?

rowCallback: function(row, data) {
  $('td:eq(0)', row).html('<input type="text" name="Country" value=' + data[0] + ' />');
  $('td:eq(1)', row).html('<button type="button" class="showup"> submit </button>');
}

If so, are those the buttons which you are expecting to do something when you click on them?

If this is the case then you should be able to add an event listener to the #information element and when they are added, any click will bubble up to that #information element.

As I say maybe it is me misunderstanding the issue here.