moey
moey

Reputation: 10887

Automatically Invoke a jQuery Plugin on a Dynamically-Created Element

I need to apply a jQuery plugin to an HTML element that will be created upon a user's input. For example:

<!-- Upon click, this link creates a new div with an id of 'target'. -->
<a id="trigger-a" href="javascript:void(0);">Create a new div</a>

/* This will not work because div#target isn't available yet upon page load. */
$(function() {
  $("div#target").aJQueryPlugin( ... );
});

In the simplest form, I can call the plugin inside the <a>'s click handler, after the div is created.

$(function() {
  $("#trigger-a").click(function() {
    // Create div#target.

    // I can call the plugin here but is there a different, maybe better, way?
    $("div#target").aJQueryPlugin( ... );
  });
});

However, if possible, I am looking for something that is more "automatic"; maybe using .on() that automatically invokes the plugin once the element becomes available?

Paraphrasing the question: In jQuery, is there a way to "monitor" when a certain element becomes available (i.e. after it's being created)? If there is, I'd then call the plugin or other functions as a callback.

Upvotes: 6

Views: 4068

Answers (7)

ogur
ogur

Reputation: 4586

Maybe something like this?

HTML

<a id="trigger-a" href="javascript:void(0);">Create a new div</a>

<div class="cont"></div>

JS

$("#trigger-a").click(function () {
    var $div = $('<div>', {class: 'target', text: 'text'});
    $('.cont').append($div);
    $div.trigger('divCreate');
});

$('.cont').on('divCreate', 'div.target', function () {
    $(this).append('added by event')
});

http://jsfiddle.net/Q2UYC/

Triggering custom event let you bind event handler later.

Upvotes: 3

Steve O
Steve O

Reputation: 5774

If you can't bring the plugin in at the same time as the element creation (like andbeyond suggested in their comment), for whatever reason, my advice would be to use Brandon Aaron's LiveQuery plugin:

http://brandonaaron.net/code/livequery/docs

...Live Query also has the ability to fire a function (callback) when it matches a new element and another function (callback) for when an element is no longer matched. This provides ultimate flexibility and untold use-cases.

Hope that's helpful :)

Upvotes: -1

daniel0mullins
daniel0mullins

Reputation: 1959

I would also be interested to see the code that inserts the new DOM object. Let's assume it's something like this: (you really shouldn't be using onclick handlers)

$("#trigger-a").click(function() {
    $(this).after('<div id="someDiv"></div>');

    $that = $("#someDiv");

    $that.ajQueryPlugin(...);
});

Is the best I can do without seeing more information...

Click the trigger, insert the new div, grab that object and run the plugin on it. Basically you're operating on the div at the time of creation, no need to 'monitor'.

Upvotes: 0

Bipin Chandra Tripathi
Bipin Chandra Tripathi

Reputation: 2620

You can use live() or on() for this

$(document).ready(function(){
    $('div#target').on('click',function(){});
});

Upvotes: -2

user1840875
user1840875

Reputation:

You can use 'DOMNodeInserted' which is not a jQuery event.

$(document).bind('DOMNodeInserted', function(event) {

//write your stuff here to check if desired element was inserted or not.

    alert('inserted ' + event.target.nodeName + // new node
        ' in ' + event.relatedNode.nodeName); // parent
});

Upvotes: 4

Jonathan Reyes
Jonathan Reyes

Reputation: 94

If you must check the element is there before calling the plugin, you could probably try something like this:

$('#click-here').click(function() {
    $(this).after('<button class="new-button">I am a new button</button>');

    var checkElement = setInterval(function() {
        if ($('.new-button').length) {
            $('.new-button').button({'label': 'I am a new fancy button'});
            clearInterval(checkElement);
        }
    }, 200);
});

You can see it working here.

Note that the .button function is a jQuery UI plugin initialization, so it should also work for the plugin you need. You should also change the setInterval second argument to something else, 200 is just to show a delay.

Upvotes: 1

anson
anson

Reputation: 4164

jQuery's delegate and on are both good for this. Note that if you use older versions of jQuery you can use delegate but if you use the latest version (1.7+) you need to use on.

With these you must call the method using an element that is already loaded and use a parameter to specify to element that fires the event. To make this as efficient as possible this element should be the closest parent to the dynamically created element.

For instance if on click of the anchor tag, you place a div with id of 'target' into a container that was already loaded before the call to on, with an id of 'container', your on call should be.

$('#container').on('click', '#target', function(){ $(this).pluginCall(); });

You cant simply just call on onto the #target div because that element has not been loaded yet.

The other solution is to place a $(document).ready() function inline into your dynamically created content that calls your plugin. You wont need on or delegate in this instance but this will only work for the currently loaded elements. In the first example, any instance of #target that gets created from any ajax call will be the click handler.

Upvotes: 0

Related Questions