javascript not executed with ajax - php

How to make javascript code execute on php page which was previously loaded from an ajax call?
code samples:
ajax+function parseScript to force javascript to run on the ajax requested page
Senario: I am selecting a question from selectQuest.php and using ajax it request a page called showRecord.php.
The page showRecord.php will display a table which contain the information corresponding to the quetsion selected.It contains the javascript that do not run.The javascript return will allow me to update info in db when i click submit.
The code sample below is found in the showRecord.php.Finally, if the latter run the showRecord will make another ajax request for updateQuestion.php.
But the javascript is not running in showRecord.php
function show(fileTex,aTex,bTex,cTex,dTex,eTex,newQuestNumTex,textAreaTex,textQuesAnsTex)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)
{
var resp=xmlhttp.responseText;
document.getElementById("txtHint2").innerHTML=resp;
parseScript(resp);
// document.getElementById("txtHint").style.border="1px solid #A5ACB2";
}
}
xmlhttp.open("POST","updateQuestionAdmin.php?param="+fileTex+"&text_A="+aTex+"&text_B="+bTex+"&text_C="+cTex+"&text_D="+dTex+"&text_E="+eTex+"&text_ID="+newQuestNumTex+"&text_Ques="+textAreaTex+"&text_Ans="+textQuesAnsTex,true);
xmlhttp.send();
}
// this function create an Array that contains the JS code of every <script> tag in parameter
// then apply the eval() to execute the code in every script collected
function parseScript(strcode) {
var scripts = new Array(); // Array which will store the script's code
// Strip out tags
while(strcode.indexOf("<script") > -1 || strcode.indexOf("</script") > -1) {
var s = strcode.indexOf("<script");
var s_e = strcode.indexOf(">", s);
var e = strcode.indexOf("</script", s);
var e_e = strcode.indexOf(">", e);
// Add to scripts array
scripts.push(strcode.substring(s_e+1, e));
// Strip from strcode
strcode = strcode.substring(0, s) + strcode.substring(e_e+1);
}
// Loop through every script collected and eval it
for(var i=0; i<scripts.length; i++) {
try {
eval(scripts[i]);
}
catch(ex) {
// do what you want here when a script fails
}
}
}
</script>

As iyrag said, a Javascript framework would help. jQuery has a callback function that you can run when a script is successfully loaded and finished with ajax.
You'll want to execute some other stuff within that callback function, for instance :
$.ajax({
url: 'test.php',
success: function(data) {
$('#result').html(data); // Display script return on some div
someFunction(); // blabla
// Execute some other javascript here, you'll be abble to access the DOM of the test.html
// page because here you'lle be sure that test.html is loaded.showRecord.php should not contain javascript, which would rather be here
}
});
I also posted this because the tag features jQuery...

Related

ajax callback function is empty

It's my first time on StackOverflow, please forgive me if I forget some important information or if my question sounds stupid!
I am building a web site which generates a list once the user writes a word and hits the "Send" button. Php is responsible for extracting the required data and returning it to the web page as a list.
My problem is that I then want to pass this data in a js function. I have read a lot of answers on StackOverflow concerning this, and it sounded like a callback function is what I needed. However, my js function keeps telling me that my node is null; it seems the data returned from ajax is not accounted for.
Here are some parts of my code:
<script>
var xmlhttp;
function loadXMLDoc(cfunc){
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
var us = document.getElementById("user").value;
var ur = document.getElementById("wiki").value;
xmlhttp.onreadystatechange = cfunc;
xmlhttp.open("GET","contributions_old.php?user="+us+"&wiki="+ur+"",true);
xmlhttp.send();
}
function myFunction() {
loadXMLDoc(function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("result").innerHTML=xmlhttp.responseText;
var parser = new DOMParser ();
var responseDoc = parser.parseFromString (xmlhttp.responseText, "text/html");
var text1 = responseDoc.getElementById('old1').value;
var text2 = responseDoc.getElementById('new1').value;
var dmp = new diff_match_patch();
dmp.Diff_Timeout = 0;
// No warmup loop since it risks triggering an 'unresponsive script' dialog
// in client-side JavaScript
var ms_start = (new Date()).getTime();
var d = dmp.diff_main(text1, text2, false);
var ms_end = (new Date()).getTime();
var ds = dmp.diff_prettyHtml(d);
document.getElementById('outputdiv').innerHTML = ds + '<BR>Time: ' + (ms_end - ms_start) / 1000 + 's';
}
});
}
</script>
It's of course the Send button that calls myFunction() at the bottom of my web page, once the user has entered a word.
I have also verified that my web page, once the list has been generated, has the divs with "new1" and "old1" as ids (they are generated through my php code).
Any help would be really appreciated! I feel like I've tried everything!
Thank you! :)
Highly recommend using jQuery or some other lib for this.
var url = "contributions_old.php?user=" + $("#user").val() + "&wiki=" + $("#wiki").val();
$.get(url);

