0

I'm trying to show a pop up (using Jquery UI's dialog() function) when user clicks on content inside a table cell. I'm populating the table using data returned from the Ajax call on a REST url. I get the correct data and the table is displayed correctly. The issue is that the click() function for the text inside the table cell doesn't get called.

The culprit seems to be the Ajax call since the the same approach works in case of static data inside the table.

Snippets from the html file:

            <head>
                $(document).ready(function(){
                            $("#dlg1").dialog({ autoOpen: false });
                            $('.linkClass1').click(function() {
                                $("#dlg1").dialog("open");
                            });
                            $.ajax({
                                url: "http://localhost:8080/abc/rest/def",
                                type: "GET",
                                contentType: 'application/json; charset=utf-8',
                                success: function(resultData) {
                                    var len = resultData.length;
                                    var table = $('<table></table>').addClass('tableClass1');
                                    var hRow = $('<tr></tr>');
                                    var hVar1 = $('<th></th>').addClass('headingClass1').text("col1");
                                    hRow.append(hVar1);
                                    table.append(hRow);
                                    for(i=0; i<len; i++)
                                    {
                                        row = $('<tr></tr>');
                                        var var1 = $('<td></td>').addClass('cellClass1');
                                        var linkVar1 = $('<a>')
                                                        .attr('class', 'linkClass1')
                                                        .attr('href', '#dummyId')
                                                        .text(resultData[i].id);
                                        var1.append(linkVar1);
                                        row.append(var1);
                                        table.append(row);
                                    }
                                    $(table).attr("id","tableId1");
// this table is appended to an html element and is correctly displayed
                                },
                             });
                        });
            </head>

        <body>

    <div id="dlg1" title="Basic dialog">
                    <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
                </div>
        </body>

On clicking the text inside table, nothing happens, just the original url is appended with #dummyId. I also tried using an alert() inside the click function and even that is not shown. Even setting async: false in the Ajax call doesn't help.

If anyone can help, thanks.

3 Answers 3

1

Long Answer

Instead of applying a jQuery click handler why don't you use the href or onclick tags to call the desired function as:

function openDialog(){
    $("#dlg1").dialog("open");
}

...
for(i=0; i<len; i++) {
    row = $('<tr></tr>');
    var var1 = $('<td></td>').addClass('cellClass1');
    var linkVar1 = $('<a>')
        .attr('class', 'linkClass1')
        .attr('href', '#dummyId')
        .attr("onclick", openDialog)
        .text(resultData[i].id);
    var1.append(linkVar1);
    row.append(var1);
    table.append(row);
}
....

You can also afford to remove the click handler you had applied.

Short Answer

Just move the click handler at the end of the success event handler. This will ensure that when the click handler gets applied, all the DOM elements are present on the page.

$(document).ready(function(){
    $("#dlg1").dialog({ autoOpen: false });
    
    $.ajax({
        url: "http://localhost:8080/abc/rest/def",
        type: "GET",
        contentType: 'application/json; charset=utf-8',
        success: function(resultData) {
            var len = resultData.length;
            var table = $('<table></table>').addClass('tableClass1');
            var hRow = $('<tr></tr>');
            var hVar1 = $('<th></th>').addClass('headingClass1').text("col1");
            hRow.append(hVar1);
            table.append(hRow);
            for(i=0; i<len; i++)
            {
                row = $('<tr></tr>');
                var var1 = $('<td></td>').addClass('cellClass1');
                var linkVar1 = $('<a>')
                                .attr('class', 'linkClass1')
                                .attr('href', '#dummyId')
                                .text(resultData[i].id);
                var1.append(linkVar1);
                row.append(var1);
                table.append(row);
            }
            $(table).attr("id","tableId1");
            $('.linkClass1').click(function() {
                $("#dlg1").dialog("open");
            });
        },
     });
});
Sign up to request clarification or add additional context in comments.

Comments

0

At the time of binding to $('.linkClass1').click .linkClass1 doesn't exist yet, either bind to this at the end of your ajax success or use

$('body').on('click', '.linkClass1', function

where it is now.

Comments

0

This code is only ever invoked once:

$('.linkClass1').click(function() {
    $("#dlg1").dialog("open");
});

Which means it's only going to find the .linkClass1 elements which exist at the time it's called and only going to bind click handlers to those elements. Remember that handlers are attached to elements, not to selectors.

So what's essentially happening is this code is never assigning a click handler to the elements that are being added after the AJAX call.

You can fix this by delegating the event handling to a common parent element which doesn't change during the life of the DOM. Any parent element will do, document is usually a workable default. Something like this:

$(document).on('click', '.linkClass1', function() {
    $("#dlg1").dialog("open");
});

This will assign the click handler to the document instead of the element, and assuming nothing stops the propagation of the event that click will "bubble up" from the clicked element to every parent element, all the way up to document. The second selector in that code is then a filter used to respond only to click events which originated from matching elements.

1 Comment

A fine blog entry that elucidated the concept very well. Good work @David.

Your Answer

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.