Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datatables I can't call an onclick event after I paginate?

I am using http://datatables.net/

The demo table on their homepage resembles pretty much the exact same thing that i'm using (pagination, specifically), except each row has an area to click:

<a href="#" class="show-post"><%= Post.title %></a>

This link opens a jquery UI modal dialog which displays some information which is ajax requested.

Part 1 (solved), see part 2 below

I'm trying to run an onclick event which works normally on page one, but as soon as i go to page 2 (or any others) it stops working. I checked the source to make sure it wasnt doing anything funny in all the code is infact there (all the rows, even the ones hidden by the pagination)

Any ideas?

$(function() {
    $('#dialog').dialog({
        autoOpen: false,
        resizable: false,
        maxHeight: 600,
        width: 650,
        modal: true,
        beforeClose: function close() {
            $('#dialog').html('');
        }
    });

    $('.show-post').click(function() {
        clickLink(this);
        return false;
    });
});

Thanks to those who answered my question! I fixed that issue.

Part 2

my next 'issue' id like to get to work is... I'm using the left and right arrow keys to allow them to 'scan' to the next or previous row, and display the information. This is as opposed to closing it and then having to click the next one.

I'd like to make it so when you get to the bottom of page one, or top of page two, hidding next/previous respectively will automatically load that page, go to the top (or bottom), then open that dialog for that row on the other page.

heres my click function (i know its kind of probably not structured the best... im new to jquery)

$(document).ready(function() {
    oTable = $('#posts').dataTable({
      "bJQueryUI": true,
      "iDisplayLength": 400,
        "bAutoWidth": false,
        "sPaginationType": "full_numbers",
        "aLengthMenu": [[-1, 400, 100, 50], ["All", 400, 100, 50]]
    });

    $(this).keydown(function(e) {
        var id = $("#dialog").attr("data-id");
        currentPost = $("#posts tr[data-id=" + id + "]");

        if (e.keyCode == 39 && $('#dialog').html() != "") {

            /* Remove current background */
            $(currentPost).blur()
            $(currentPost).removeClass("current");
            $(currentPost).find("td.sorting_1").removeClass("current");

            var next = currentPost.next().find(".show-post");
            clickLink(next);

        } else if (e.keyCode == 37 && $('#dialog').html() != "") {

            /* Remove current background */
            $(currentPost).removeClass("current");
            $(currentPost).find("td.sorting_1").removeClass("current");

            var prev = currentPost.prev().find(".show-post");
            clickLink(prev)
        }
    });
});

heres the actual click function

function clickLink(src) {
var post = $(src);
var id = $(post).parent().parent().attr('data-id');

/* Set background for current line */
$(post).parent().parent().find("td.sorting_1").addClass("current");
$(post).parent().parent().addClass("current");

$('#dialog').attr("data-id", id);

$('#dialog').load('/show-post/' + id, function() {

    $.ajax({
        type: "POST",
        url:  "/checkstatus/" + id,
        dataType: "html",
        error: function(data){
            $("#dialog").fadeOut("fast", function() {
            $("#dialog").html("<img src='/img/invalid.jpg' alt='invalid' style='margin: 40px auto; display: block;'>").fadeIn("slow");
           });
        }
    });

    /* Set Visited */
    $(post).parent().parent().removeClass("visited").addClass("visited");

    $('#dialog').dialog({
        title: post.html(),
        beforeClose: function close() {
            $(post).parent().parent().find("td.sorting_1").removeClass("current");
            $(post).parent().parent().removeClass("current");
        },
        buttons: {
            "Email 1": function() {
                $.ajax({
                    type: "POST",
                    url:  "/get-email/" + id + "/" + "1",
                    dataType: "html",
                    success: function(data) {
                        window.location.href = data + "&subject=" + post.html();
                    }
                });
            },

        }
    });
    $('#dialog').dialog('open');
});
return false;
};
like image 988
Tallboy Avatar asked Dec 28 '11 21:12

Tallboy


1 Answers

The example on the link you provided appears to be adding/removing DOM elements, meaning that elements on subsequent pages probably are not in the DOM on page load. Have you tried using event delegation?

$(<root element>).delegate('.show-post', 'click', function() {
    clickLink(this);
    return false;
});

Where <root element> can be document but should be set to an ancestor element that is always in the DOM.

.delegate():

Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.

Source: http://api.jquery.com/delegate

UPDATE

Note that .delegate() is an alias of .on() now, so if you're using jQuery 1.7+ I would just use .on() right from the get-go. Almost the same syntax except the selector and event are swapped: $(<root element>).on('click', '.show-post', function() { ... });

Source: Thanks Greg Pettit, Excellent Comment

like image 75
Jasper Avatar answered Oct 07 '22 18:10

Jasper