0

I see a lot of similar questions but not one that directly targets my problem. The business logic of my problem is that I allow the user to open a jQuery Dialog where I create table loaded with a data from a database and when the user make a choise I load the selected data info fields from the main screen.

My current problem is with collecting the data from the <tr> which happens on button click. If it was a hard coded table I would just:

$(selector).on('click', function(){
 var $item = $(this).closest("tr").find('td');
})

and then do something with $item however the table is created dynamically (from Ajax request) everytime the Ajax request is made the table is destroyed and recreated so basically I can't or at least I don't know a way to use some sort of selector to which to bind the event so I can reproduce the above code.

Instead in the dynamic table I have this:

 <td><button onclick="getData();return false">Select</button>

The problems with this (at least how I see it) are two - first, the using of onclick inside HTML element. From what I know it's not a good practice and there are better alternatives and I would appreciate answer showing this. Also, even though I go with this code I'm yet unable to extract the text from each <td> in:

function getData() {
...
}

I tried several approaches including the one which was working with the static table and the binded event handler.

At the end here is a JS Fiddle example where I think I made it clear what I can and what I can not do, so you can refer to it.

asked Nov 13, 2014 at 10:58
5
  • 1
    If you select the parent element where the table is created and bind an event to it like this $('#temp-table').on('click', 'table button', function(){, I think that the event it triggered, but I'm not sure. Check this fiddle. Commented Nov 13, 2014 at 11:06
  • @DontVoteMeDown Seems legit to me. If you want see Cerlin Bosses answer. Pretty close to yours. I can't decide if one is better than the other or are the same.. Commented Nov 13, 2014 at 11:25
  • He's answer is pretty close to mine, the difference is that I prefer to attach the delegation to the parent element, instead of the document itself. I think that there is no use to bind the event in the entire document, but its a minimal performance concern. Commented Nov 13, 2014 at 12:16
  • @DontVoteMeDown in fact I tried to attach the delegation to the divI'm using to create the jQuery dialog where everything else is appended afterwards but for some reason it didn't work while if I use document it's ok... any idea why? Commented Nov 13, 2014 at 12:19
  • Nope. Not sure why, but it worked on the fiddle I posted. Anyway, if it works to you, its ok. As I said, its just a minimal concern. I don't think binding event to document would decrease your app performace at all. Commented Nov 13, 2014 at 12:46

3 Answers 3

5

Check this fiddle

$(selector).on('click', function(){
 var $item = $(this).closest("tr").find('td');
})

Using the above code you are binding a direct event but the one which you want is delegated event

To use delegated event you should use like

$(document).on('click',selector, function(){
 var $item = $(this).closest("tr").find('td');
})

so your final code will look something like

$(document).on('click','.get-data' ,function(){
 var $item = $(this).closest("tr").find('td');
 $.each($item, function(key, value){
 alert($(value).text());
 })
});

document can be anything which is parent to the table which is going to be created.

Dont forget to add the selector while adding a new table element

answered Nov 13, 2014 at 11:12
Sign up to request clarification or add additional context in comments.

3 Comments

delegated event it is. The code is working now as desired. Thanks.Do you think this is the legit approach when it comes to attaching events to dynamic data. I know that before you could use live() for that, but from what I know now it's deprecated so is this now the jQuery way to do this?
yes. Users of older versions of jQuery should use .delegate() in preference to .live()
@Cerlin how to get values for all rows at once?
2

I had the same problem and solved it that way. You can create your table with the database results like this:

for (var i = 0; i < results.length; i++) {
 // create table row and append it to the table using JQuery
 // next create a td element, append it to the created tr
 // and attach a listener to it
 $('<td/>').html(results[i].textProperty)
 .appendTo($(tr))
 .on('click', getData);
}

where getData() is your function.

You can pass arguments to your getData like this:

.on('click', {info: results[i].data}, getData);

Then you can access them in your function:

function getData(event) {
 console.log(event.data.info);
}

Hope this helps!

Edit: This way you are creating a listener for each td. An optimization could be to create a listener for the whole class of td elements and to pass data to it via HTML attributes or text value like in the approved answer.

answered Nov 13, 2014 at 11:29

3 Comments

Nice to see fellow bulgarian :) here - .on('click', {info: re.. to what are you attaching the event?
Hey :). The event is attached to the newly created td, like in the first code snippet.
To be honest this comes a little over complicated for me, but +1 for the alternative approach. Although using delegated event seems much more intuitive so I think I'm gonna stick to it.
0

or you can use this pass object in getdata method

$('#build-table').on('click', function(){
 $('#temp-table').append('<table><thead><tr><th>Select</th><th>Name</th> </tr></thead>' +
 '<tbody><tr><td><button class onclick="getData(this);return false">Select</button></td><td>Name1</td></tr>' + 
 '<tbody><tr><td><button onclick="getData(this);return false">Select</button></td><td>Name2</td></tr>' +
 '</tbody></table>')
 });
 function getData(ob) {
 var $item = $(ob).closest("tr").find('td');
 $.each($item, function(key, value){
 alert($(value).text());
 })
 }
answered Nov 13, 2014 at 11:14

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.