views:

5865

answers:

6

We're using Prototype for all of our Ajax request handling and to keep things simple we simple render HTML content which is then assigned to the appropriate div using the following function:

function ajaxModify(controller, parameters, div_id)
{
    var div = $(div_id);

    var request = new Ajax.Request 
    (
     controller, 
     {
      method: "post",
      parameters: parameters,
      onSuccess: function(data) {
       div.innerHTML = data.responseText;
      },
      onFailure: function() {
       div.innerHTML = "Information Temporarily Unavailable"; 
      }
     }
    );
}

However, I occasionally need to execute Javascript within the HTML response and this method appears incapable of doing that.

I'm trying to keep the list of functions for Ajax calls to a minimum for a number of reasons so if there is a way to modify the existing function without breaking everywhere that it is currently being used or a way to modify the HTML response that will cause any embedded javascript to execute that would great.

By way of note, I've already tried adding "evalJS : 'force'" to the function to see what it would do and it didn't help things any.

+8  A: 

The parameter is:

evalScripts:true

Note that you should be using Ajax.Updater, not Ajax.Request

See: http://www.prototypejs.org/api/ajax/updater

Ajax.Request will only process JavaScript if the response headers are:

application/ecmascript, application/javascript, application/x-ecmascript, application/x-javascript, text/ecmascript, text/javascript, text/x-ecmascript, or text/x-javascript

Whereas Ajax.Updater will process JS is evalScripts:true is set. Ajax.Request is geared toward data transport, such as getting a JSON response.

Since you are updating HTML you should be using Ajax.Updater anyways.

Diodeus
THAT WAS TOTALLY WICKED! I can't believe that I never saw this before. Thank you.
Noah Goodrich
Me too. I made the same mistake and spent an hour bashing my head against my monitor. It was because I was just spitting out JS and didn't care about updating any HTML. I ended up updating a dummy/hidden DIV just so I didn't have to fiddle with server headers.
Diodeus
A: 

You should be able to do something like this:

div.innerHTML = "<div onclick='someOtherFunctionTocall();'>";

If you need to execute something at the same time as injecting the HTML, can you modify the signature of ajaxModify() by passing another parameter, which will be the javascript function you're going to execute (if it's not null - which let's you keep it optional, as you surely won't want to execute something on EVERY AJAX response).

Kon
A: 

Does setting evalScripts: true as an option help?

Jeroen Heijmans
A: 

tengo el mismo probelma y no puedo lograr que se ejecuten las funciones que tengo dentro del php que llamo mediante ajax y que coloco en un div. tengo funciones javascript que se ejecutan en ciertos eventos que ocurren dentro de la pagina llamada, como por ejemplo en el onChange de un combo se me actualiza un textarea, pero ni siquiera ve la funcion , solo la ve si la pongo en el html superior , pero no quiero poner todas en el nivel superior, eso no me sirve.

A: 

Just execute a custom my_function() after the ajax response

div.innerHTML=...ajax response text...
my_function()

then execute any function inside the custom my_function()

function my_function() {
  function_1()
  ...
}

Note that my_function() should be somewhere outside the div.innerHTML.

Ray Chakrit
A: 

Found this answer today via Google search. I have it "half" working. What I mean is, my response text comes back and updates my div perfectly with evalScripts: false, however the scripts of course are not executed. When I set evalScripts: true, then the ONLY thing that executes is the scripts and it outputs it directly to the page instead of loading it into the div. Any idea what I am doing wrong? Here's my code:

function runCalcs() {
var request = new Ajax.Updater
(
    "result_tab_frame","ajax_runCalcs.asp",
    {
        method: "get",
        evalScripts: true,
        onSuccess: function () {
            document.getElementById("loading").className = "clsHide";
        }
    }
);

}

grinder