Refresh javascript calculations without reloading page

I have a submit button that uses a javascript xmlhttp request to call a php page that's sole function is to write a kml file for a google earth window on my main page. The php page is not viewable within the web browser as html.
The formulas in the php file work as intended. The problem I'm having is that after I manually press submit the first time I would like the script to continue to repeat every 5 seconds until I manually reload the page (or press a button to stop the script). Because I plan on having multiple users at the same time viewing the page each user is assigned a random 5 digit number to hold their session information and to create the kml files within the newly created session folder until they reload the page (which will then create a new session number for the user).
Because each user is designated with a unique session id the page cannot reload as the php calculations repeat. Because of this I have a return false line at the end of my javascript function.
I would like to be able to use javascript to call setInterval to repeat the function without reloading the page. If the page were to reload the just created kml file will now not be viewable within the new session. Let me know if anyone has any suggestions. Below is the applicable code.
DIV id on main index.php page
<div>
<form id="KMLsubmit" name=KMLsubmit >
<input class="KMLsubmit" type="submit" value="Create KML" onclick="createKML()"/>
</form>
</div>
JavaScript function on main index.php page
function createKML() {
$('#KMLsubmit').submit(function () {
$.get("generateKML.php",function(data,status){
});
//alert("Generating your KML files!");
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("kmldetails").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST","generateKML.php?session=" + session,true);
xmlhttp.send();
return false;
});
}
Let me know if anyone has any suggestions on how to do this. Thanks for the help.
make createKML() external, call it on KMLsubmit submit event, set timeout function of 5 sec and clear the timeout on next submition then restart the process like this:
var myTimer = false;
function createKML() {
var xmlhttp = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("kmldetails").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST", "generateKML.php", true);
xmlhttp.send("session=" + session);
myTimer = setTimeout(function(){createKML()}, 5000);
}
document.getElementById('KMLsubmit').onsubmit = function(event){
(event.preventDefault) ? event.preventDefault() : event.returnValue = false; //prevent the form from submitting and reloading the page
if(myTimer) clearTimeout(myTimer);
createKML();
}
Try
$(function(){
$('#KMLsubmit').submit(function () {
$.get("generateKML.php",function(data,status){
});
update();
return false;
});
function update(){
$.ajax({
url: 'generateKML.php',
data: {
session: session
}
}).done(function(result){
$('#kmldetails').html(result);
setTimeout(update, 5000)
});
}
})

Embed Ajax requests in bind events (XHR)

I'm trying to find the answer somewhere around but i can't,
So i'm having a .bind() event and I want when's triggered to make a get query from a php file with JSON like AJAX does.
I have tried the following which doesn't work:
$(document).ready(function() {
$("#adivhere").bind("valuesChanged", function(){
// Some variables here
var max2 = 10
var min2 = 5
//The classic AJAX Request
function afunc(max2,min2){
var xmlhttp;
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
//The classic AJAX onreadystatechange function
xmlhttp.onreadystatechange=function()
{ if (xmlhttp.readyState==4 && xmlhttp.status==200){
//The code triggered
var fets = jQuery.parseJSON( xmlhttp.responseText );
var t = fets.date.split(/[-]/);
var d = new Date(t[0], t[1], t[2]);
alert(d);
}}
//The XHR request with the .php file and the
// two values that sends
xmlhttp.open("GET","getdates.php?max2="+max2+"&min2="+min2,true);
xmlhttp.send();
};
});
It looks like you're using jQuery, so this should work:
$(function(){
$('#adivhere').bind('valuesChanged',function(){
var max2 = 10;
var min2 = 5;
$.getJSON('getdates.php?callback=?', {max2: max2, min2: min2}, function(json){
alert(json);
var t = json.date.split(/[-]/);
if (t && t.length) {
var d = new Date(t[0], t[1], t[2]);
alert(d);
}
});
});
});
There's already an awesome $.getJSON method in jQuery that will do all of the heavy lifting for you, including return your results as JSON.
You'll need to make your getdates.php script echo the callback and wrap your results in parentheses so it returns as actual jQuery.
There are several "errors" in your script:
"afunc" is never called, so why should it be executed?
the parenthesis are not closed properly; at the end there are two missing: )}

