0

I am trying to load a dropdown menu from a server and then use jQuery to interact with that dropdown. Everything loads fine, but I can't interact with the menu items as they weren't part of the original HTML that was loaded, they were entered after AJAX got its response.

Here's the ajax code:

$(document).ready(function(){
    //load dropdown menu using ajax

    $.ajax({ url: "default/CallSupplierMongo",
        context: document.body,
        success: function (res) {
            document.getElementById("dropdownItems").innerHTML = res;
        }
    });

});

The jQuery:

$(document).load(function() {
  $('.dropdownItems > div').click(function () {
        supplierCode = $(this).html();

        $('.dropdownItems > div').css({
            'background-color': 'white',
            'color': '#888888'
        });

        $(this).css({
            'background-color': '#888888',
            'color': 'white'
        });

        $('.dropdownItems').slideUp('fast');

        $('.dropdownButton').html(supplierCode);
        $('.dropdownButton').css({
            'border-bottom-right-radius': '5px',
            'border-bottom-left-radius': '5px'
        })
    });

});

And the PHP:

function actionCallSupplierMongo() {
        self::getSuppliers();
}

private static function echoSupplierCodes($supplierCodes) {

    for ($i=0;$i<count($supplierCodes);++$i) {
        echo '<div>'.$supplierCodes[$i].'</div>';
    }

}

To explain the issue further: I want to click on the dropdown items and grab the HTML inside it. When I click, nothing is registered. I believe that's because jQuery checks to see if those <div>s exist before they are loaded and thus doesn't apply the .click function to them.

EDIT I've tried putting the AJAX call in $(document).load() but it still has no effect.

  • you need to **delegate** event handlers. Source: http://api.jquery.com/delegate/ – CodeGodie Oct 01 '15 at 16:15
  • DOM queries work on the live tree. If you've inserted that php-generated html into your document, then you can use DOM queries to get it out. e.g. the exame same getElById().innerHTML stuff you're already using. – Marc B Oct 01 '15 at 16:15
  • You could easily do those calls in the success function of the ajax rather than onload – developerwjk Oct 01 '15 at 16:17
  • Possible duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – showdev Oct 01 '15 at 16:21
  • 2
    Possible duplicate of [JavaScript does not fire after appending](http://stackoverflow.com/questions/27494227/javascript-does-not-fire-after-appending) – Jay Blanchard Oct 01 '15 at 16:30

4 Answers4

1

Problem: When you initially load your page, your JS code attaches the events (such as click()) to the elements that are currently on the DOM, but when you load new elements to the DOM through AJAX, those new elements do not have any events binded to them. Thus the events in JS not working.

Solution: You need to delegate the event handler.

Change this:

$('.dropdownItems > div').click(function () {

To this:

$(document).on('click', '.dropdownItems > div', function () {

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

CodeGodie
  • 12,116
  • 6
  • 37
  • 66
1

The problem is that you're attaching click event handlers to items that don't exist yet.

You should use the jQuery's event delegation, e.g:

$('.dropdownItems').on('click', '> div', function () {

Note: If, for some reason, you don't want to use event delegation, and prefer to attach the events to the elements themselves, you must put the ready's code you have into a function, and instead of calling the function when the page is ready, you must call it anytime you modify the collection.

Buzinas
  • 11,597
  • 2
  • 36
  • 58
0
$('.dropdownItems > div').click(function () {

Replace this with

$(document).on('click', '.dropdownItems > div', function() {
Muthu kumar
  • 162
  • 1
  • 2
  • 12
0

The answer was to call the function on success of the response from the AJAX call.

$.ajax({ url: "default/CallSupplierMongo",
    context: document.body,
    success: function (res) {
        document.getElementById("dropdownItems").innerHTML = res;

        loadDropdownFunctions();
    }
});


function loadDropdownFunctions() {

$('.dropdownItems > div').click(function () {
    supplierCode = $(this).html();

    $('.dropdownItems > div').css({
        'background-color': 'white',
        'color': '#888888'
    });

    $(this).css({
        'background-color': '#888888',
        'color': 'white'
    });

    $('.dropdownItems').slideUp('fast');

    $('.dropdownButton').html(supplierCode);
    $('.dropdownButton').css({
        'border-bottom-right-radius': '5px',
        'border-bottom-left-radius': '5px'
    })
});
  • it will work But please pay attention to the first answer. It has a good explanation of the reasons – Dmitry Oct 01 '15 at 16:33
  • lol i explicitly stated in my original post that i knew that was what was going on. but yes, delegating worked, as shown above –  Oct 01 '15 at 17:55