Hello, I''m having an issue with getting embedded javascript code to actually run when loaded via an Ajax.Request() call and the callback function inserts the generated HTML and js code to my current page. It seems that the javascript code is not properly parsing. For example, I''m using the following function showinfo() to return some html code. function showInfo(go_url){ if($("display_area") && go_url){ var xmlHttp= new Ajax.Request(go_url, {method: "post", parameters: Form.serialize(document.forms[0]), onComplete:function(){ if(xmlHttp.responseIsFailure()) { var sts = xmlHttp.transport.status ? xmlHttp. transport.status : "undefined"; $("debug_msg").value "XMlHttpRequest returned response status "+sts; document.getElementById("debug_msg").innerHTML "HTTP response and server information; "+ "response status="+ xmlHttp.transport.status; } else { document.getElementById("display_area").innerHTML =xmlHttp.transport.responseText; document.getElementById("debug_msg").innerHTML "HTTP response and server information; "+ "response status="+ xmlHttp.transport.status; } }}); } } Now, in the line document.getElementById("display_area").innerHTML=xmlHttp.transport.responseText; Generated by the link saved in go_url, I have html code that I derived from the examples in ajax_inplaceeditor_test.html to appear in between my <div id="display_area"> tags. The inplace editing functionality works when I run the go_url link on its own, but when I embed it in the manner above, the html properly appears, but the code does not run. Am I doing the right thing to use innerHTML? -Al
Add ''evalScripts: true'' to your options on the Ajax.Request constructor. Setting innerHTML with javascript does not cause the javascript to be invoked. Greg> -----Original Message----- > From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org[mailto:rails-spinoffs-> bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Al > Sent: Wednesday, April 12, 2006 1:05 PM > To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > Subject: [Rails-spinoffs] innerHTML and scripts not running > > Hello, > > I''m having an issue with getting embedded javascript code to actually > run when loaded via an Ajax.Request() call and the callback function > inserts the generated HTML and js code to my current page. It seems > that the javascript code is not properly parsing. > > For example, I''m using the following function showinfo() to return > some html code. > > function showInfo(go_url){ > if($("display_area") && go_url){ > > var xmlHttp= new Ajax.Request(go_url, {method: "post", > parameters: Form.serialize(document.forms[0]), > onComplete:function(){ > > if(xmlHttp.responseIsFailure()) { > var sts = xmlHttp.transport.status ? xmlHttp. > transport.status : "undefined"; > $("debug_msg").value> "XMlHttpRequest returned response status "+sts; > document.getElementById("debug_msg").innerHTML> "HTTP response and server information; "+ > "response status="+ > xmlHttp.transport.status; > } else { > document.getElementById("display_area").innerHTML > =xmlHttp.transport.responseText; > > document.getElementById("debug_msg").innerHTML> "HTTP response and server information; "+ > "response status="+ xmlHttp.transport.status; > } > }}); > } > } > > > Now, in the line > >document.getElementById("display_area").innerHTML=xmlHttp.transport.resp on> seText; > > Generated by the link saved in go_url, I have html code that I derived > from the examples in ajax_inplaceeditor_test.html to appear in between > my <div id="display_area"> tags. The inplace editing functionality > works when I run the go_url link on its own, but when I embed it in > the manner above, the html properly appears, but the code does not > run. > > Am I doing the right thing to use innerHTML? > > > -Al > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
Thanks for the reply. Apparently evalScripts doesn''t work for Ajax.Request(). According to the documentation in http://wiki.script.aculo.us/scriptaculous/revision/Ajax.Request: Note: even though the Rails helpers inject it as an option, the ''evalScripts'' option does not work with Ajax.Request. See Ajax.Updater if you want ''evalScripts'' to work. I''m using Ajax.Updater() now, and it works great. Thanks for the lead! On 4/12/06, Gregory Hill <Gregory_Hill-l9nu40+TWxQ@public.gmane.org> wrote:> Add ''evalScripts: true'' to your options on the Ajax.Request constructor. > > Setting innerHTML with javascript does not cause the javascript to be > invoked. > > Greg > > > -----Original Message----- > > From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > [mailto:rails-spinoffs- > > bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Al > > Sent: Wednesday, April 12, 2006 1:05 PM > > To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > Subject: [Rails-spinoffs] innerHTML and scripts not running > > > > Hello, > > > > I''m having an issue with getting embedded javascript code to actually > > run when loaded via an Ajax.Request() call and the callback function > > inserts the generated HTML and js code to my current page. It seems > > that the javascript code is not properly parsing. > > > > For example, I''m using the following function showinfo() to return > > some html code. > > > > function showInfo(go_url){ > > if($("display_area") && go_url){ > > > > var xmlHttp= new Ajax.Request(go_url, {method: "post", > > parameters: Form.serialize(document.forms[0]), > > onComplete:function(){ > > > > if(xmlHttp.responseIsFailure()) { > > var sts = xmlHttp.transport.status ? xmlHttp. > > transport.status : "undefined"; > > $("debug_msg").value> > "XMlHttpRequest returned response status "+sts; > > document.getElementById("debug_msg").innerHTML> > "HTTP response and server information; "+ > > "response status="+ > > xmlHttp.transport.status; > > } else { > > document.getElementById("display_area").innerHTML > > =xmlHttp.transport.responseText; > > > > document.getElementById("debug_msg").innerHTML> > "HTTP response and server information; "+ > > "response status="+ xmlHttp.transport.status; > > } > > }}); > > } > > } > > > > > > Now, in the line > > > > > document.getElementById("display_area").innerHTML=xmlHttp.transport.resp > on > > seText; > > > > Generated by the link saved in go_url, I have html code that I derived > > from the examples in ajax_inplaceeditor_test.html to appear in between > > my <div id="display_area"> tags. The inplace editing functionality > > works when I run the go_url link on its own, but when I embed it in > > the manner above, the html properly appears, but the code does not > > run. > > > > Am I doing the right thing to use innerHTML? > > > > > > -Al > > _______________________________________________ > > Rails-spinoffs mailing list > > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >
Hi, You can always do a response.responseText.evalScripts() in the onComplete function. Eg: onComplete: function(response) { // xyz //xyz response.responseText.evalScripts() } Hope this helps. Thanks, Irfan -----Original Message----- From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org [mailto:rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org]On Behalf Of Al Sent: Thursday, April 13, 2006 1:53 AM To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org Subject: Re: [Rails-spinoffs] innerHTML and scripts not running Thanks for the reply. Apparently evalScripts doesn''t work for Ajax.Request(). According to the documentation in http://wiki.script.aculo.us/scriptaculous/revision/Ajax.Request: Note: even though the Rails helpers inject it as an option, the ''evalScripts'' option does not work with Ajax.Request. See Ajax.Updater if you want ''evalScripts'' to work. I''m using Ajax.Updater() now, and it works great. Thanks for the lead! On 4/12/06, Gregory Hill <Gregory_Hill-l9nu40+TWxQ@public.gmane.org> wrote:> Add ''evalScripts: true'' to your options on the Ajax.Request constructor. > > Setting innerHTML with javascript does not cause the javascript to be > invoked. > > Greg > > > -----Original Message----- > > From: rails-spinoffs-bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > [mailto:rails-spinoffs- > > bounces-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org] On Behalf Of Al > > Sent: Wednesday, April 12, 2006 1:05 PM > > To: rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > Subject: [Rails-spinoffs] innerHTML and scripts not running > > > > Hello, > > > > I''m having an issue with getting embedded javascript code to actually > > run when loaded via an Ajax.Request() call and the callback function > > inserts the generated HTML and js code to my current page. It seems > > that the javascript code is not properly parsing. > > > > For example, I''m using the following function showinfo() to return > > some html code. > > > > function showInfo(go_url){ > > if($("display_area") && go_url){ > > > > var xmlHttp= new Ajax.Request(go_url, {method: "post", > > parameters: Form.serialize(document.forms[0]), > > onComplete:function(){ > > > > if(xmlHttp.responseIsFailure()) { > > var sts = xmlHttp.transport.status ? xmlHttp. > > transport.status : "undefined"; > > $("debug_msg").value> > "XMlHttpRequest returned response status "+sts; > > document.getElementById("debug_msg").innerHTML> > "HTTP response and server information; "+ > > "response status="+ > > xmlHttp.transport.status; > > } else { > > document.getElementById("display_area").innerHTML > > =xmlHttp.transport.responseText; > > > > document.getElementById("debug_msg").innerHTML> > "HTTP response and server information; "+ > > "response status="+ xmlHttp.transport.status; > > } > > }}); > > } > > } > > > > > > Now, in the line > > > > > document.getElementById("display_area").innerHTML=xmlHttp.transport.resp > on > > seText; > > > > Generated by the link saved in go_url, I have html code that I derived > > from the examples in ajax_inplaceeditor_test.html to appear in between > > my <div id="display_area"> tags. The inplace editing functionality > > works when I run the go_url link on its own, but when I embed it in > > the manner above, the html properly appears, but the code does not > > run. > > > > Am I doing the right thing to use innerHTML? > > > > > > -Al > > _______________________________________________ > > Rails-spinoffs mailing list > > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs > _______________________________________________ > Rails-spinoffs mailing list > Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs >_______________________________________________ Rails-spinoffs mailing list Rails-spinoffs-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs
Al wrote:>Hello, > >I''m having an issue with getting embedded javascript code to actually >run when loaded via an Ajax.Request() call and the callback function >inserts the generated HTML and js code to my current page. It seems >that the javascript code is not properly parsing. > >I had a similar problem in the system I am writing. I found that prototype.js has an evalScripts extention to the String object. Calling this will execute code at run time. The one problem with this is that any code that defines functions works only while being evaluated. The functions are not defined if you try to call them later. If you need to add additional functions to an existing page you need to add a script element to the DOM and get it evaluated. After a little experimenting I finally came up with this function: function loadScripts(scrId, scrCode) { if(document.getElementById(scrId) == null) { var head = document.getElementsByTagName("head").item(0); scrHandle = document.createElement("script"); scrHandle.id = scrId; scrHandle.type = ''text/javascript''; void(head.appendChild(scrHandle)); } scrHandle.text = scrCode; } This basically just adds a new script element to the DOM and then loads and evaluates a string containing javascript at run time. Any functions that are defined in the loaded string will be available and callable from that point onward. The scrId is a unique name used to identify the new script element, and the scrCode is the actual script text to load. This function works on Firefox 1.x, IE 6.x and Opera 8.x that I have tried. Hope this helps, -- Will Merrell
On 4/14/06, Will Merrell <will-jkbzaOXREqcCMe7iY93BLQC/G2K4zDHf@public.gmane.org> wrote:> The one problem with > this is that any code that defines functions works only while being > evaluated. The functions are not defined if you try to call them later.They are defined in the context the eval is executed in. That is: as inner functions of the evalScripts method. If you want them to be members of the global object, 1. assign them to the global object using the window.newfunction function(){...} syntax or 2. roll your own evalScripts method that does the eval in a setTimeout, as timeouts are executed in the global object. The drawback of number 2 is that the new functions are not available directly after the evalScripts call. It depends on the intended use if this is s problem or not. But that is just as with your method of adding script elements to the DOM. Bye, Martin
To add to thsi - Merrell - Your solution won''t work in Safari as document.createElement("script"); is not supported. Thanks, Mandy.
To followup to myself:> They are defined in the context the eval is executed in. That is: as > inner functions of the evalScripts method.The way evalScripts is implemented in prototype: as inner functions of the enumerator iteration. A third solution (untested) would be evalScriptsGlobal: function() { return this.extractScripts().map(function(s){eval(s)}.bind(window)); }, directly changing evalScript could be problematic. You never know if someone depends on the current behaviour of encapsulation. Bye, Martin
Too fast on the trigger finger.> evalScriptsGlobal: function() { > return this.extractScripts().map(function(s){eval(s)}.bind(window)); > },should rather be evalScriptsGlobal: function() { return this.extractScripts().map(function(s){eval.call(window, s)}); },
A couple of days ago Maninder, Singh wrote:>To add to this - > >Merrell - > >Your solution won''t work in Safari as document.createElement("script"); is not supported. > >Thanks, >Mandy. >Well that figures. So, now my question is: is there a way to do this under Safari? What does Safari support? Can Safari modify it DOM? Thanks for any help. -- Will Merrell
Check scriptaculous.js for doing it the document.write way. require: function(libraryName) { // inserting via DOM fails in Safari 2.0, so brute force approach document.write(''<script type="text/javascript" src="''+libraryName+''"></script>''); - Mandy.
Will Merrell
2006-Apr-18 03:09 UTC
Re: innerHTML and scripts not running and evalScripts in IE
Martin Bialasinski wrote:>should rather be > > evalScriptsGlobal: function() { > return this.extractScripts().map(function(s){eval.call(window, s)}); > }, > >Thanks to all who have supplied input on this. To recap the problem that I would like to see a universal solution for: (I think the OP was also looking for this) I want to be able to load javascript functions (possibly a lot of code) into an existing page in response to a user action and have that code be executable from that point forward. That is, the page loads, the user does something, the page loads new javascript from the server that implements new event handlers, the user can then take actions that execute these freshly loaded functions, all without reloading the entire page. The holy grail is that this should work for Mozilla, IE, Opera, and Safari, on all of their respective platforms. To do this something that holds the new functionality must be added into the global space in such a way that it remains available after the loading is complete. It would be nice if this persistent container were detectable so that reloading could be avoided if the user invokes the load operation a second time. I have not yet seen such a universal solution. Suggestions I have seen so far: I proposed a function that adds a script element to the DOM. This works for Mozilla, IE and Opera under Windows, but does not work for Safari because Safari does not support createElement. Someone suggested using document.write to write a new script element. I don''t see how this helps because I am not aware of any way to write to a completed page without overwriting the page. This appears to me to be simply a page reload. Martin Bialasinski suggested a modified version of prototype.js''s evalScripts. This looked promising, but as far as I can tell it does not work in IE. I have included a test sample below that uses it, and it works in Mozilla and Opera, but not in IE. Is there any universal solution to this? -- Will Merrell =================== Test Page begin ========================<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>Eval Test</title> <script type="text/javascript" src="functions/javascript/prototype.js"></script> <script type="text/javascript"> <!-- Object.extend(String.prototype, { evalScriptsGlobal: function() { return this.extractScripts().map(function(s){eval.call(window, s)}); } }); function loadScripts(scrCode) { alert("Loading " + scrCode); newscript = "<script type=\"text/javascript\" >" + scrCode + "<\/script>\n"; newscript.evalScriptsGlobal(); alert(newscript); } function loadit() { loadScripts($("textarea_1").value); } // --> </script> </head> <body> <textarea id="textarea_1" rows="10" cols="80" name="textarea1"></textarea><br /> <button onclick="loadit();" >Load It</button> <button onclick="testit();" >Test It</button> <script type="text/javascript"> <!-- // This script simply preloads the text area to save time. $("textarea_1").value = "function testit() { alert(\"Hello from TestIt\"); }\n"; // $("textarea_1").value = "testit = function() { alert(\"Hello from TestIt\"); }\n"; // --> </script> </body> </html> =================== Test Page end=========================