-1

I am fetching data from a php file using ajax. Looping through json object and creating buttons using ajax. I want to add an onclick event on that dynamically created button so that i can call a function, pass the current ID of the record to it, and then do some things to it like deleting or updating.

'<button type="button" onclick="test()" id="btnHistory" class="btn btn-success">History</button> '

but it leaves me an error saying the test function isn't defined.

enter image description here

here's my whole code:

$.ajax({
    type: "POST",   
    url: "../php_scripts/getUnits.php",
    success: function(data){
        var items = JSON.parse(data);

        /*var btnSomething = $("<button>")
        .attr('class', 'btn btn-danger')
        .attr('id', 'asdf')
        .html('Save');
*/


//$('#content').append(btnSomething);

        for (var i = 0; i < items.length; i++) {

            //test();
            $('#myTable').append('<tr><td>' + items[i].unitId + '</td><td>'+
             items[i].pcName +'</td><td>'+ items[i].user + '</td><td>'+ 
             items[i].department+'</td><td>'+items[i].location+ '</td><td>'+ 
             items[i].dateAssigned + '</td><td>' + items[i].status +'</td><td>' +
             '<button type="button" onclick="test()" id="btnHistory" class="btn btn-success">History</button> ' + 
             '<button id="btnUpdate" class="btn btn-primary">Update</button> ' +
             '<button id="btnDelete" class="btn btn-danger">Delete</button> ' + 
             '</td></tr>');
        }

        function test(){
            alert('test');
        }

        /*$(document).on("click", "#btnHistory", function(){
          alert ('History clicked ');
        });*/

    }
});
guradio
  • 15,524
  • 4
  • 36
  • 57
void null
  • 1
  • 1
  • 1
  • as the error says you dont have the test function – guradio Jul 05 '17 at 07:30
  • but it's defined there.. also before appending the data to my table, I called the test function. Works perfect but when I'm calling it to my button's onclick event it's undefined – void null Jul 05 '17 at 07:32
  • 1
    you have it inside document ready?move it out – guradio Jul 05 '17 at 07:33
  • @guradio it freaking worked!!! I can't thank you enough for noticing it.. but why did it work when it's outside the document ready? – void null Jul 05 '17 at 07:38
  • Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Govind Samrow Jul 05 '17 at 07:40
  • 1
    @voidnull because of a little thing called 'scope' :) – vi5ion Jul 05 '17 at 07:40
  • it is `scope` issue mate. check [this](https://scotch.io/tutorials/understanding-scope-in-javascript#toc-lexical-scope) you can find more in there – guradio Jul 05 '17 at 07:42
  • @GovindSamrow not a duplicate as this uses `onclick=` – freedomn-m Jul 05 '17 at 07:49
  • @voidnull `function test()` is defined within the *scope* of the `$.ajax success:` callback - ie it's what other languages call `private` to that function - it can't be seen *outside* that function. You're attempting to call it from the *global scope*, which is outside the ajax success callback, so your `onclick=` can't find the method. – freedomn-m Jul 05 '17 at 07:50
  • but when i redefined the test() function in document ready, outside the ajax success callback, why does the onclick still unable to see it? – void null Jul 05 '17 at 08:04
  • because it's then in the *scope* of document ready. Generally, if it's inside `{ }` then onclick won't be able to see it. If you use jquery event binding, then it wouldn't be an issue, but you're using `onclick=` which needs functions defined at the global level (or namespaced, but that's another issue). – freedomn-m Jul 05 '17 at 08:49

5 Answers5

1

Add this function to attach the test function for dynamically add button and remove test() function from the Ajax request

$(document).on("click", "#btnHistory", function(){
  alert ('test');
});

Remove onclick attribute from button

Osama
  • 2,912
  • 1
  • 12
  • 15
0

Simple add this function on your script

function test() {
    alert('working');
//    your code
}

It will work for you.

Bibhudatta Sahoo
  • 4,808
  • 2
  • 27
  • 51
0

Add the class attribute to the dynamically added button and add the onclick jquery function to the buttons. Use this code.

History

use the jquery function like this

$(document).on("click", ".btn-history", function(){ alert ('test'); });

or

$('#table-id').on("click", ".btn-history", function(){ alert ('test'); });

0

I have written jQuery to enable external function. and also you need to write call function in it, if the data is binding dynamically $(document).on("click", "#btnHistory", function(){ });

in your code you are looking for function and enabling click meted but data is blinded later and click method is not ready to trigger so if you use above jQuery will solve issue.

$(document).ready(function(){
  $('.test').on('click',function(){
    alert('test');
    alert($(this).attr('id'));
  });
  for (var i = 0; i < 5; i++) {      
    //test();
    $('#bindTable').append('<table class="table table-striped"><tr><td>Id</td><td>Pic Name</td><td>' +
             '<button type="button"  id="btnHistory" class="btn btn-success">History</button> ' + 
             ' <button id="btnUpdate" class="btn btn-primary">Update</button> ' +
             ' <button id="btnDelete" class="btn btn-danger">Delete</button> ' + 
             '</td></tr></table>');
  }
});
function test(){
  alert ('test');
}
$(document).on("click", "#btnHistory", function(){
  test();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div id="bindTable"></div>
Iqbal Pasha
  • 1,318
  • 1
  • 8
  • 12
0

Calling a function inline will only work from global scope, so defined it outside of the success callback. Or alternatively you could just attach the listener dynamically, like so:

$(.test).off('click').on('click', test)

And then your test() function could be defined in global scope. You can add the off('click') to make sure only one listener is on the buttons at all times. Perhaps a more performant option, however could be the following:

$(document).on('click', function (event) {
    if ($(event.target).is('.test')) {
        // call test() here
    }
})

This way, only a single listener needs to be attached and it does not have to be re-attached when new buttons are added.