How to combine the two scripts refreshing div into one?

I have two scripts refreshing div dynamic:
1) http://project-welcome.ugu.pl/test/ajax.js
2) http://project-welcome.ugu.pl/test/ajax2.js
I tried to combine it:
// Customise those settings
var seconds = 1;
var divid = "timediv";
var divid2 = "points";
var url = "boo.php";
var url2 = "boo2.php";
// Refreshing the DIV
function refreshdiv(){
// The XMLHttpRequest object
var xmlHttp;
try{
xmlHttp=new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari
}
catch (e){
try{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
}
catch (e){
try{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e){
alert("Your browser does not support AJAX.");
return false;
}
}
}
// Timestamp for preventing IE caching the GET request
fetch_unix_timestamp = function()
{
return parseInt(new Date().getTime().toString().substring(0, 10))
}
var timestamp = fetch_unix_timestamp();
var nocacheurl = url+"?t="+timestamp;
var nocacheurl2 = url2+"?t="+timestamp;
// The code...
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4){
document.getElementById(divid).innerHTML=xmlHttp.responseText;
document.getElementById(divid2).innerHTML=xmlHttp.responseText;
setTimeout('refreshdiv()',seconds*1000);
}
}
xmlHttp.open("GET",nocacheurl,true);
xmlHttp.send(null);
xmlHttp.open("GET",nocacheurl2,true);
xmlHttp.send(null);
}
// Start the refreshing process
var seconds;
window.onload = function startrefresh(){
setTimeout('refreshdiv()',seconds*1000);
}
Source of index.html:
<script src="ajax3.js"></script>
<script type="text/javascript"><!--
refreshdiv();
// --></script>
Logs<div id="timediv"></div><br>
Points<div id="points"></div><br>
It doesn't work because two div show the same (in this case points). How correct combine scripts?
P.s You can see it in file original.php
Login: testowyuser Pass: testtest then click "Strona Główna"
Something goes last and overlaps the 1st.
It's Ok that you are complaining ;), look here
xmlHttp.open("GET",nocacheurl,true); // opening 1st URI
xmlHttp.send(null); // requresting. in the mean time we've got the response and our `onreadystatechange` function triggers
xmlHttp.open("GET",nocacheurl2,true); // opening 2nd URI
xmlHttp.send(null); // the same situation. received response, triggered function
You are using 1 xmlHTTP instance to request for both. and using it sequentially, but demanding it works simultaneously.
So when the function triggers (doesn't matter 1st or 2nd time) you suppose (but not the script) to have already 2 responses in 1 variable. Moreover, you want script guess what you actually want.
document.getElementById(divid).innerHTML = xmlHttp.responseText; // getting response text from the current response (it can be 1st or 2nd response)
document.getElementById(divid2).innerHTML = xmlHttp.responseText; // and again getting the current response text from the same instance (not the response you are expecting from the next request). so, you are repeating the same for the another <div>
Actually each time you have only one response text. And each time you are putting in your <div's> the same information (copy info over 2 <div's>) bec. there is no info about the next request yet.
And as the result in your script, I suppose, you have always last request copied over 2 <div's>.
Try to create 1 instance per "channel" (1 instance of xmlHTTP for the 1st script to use and 1 for the second) and set them different (separate) onreadystatechange function. This way you will not have overlap of data and will not be tangled.
Far more elegant solution (less refactoring in JS) is to distinguish responses. For e.g. if you are receiving XML, you can parse it for some flag that will tell you that this response is for <div id=divid> and another one is for another <div> or this request is first and this is the second etc.

