Almas Adilbek
Almas Adilbek

Reputation: 4410

jQuery select dynamically created html element

There are a lot of asked questions with almost similar titles with this question of mine, but you know I didn't find an answer.

My simple question is: I have button, when I click on it, javascript creates modal window

<div class="aui-dialog">
     html here... 
     <button id="closeButton">Close</button>
</div>

just after <body> tag.

I can bind click event of close button with no problem using jQuery live:

$("#closeButton").live("click", function() { 
    alert("asdf"); // it calls
    $("body").find(".aui-dialog").remove();
});

My problem is, I cannot select that dynamically created modal window div by its classname. So that I could call jQuery .remove() method to make close action. Now I know, I must deal with dynamic elements in another way.

What way?

EDIT:
I think it's important to mention this:
I dont' create the modal window myself, I use liferay portal. It has built-in javascript framework AUI(YUI) that creates that modal window. I can just create that close button inside it in its view.

EDIT 2:
Modal window div class attribute value is: "aui-component aui-panel aui-dialog aui-widget-positioned"

Upvotes: 17

Views: 51989

Answers (6)

JUlinder
JUlinder

Reputation: 1065

Since jquery will read the current DOM-state when page loads:

jQuery( document ).ready(function( $ ) {

it will miss the elements you generate post to page load.

One simple solution is to listen for clicks on document, and filter with the class or element-type that you want to use to execute your code. That way jquery will find new elements generated under document, after page load.

$(document).on("click", '#closeButton', function(){
$(".aui-dialog").remove();
});

Upvotes: 15

ahmadalibaloch
ahmadalibaloch

Reputation: 6021

Many users will come on this page when they want to select some element generated runtime by JQuery and it failed, like me.
The solution is simply approach the root (the parent) of your randomly generated element and then get inner by jQuery TAG selection. For example you generate many TDs of users in a table at runtime, the element having your users list is a table with id tblUsers then you can iterate over runtime generated TRs or TDs as following:

$("#tblUsers tr").each(function(i){
    alert('td' + i);
});   

further if you have inputs in tds you can go deep in selection as

$("tblUsers tr td input")

Another case could be a randomly generated dialog or popup, then you have to approach its root(parent) and next same selection by TAG as stated above.

Upvotes: 5

Almas Adilbek
Almas Adilbek

Reputation: 4410

I found an answer, hope it would be helpful for developers who faced with dynamically generated html with IFRAME inside.

If you have a button (#closeButton) inside that IFRAME, and you want select iframe parent window's dom elements, just add second argument window.parent.document for your selector:

// This functions is inside generated IFRAME
$("#closeButton").on("click", function() {        
       // body - is your main page body tag
       /* Will alert all html with your dynamically 
          generated html with iframe and etc. */
       alert($('body', window.parent.document).html()); 
       return false;
}); 

Upvotes: 0

Stian
Stian

Reputation: 1299

UPDATED:

You can use:

$(".aui-dialog").live('click', function() {
    $(this).remove();
    return false;
});)

This attach an event handler for all elements which match the current selector, now and in the future. Please not that this method is depreciated in newer version of jQuery and you should consider using .on() instead of .live().

Upvotes: 0

Joseph
Joseph

Reputation: 119897

You could do a few things, but first, if you are using jQuery 1.7, better use .on(). it has replaced .live() which is deprecated.

if you have no control over the building of the modal but know that the button is a direct child of the modal, then use parent()

$('#closeButton').on('click',function() {
    $(this).parent().remove();
    return false;
});

if the button is somewhere deep in the parent but has a fixed depth from the parent, use parents() which gets all ancestors of the element, and then filter it to a specific depth. if the close was 2 levels deep, the index of :eq() would be 1.

$('#closeButton').on('click',function() {
    //where N is zero-indexed integer, meaning first item of the set starts with 0
    $(this).parents(':eq(N)').remove(); 
    return false;
});

another way is to add the handler when the modal is created

var modal = $('modalHTML');

$('#closeButton',modal).on('click',function(){
    //modal still refers to the whole modal html in this scope
    modal.remove();
});

//show modal

Upvotes: 3

binarious
binarious

Reputation: 4588

Create a reference when you're creating the modal window:

var modalWindow = $('<div class="aui-dialog">html here... <button id="closeButton">Close</button></div>');
// later...
modalWindow.remove();

To your edit:

Get the window via jQuery's parent when the button is inside the modal window:

$('#closeButton').on('click',function() {
    $(this).parent().remove();
    return false;
});

Upvotes: 12

Related Questions