3

After using AJAX to load a partial view in to a dialog on the page, this code, located in the partial itself NOT in the main page, runs and I get tabs as expected:

// Run this on page load
$(function () {
    debugger;
    $("#ProjectTabset").tabs();
});

This being the case, if the div containing the partial was removed from the DOM (using jQuery remove) then added again and the partial loaded in to it once more, it should run again, but it doesn't.

Why would it run the first time, but not any subsequent time? Could the problem be that the div in to which the partial is being inserted is not really removed somehow? (Though I am testing it is not present before creating, and it seems it is no longer part of the DOM.)

Please let me know if I can be more clear or provide any more detail :)

GP24
  • 867
  • 2
  • 13
  • 28
  • you should call ``$("#ProjectTabset").tabs();`` in the success call back of ajax call – Ehsan Sajjad Jun 16 '14 at 05:28
  • Thanks, I have tried that, and it works, but I am interested in why this code runs the first time but not thereafter. – GP24 Jun 16 '14 at 05:32
  • have you tried using $(document).find("#ProjectTabset").tabs();? – Bhushan Kawadkar Jun 16 '14 at 05:36
  • 1
    $(document).ready() runs when the document is ready. Appending html after the fact does not make the document not ready, once it is ready, it is always ready until the page is unloaded. $(document).ready() only gets triggered once. You can bind to it as many times as you like/need, but each one will only execute once. – Kevin B Jun 16 '14 at 05:43
  • @KevinB, I think, you should post your comment as answer. – Jashwant Jun 16 '14 at 05:49
  • Better to find the duplicate, just wasn't able to at the time – Kevin B Jun 16 '14 at 06:26
  • @KevinB, sorry if I am not being clear, but the document ready (DR) I am talking about it is in the newly loaded partial, and runs after the parent page's DR, once it has been loaded. My question is why that only happens the first time the partial is loaded and not any subsequent time. – GP24 Jun 16 '14 at 06:55
  • It isn't happening only the first time. That or you aren't appending it every time. Something else is happening. – Kevin B Jun 16 '14 at 13:03
  • I can see why you would say that but the breakpoints in the DR are only reached the first time, and the new div containing the partial appears every time. Something else is definitely happening, but I can't think what. Do you have any ideas? – GP24 Jun 17 '14 at 00:48

2 Answers2

0

Since you have removed the element from DOM and added back dynamically you may need to use the delegated events via on() if you want events to be handled on dynamically added elements. Try the below and see if it helps.

$( document ).on( 'ready', function (e) {
   $("#ProjectTabset").tabs();
})

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

May be the links here will help you resolve the problem.

Community
  • 1
  • 1
Dennis R
  • 3,195
  • 1
  • 19
  • 24
  • Thanks Dennis, this is a good idea. I added the code the the parent page, and to its document ready (DR), and both executed but did not result in the partial's DR running again. I also added it to the partial, and its DR but it does not get executed at all. Am I explaining this well enough? Its a weird scenario and I am worried its not clear what's happening. Its not my code and I was a bit surprised a DR would run at all from the newly inserted partial... – GP24 Jun 16 '14 at 06:18
  • Do not bind to .ready in this way. It does not do what you think it does. `ready` isn't handled the same way as most other events within jQuery. Not to mention, your syntax doesn't even have anything to do with event delegation. – Kevin B Jun 16 '14 at 17:50
  • @KevinB, sorry for the delayed reply, I didn't receive a notification for your comment for some reason. Can you elaborate? I am pretty clear on what .ready does, do you mean the delegation set up Dennis R suggested? – GP24 Jul 02 '14 at 07:22
  • @Gp24 my point was it is impossible to delegate the ready event, and binding to it with .on is considered a bad practice according to the docs. The problem with binding to it with .on is that it will not work if the ready event has already fired, it can only fire once for the life of a single page. – Kevin B Jul 02 '14 at 13:10
  • The ready event does nothing that will help you solve your problem. – Kevin B Jul 02 '14 at 13:13
  • @KevinB, the tests I ran certainly seem to agree with that, though I am not that familiar with delegating events in JS. The behaviour of the .ready event is my question here...why it would run the first time a partial is loaded but not thereafter. I have seen some things since that make me think that if there was an error in the JavaScript after the .ready on the first load, it might not run correctly subsequently. Might try to test that theory today. – GP24 Jul 03 '14 at 01:16
  • because it's not a normal event. It is not the same as, say, a click event or a change event. The event only happens when the DOMContentLoaded event happens, which is only once. https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded Doing ajax will not retrigger it. – Kevin B Jul 03 '14 at 01:19
-3

You should use .delegate():

 // Run this on page load or ajax load complete
 $('body').delegate('#ProjectTabset', 'ready', function() {
        $("#ProjectTabset").tabs();
 });

UPDATE:

$(document).delegate('#ProjectTabset', 'click', function() {
    $('#ProjectTabset').tabs();
}

$.ajax(function(){
    ...
    success: function(){
        $('#ProjectTabset').click();
    }
})
mihutz
  • 195
  • 1
  • 3
  • 11
  • And make sure you call that function after the ajax request is ready! ;) – mihutz Jun 16 '14 at 05:52
  • Thanks mihutz, I tried putting this code in the parent page and its document ready (DR), and in the partial, its DR and the success function of the ajax call but none seem to work as expected. Indeed the .tabs(); line never seems to get called. Was there somewhere else you meant for me to use the code? – GP24 Jun 16 '14 at 06:39
  • Thanks mihutz, I ma doing something very similar to that - basically just calling the .tabs() in the success function. Am trying to work out what would stop the document ready function contained in the partial I am loading from running if it runs the first time it is added to the DOM. – GP24 Jun 16 '14 at 07:48