Executing javascript script after ajax-loaded a page - doesn't work

I'm trying to get a page with AJAX, but when I get that page and it includes Javascript code - it doesn't execute it.
Why?
Simple code in my ajax page:
<script type="text/javascript">
alert("Hello");
</script>
...and it doesn't execute it. I'm trying to use Google Maps API and add markers with AJAX, so whenever I add one I execute a AJAX page that gets the new marker, stores it in a database and should add the marker "dynamically" to the map.
But since I can't execute a single javascript function this way, what do I do?
Is my functions that I've defined on the page beforehand protected or private?
** UPDATED WITH AJAX FUNCTION **
function ajaxExecute(id, link, query)
{
if (query != null)
{
query = query.replace("amp;", "");
}
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
if (id != null)
{
document.getElementById(id).innerHTML=xmlhttp.responseText;
}
}
}
if (query == null)
{
xmlhttp.open("GET",link,true);
}
else
{
if (query.substr(0, 1) != "?")
{
xmlhttp.open("GET",link+"?"+query,true);
}
else
{
xmlhttp.open("GET",link+query,true);
}
}
xmlhttp.send();
}
** Solution by Deukalion **
var content = xmlhttp.responseText;
if (id != null)
{
document.getElementById(id).innerHTML=content;
var script = content.match("<script[^>]*>[^<]*</script>");
if (script != null)
{
script = script.toString().replace('<script type="text/javascript">', '');
script = script.replace('</script>', '');
eval(script);
}
}
and on certain events, I had to within the script addevent listeners instead of just making a "select onchange='executeFunctionNotIncludedInAjaxFile();'" I had to addEventListener("change", functionName, false) for this. In the script that is being evaluated.
When you update your page by doing something like setting a container's innerHTML to some updated content, the browser simply will not run the scripts in it. You can locate the <script> tags, get their innerHTML (IE may prefer innerTEXT), and then eval() the scripts yourself (which is pretty much what jQuery does, though it finds the scripts with a regex before updating the DOM).
Use this function:
function parseScript(_source) {
var source = _source;
var scripts = new Array();
// Strip out tags
while(source.indexOf("<script") > -1 || source.indexOf("</script") > -1) {
var s = source.indexOf("<script");
var s_e = source.indexOf(">", s);
var e = source.indexOf("</script", s);
var e_e = source.indexOf(">", e);
// Add to scripts array
scripts.push(source.substring(s_e+1, e));
// Strip from source
source = source.substring(0, s) + source.substring(e_e+1);
}
// Loop through every script collected and eval it
for(var i=0; i<scripts.length; i++) {
try {
eval(scripts[i]);
}
catch(ex) {
// do what you want here when a script fails
}
}
// Return the cleaned source
return source;
}
then do parseScript(xmlhttp.responseText); when you're replacing/adding content.
In case some other people stumble upon this old thread, there is one issue with the accepted answer by Deukalion, there is one issue that may have been overlooked: as written, the script only looks for the first script tag. If multiple script tags exist, all others are overlooked.
A few minor tweaks would resolve the issue. Change one line from:
var script = content.match("<script[^>]*>[^<]*</script>");
To:
var script = content.match(/<script[^>]*>[^<]*<\/script>/g);
And another from:
script = script.toString().replace('<script type="text/javascript">', '');
To:
script = script.join("").replace(/<script type="text\/javascript">/g, '');
Now it will gather all the <script> code and execute them in the order found on the page. Otherwise it was an excellent solution.
After the AJAX request, you can make an "on success" function which can take the returned html and do something with it. Then something will be executed.
If there was a code example, then I could provide a code solution to the situation. But using just standard xmlhttprequest, the following could be done:
xhr = new XMLHttpRequest();
xhr.open("GET","ajax_info.txt",true);
xhr.onreadystatechange=function()
{
if (xhr.readyState==4 && xhr.status==200)
{
document.getElementById("myDiv").innerHTML = xhr.responseText;
}
}
xhr.send();
​

Categories