Execute document.ready after ajax post

55,239

Solution 1

You could always just put everything in one function (named loadfunction or something) and call that function when the document loads, and again when the ajax is loaded. Though it is a hacked together solution, it should work well enough.

So then take everything between $(document).onready(function () { and its end bracket } And put it in function OnloadFunction () { ending with }. Then put $document.onready(OnloadFunction);

Example: You have

$(document).ready(function () {alert("test");});

It would turn into:

function OnloadFunction ()
{
    alert("test");
}
$(document).ready(OnloadFunction);

Then you can call OnloadFunction whenever you want to.

Solution 2

Combining Ben and fotanus' answers I created the following pattern:

$(document).ready(function () {
    AjaxInit()
});

$(document).ajaxComplete(function () {
    AjaxInit()
});

function AjaxInit() {
    alert("test");
}

Solution 3

There is a event that triggers after every ajax call. It is called ajaxComplete.

$( document ).ajaxComplete(function() {
    $( ".log" ).text( "Triggered ajaxComplete handler." );
});

Solution 4

I've successfully used a pattern like the following:

First off we must define a .query() plugin.

// jQuery.fn.query() emulates the behavior of .querySelectorAll() 
// by allowing a full/complex selector to be matched against
//a small slice of the dom. 
$.fn.query = function ( selector ) {
    var scopeElms = this,
        scopeIsDoc = scopeElms.length === 1  &&  scopeElms.is('html') ,
        // check for obviously simple selectors.... (needs more elegance)
        isComplexSelector = /\s/.test( selector.replace(/\s*([|~*$\^!]?=|,)\s*/g, '$1') ),
        elms;
    if ( scopeIsDoc  ||  isComplexSelector )
    {
      elms = $(selector);
      if ( scopeElms[0] )
      {
        elms = elms.filter(function(){
            var i = scopeElms.length;
            while (i--) {
              if ( scopeElms[i] === this || $.contains(scopeElms[i], this) )
              {
                return true;
              }
            }
            return false;
          });
      }
    }
    else
    {
      elms =  scopeElms.filter( selector )
                  .add( scopeElms.find(selector) );
    }
    return $(elms);
  };

We then write our init function and bind it to the "ready" event, and also to our custom "domupdated" event. Within the init function we use .query() to find elements from either the whole document or just the updated fragment...

// Here we define our DOM initializations
$(document).bind('ready domupdated', function (e, updatedFragment) {
    var root = $( updatedFragment || 'html' );

    // Begin imaginary initialization routines
    root.query('form').validate();
    root.query('.sidebar .searchform input#search').autocomplete();
    // etc...

  });

Then whenever we inject blocks of new elements into the DOM (like when an Ajax request has finished) we then trigger the domupdated event and pass the updated DOM fragment as a parameter - like so:

...
var ajaxedDom = $(xhr.resultText).find('#message');
ajaxedDom.appendTo( '#modal' );

$(document).trigger('domupdated', [ajaxedDom]);

For me, this set up takes all the pain out of initing the DOM. It allows me to maintain a single set of init routines, and focus on the fun things.

Solution 5

Minor twist on Ken Mc's answer. For whatever reason my ajaxComplete would not fire unless it was nested within a document.ready. Nesting it inside and still calling out worked for me.

$(document).ready(function () {
    AjaxInit();

    $(document).ajaxComplete(function () {
      AjaxInit()
    });
});

function AjaxInit() {
    alert("test");
}

Share:
55,239

Related videos on Youtube

Jason Yost
Author by

Jason Yost

I am a senior software engineer based in CO. I have been developing software for 18 years and have a wealth of experience in both Microsoft and various open source platforms. I enjoy learning new technologies and am just a geek in general.

Updated on July 09, 2022

Comments

  • Jason Yost
    Jason Yost almost 2 years

    I have a custom.js file in which I have several elements that have click and other methods bound to them. The entire file is encapsulated in document.ready() and everything works. However when I do an AJAX post obviously document.ready() is never fired again for the current page. Is there anyway I can get document.ready() to fire again or do I need to have everything in named functions call them form my create.js.erb?

    • Jason Yost
      Jason Yost about 13 years
      Pretty simple, when you do an AJAX post the DOM is not reloaded, thus document.ready does not fire again. My question is specifically if there is a way to do that that I am unaware of. The contents of the js file are irrelevant to the question and too long to post. The code in the files are doing standard tag based manipualtion such as $("a").click(function(){return false;});
  • Shadow The Kid Wizard
    Shadow The Kid Wizard about 13 years
    To put code on the words, it's something like $(document).ready(function DocReady() { ... });
  • Micaël Félix
    Micaël Félix over 10 years
    There's a reason, your code is wrong. By doing $(document).onready(OnloadFunction()); you're pushing the return of OnLoadFunction (which is undefined) inside the onready method.

Related