views:

89

answers:

2

I do something like this:

$("#id1").html(data);

I refill a div with html but when I try to get the html of a child of this refilled div I get an empty string although it has, it's like the old child is still there but without html.

Edit: I tried to reproduce my problem, here is the html: (click 2x times on refill and after click open you will see that nothing is going to happen)

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"&gt;&lt;/script&gt;
    <link type="text/css" rel="stylesheet"  href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/themes/dot-luv/jquery-ui.css"/&gt;
</head>
<body>

<script type="text/javascript">
    $(function(){
        $("#r1").click(function(){
        var x = $("#main").html();
        $("#main").html(x);
        });
    });

</script>
<a href="#" id="r1">refill</a>

<div id="main">
<a id="a1" href="#" >open</a>
<script type="text/javascript">
$(function(){
$("#a1").click(function(){$("#forDialog").dialog();});
$("#a2").click(function(){$("#forDialog").dialog('close');});
});
</script>

<div id="forDialog">
hi
    <a id="a2" href="#" >close</a>
</div>
</div>
</body>
</html>

I'm generating this javascript dynamically so the scripts that register a1.click and a2.click need to be inside the main div

A: 

The old sub-DOM under the element will be gone after you reset its content with .html(stuff). It may exist floating around in memory somewhere, but it's detached from the DOM and you can't get at it.

Pointy
I think the old sub-DOM is still available(if you create a reference to it before you refill the element). It's removed from the document-Tree, but still a Node/DocumentFragment(or a jquery-Object)
Dr.Molle
Well OK I suppose that's the case - however the question is kind-of vague so I don't know if that's the real heart of the matter.
Pointy
@Pointy well my problem is that I'm trying to dialog('close') a div which was in the content of the .html(data) but it doesn't close, because it is trying to close the one which doesn't exist anymore; they have the same id of course, one was there and after I replaced the html with basically almost the same content the $('#childdiv').dialog('close') doesn't close the new div, because it is looking for the old one ... I think
Omu
Yes, that's correct. What I generally do with dialogs in cases like that is to have the dialog refer to a container `<div>`, and then have the loadable content go into some sub-`<div>` in the container. That way the actual dialog element stays around even though its contents may change over and over again.
Pointy
@Pointy I've edited my answer, please take a look
Omu
What are you trying to achieve with that code? Frankly, it's weird. Why don't you explain what your *goal* is.
Pointy
@Pointy well, basically I have a popup form which opens other popups, I submit the form inside the popup to the server and I receive the entire html back from the server but with some spans (validation errors) near some inputs, after that some popups that were in this popup don't close anymore with functions that I wrote using $.("#childpopup").dialog('close'); the X button works; in the question-mini-model I managed to reproduce the popup not being able to open
Omu
@Pointy forgot to mention, after I receive the html back from the server I refill the div of the popup
Omu
Well if you overwrite part of the DOM that has a dialog in it, then the Javascript that controls it won't work anymore. That's why I suggested not doing that.
Pointy
+1  A: 

I'm not quite sure as to the exact goal of your code, but I can make 3 general suggesions:

  1. Use .delegate() to attach to once and future elements.
  2. You can .hide() the HTML for you dialog box.
  3. You can prevent the page from refreshing when a link is clicked using event.preventDefault(); in the click handler of that link.

Applying those suggestions to your code results in the following working code:

<script type="text/javascript">

    $("body").delegate("#a1", "click", function(){
        $("#forDialog").dialog();
    });

    $("body").delegate("#a2", "click", function(){
        $("#forDialog").dialog('close');
    });

    $(function(){
          // Hide HTML for the dialog.
        $("#forDialog").hide();

        $("#r1").click(function(event){
            var x = $("#main").html();
            $("#main").html(x);
              // If you don't want the page to refresh by clicking
              //   on this A element, use the following:
            event.preventDefault();
        });
    });

</script>
<a href="#" id="r1">refill</a>

<div id="main">
    <a id="a1" href="#" >open</a>
    <div id="forDialog">
        hi
        <a id="a2" href="#" >close</a>
    </div>
</div>

jsFiddle example

Peter Ajtai
@Peter Ajtai I changed in my real example from .click to $('body').delegate, now my problem is that after refilling once on click I get 2 dialogs instead of 1; after refilling 2 times on click I get 3 dialogs instead of 1 ... etc.
Omu
@Omu - Look at the sample code I provide. Since `.delegate()` will bind event handlers to all now and future elements, it is important that you only fire each `.delegate()` once (look at where I've put my 2 `.delegate()` s). You must be firing each `.delegate()` multiple times. ------- Look at my jsFiddle. You can refill as many times as you want, but you always end up with 1 dialog. ------- Notice that I've taken the jQuery out of `#main`.
Peter Ajtai
@Peter Ajtai I need the jquery to be in #main because I'm generating it dynamically and setting the .html of main; I think I fixed that by calling .undelegate, and delegate after
Omu
@Omu - `.delegate()` is precisely for doing what you describe. Did you try it with the code as I show above? You can fire `.delegate()` once at the top of all the scripts. Notice how my example has the two `.delgete()` above and outside the doc ready. From then on, you can remove and dynamically replace the contents of `#main` as many times as you want, `#a1` and `#a2` will always get the click handlers attached. ----- Is my code example above not helping? - It works with dynamically added HTML.
Peter Ajtai
@Peter Ajtai your code helps for the way I wrote my question (my mini model). My problem is that after I refill some div the elements that were in there still remain, so when I do something with some element by id, I do it with the first one which doesn't exist anymore, using .click it was telling me that I try to dialog('open') an element that wasn't initiated yet; using .delegate it was dialog('open') all of them, I kinda fixed my problem by not using ids and use .classes instead so I work with all the elements at the same time
Omu