0

I've got a table which is listing orders and I want to add the possiblity to filter results. Therefore I created a select field and an onchange effect in Jquery which is loading the same table with those filtered results into my Div. Therefore I used Ajax to update this "new Content" to my div. The problem is, that this table has several JQuery effects (for example a slide down when you click on a row) which doesn't work when the Content got created by the AjaxRequest. I have read some things already here in Stackoverflow and in other boards, but there was so many specific cases that I couldn't use any. I've heared something about a "init-function" which I need to call somewhere, so the JQuery things will also work on my Ajax generated content.

This is my Ajax Request:

$('.category').on('change', function (e) {
    var optionSelected = $("option:selected", this);
    var valueSelected = this.value;

    $.ajax({
        type: "POST",
        url: "includes/listorders.php",
        data: "filter=" + valueSelected,
        success: function( data ) {
            $( "#latestOrders" ).html(data);
        }
    });
});

This is what my listorders.php basically returns (probably not necessary to know to fix my issue):

$filter = $_POST['filter'];

//Prepare Queries
$lastOrders = "SELECT * FROM Orders ORDER BY dateAdded DESC LIMIT 0,48";
$ps_orders = $db->query($lastOrders);
$data = $ps_orders->fetchAll();

foreach($data as $row)
{
    $orderid =$row['id'];
    $username = $row['name'];
    $done = $row['refsDone'];
    $quantity = $row['quantity'];
    $running =$row['refsRunning'];
    $untouched = $quantity - ($done+$running);
    ?>
    <tr class="header mySlideToggler" data-id="<? echo $orderid ?>">
        <td class="align-center">TEST<? echo $username ?></td>
        <td>0 %</td>
        <td>22 Aug 2014</td>
        <td><? echo $done . " / " . $quantity ?></td>
        <td><? echo $running ?></td>
        <td><? echo $untouched ?></td>
        <td>
            <a href="#" class="table-icon edit" title="Edit"></a>
            <a href="#" class="table-icon expand mySlideToggler" data-id=$orderid title="Expand"></a>
            <a href="#" class="table-icon delete" title="Delete"></a>
        </td>
    </tr><tr style="padding: 0"><td colspan="7" style="padding: 0">
        <div class="accounts" style="display: none">
        </div>
    </td></tr>
    <?
}
?>

My Slide effect including another Ajax request for the content which should be displayed into the slided div:

// Slide effect for listing account information to an order
$('.mySlideToggler').click(function( event ){
    event.preventDefault();
    event.stopPropagation();

    var id = $(this).data('id');
    var div = $(this).closest('tr').next().find('.accounts');

    $.ajax({
        type: "POST",
        url: "includes/listaccounts.php",
        data: "orderid=" + id,
        success: function( data ) {
            div.html(data);
        }
    });
    $(this).closest('tr').next().find('.accounts').slideToggle();
});
kentor
  • 16,553
  • 20
  • 86
  • 144
  • <- This is what it looks like, or do you meant a picture of it ? It works perfetly when it isn't loaded/generated by the Ajax Request – kentor Aug 16 '14 at 17:50
  • Please check my answer. If the js works on static content and not on async content, the problem is with your js. – Eric Uldall Aug 16 '14 at 17:52

1 Answers1

2

You need to make sure to use the new live version of event listeners, to work with content loaded asynchronously

$('body').on('click', '.my-class', function(){
    //handle click event for .my-class here
});

The above code is not specific to your situation, since you have not posted the js code that is not working on async content. It's just a sample of how you manage live event listeners.

Specific answer after reviewing your code update:

$('body').on('click', '.mySlideToggler', function(event){
    //do toggle stuff here
});

Why?

The jQuery .click does not support events happening on content loaded asynchronously. The same problem applies to using the following code:

$('.mySlideToggler').on('click', function(event){
    //THIS WONT WORK WITH ASYNC CONTENT
});

This is why jQuery has allowed us to register the event on a parent element that was not loaded asynchronously and the provide a second argument to .on that tells us which child of that element to listen for as a target or said event. This works with all events, click|change|focus|blur|etc...

Why $('body')

I generally attach these live handlers to the body of the html document because the body is rarely reloaded via async content, as reloading the entire content would probably warrant a new page load, however it's not necessary to use body. You can attach to any parent element that is static on the page, including document or window

Nice to know

jQuery formerly used the method .live() which has been deprecated for a while now, I think since 1.7

I suggest you read more about the change to .live here: http://api.jquery.com/live/

I hope this has sufficiently answered your question. Let me know if you're still having trouble.

Performance Concern

Attaching the parent object of the .on event as close to the child element as possible will increase performance if you are using a large number of these events, as jQuery doesn't have to traverse as far down the DOM Tree to find the child element.

More info here: http://api.jquery.com/on/#event-performance

Eric Uldall
  • 2,282
  • 1
  • 17
  • 30
  • I think the click/fire event isn't the problem, since it is really loading the new content into it (I've tested that). Or does it really affect my JQuery part of the table like the Slidedown effect ? – kentor Aug 16 '14 at 17:53
  • Please post the slidedown code. You can edit your original question and add it in there. – Eric Uldall Aug 16 '14 at 17:54
  • I have edited it in the thread. Thanks for the help! I appreciate this! – kentor Aug 16 '14 at 18:52
  • Yes, you're not using a live event. Try replacing the outer function with my example above. – Eric Uldall Aug 16 '14 at 22:26
  • Works fine, the slideup effect for table rows is a bit laggy when the table is generated by the ajax request. Maybe you have also a solution for this small problem? Thanks for the help anyways! – kentor Aug 17 '14 at 12:38
  • Try moving this line: $(this).closest('tr').next().find('.accounts').slideToggle(); into the ajax Success: function(){} If you're still having trouble open a new ticket. – Eric Uldall Aug 18 '14 at 21:10