I have a main page, call it Main.php. On this page, is a button that when clicked, sets a div's innerHTML (already on Main.php, called divResults) with the results from Results.php.
When Results.php is called, the returned HTML "These Are The Results" is properly received and set as the contents to divResults on Main.php. However, any javascript from Results.php is not executed. As an example, I attempt to do a simple window.alert. Here is example code:
Main.php link button to begin the action:
<img src="$MyImageSource" onclick=\"ExpandDropdownDiv()\" />
Main.php javascript function ExpandDropdownDiv():
function ExpandDropdownDiv(){
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("divResults").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","Results.php",true);
xmlhttp.send();
}
Results.php code example:
<script type="text/javascript">
alert("Success");
</script>
These Are The Results
------------------ Edit - Update ------------------
The simple alert, from Results.php is just an example. If I were able to get this to work, I believe I could solve the rest of my problem on my own. However, I noticed a few comments suggesting to just place the alert in Main.php's javascript after i set the div's innerHTML. So, let me explain what I truly want to do with the javascript, after the div is set.
Image 1, shows some normal "Select" html elements, that have been transformed using jquery and the dropdown-check-list extension (.js). When the user clicks the colorful down arrow at the bottom, the div expands, (image 2) and two more "Select" elements are generated within this other .php file... the html is returned, and placed in the div. Thus, i do not need to reload the entire page, and can place the new select dropdowns just beneath the existing ones.
The problem is, to "transform" these normal select elements, there is some javascript that needs to be executed against that HTML:
$(document).ready(function() {
$(".MultiSelect").dropdownchecklist( {firstItemChecksAll: true, maxDropHeight: 300 , searchTextbox: true, width: 100, textFormatFunction: function(options) {
var selectedOptions = options.filter(":selected");
var countOfSelected = selectedOptions.size();
var size = options.size();
switch(countOfSelected) {
case 0: return "All";
case 1: return selectedOptions.text();
/* case size: return "All"; */
default: return countOfSelected + " selected";
}
}
}
);
}
So, somehow I need to be able to execute javascript against the HTML that is generated from this other .php file. And simply calling the above code, after my divs innerHTML is filled, only re-generates the already existing dropdowns, not the two new ones.
Example Images
Here is a good read on understanding what you are doing: Eval embed JavaScript Ajax: YUI style
Making your code work with using eval(); but its not recommend for various reasons:
Let's take your php and modify it like this:
<script type="text/javascript">
function result() {
alert("Success");
}
</script>
These Are The Results
and This is the callback function from AJAX. result(); is not executed because it doesn't get evaluated, and thus does not exist. which is in your case
if (xmlhttp.readyState==4)/* && xmlhttp.status==200) */
{
document.getElementById("divResults").innerHTML=xmlhttp.responseText;
result(); // this function is embedded in the responseText
// and doesn't get evaluated. I.e. it doesn't exist
}
in order for the browser to recognize the result(); you must do an eval(); on all the JavaScript statements with in the script tags that you injected into the div with id divResults:
if (xmlhttp.readyState==4)/* && xmlhttp.status==200) */
{
document.getElementById("divResults").innerHTML=xmlhttp.responseText;
var myDiv = document.getElementById("divResults");
var myscripz = myDiv.getElementsByTagName('script');
for(var i=myscripz.length; i--;){
eval(myscripz[i].innerHTML);
}
result(); //alerts success
}
Easy Way:
The easiest way i would do it is basically remove the JavaScript from the php and display the content, and after callback just do the rest of the JavaScript within the callback function
php:
echo 'These Are The Results';
JavaScript:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4)/* && xmlhttp.status==200) */
{
document.getElementById("divResults").innerHTML=xmlhttp.responseText;
alert('success'); // or whatever else JavaScript you need to do
}
}
try to wrap the javascript code from Result.php in a function and call it after inserting it like :
<script type="text/javascript">
function result() {
alert("Success");
}
</script>
These Are The Results
and
if (xmlhttp.readyState==4)/* && xmlhttp.status==200) */
{
document.getElementById("divResults").innerHTML=xmlhttp.responseText;
if(result) result();
}
Your results.php needs to be something like...
echo 'eval("function results() { alert(\'success\'); }");';
And then call the results function.
Related
I am trying the following code to update external content inside a div named "content1"
ajax.js:
var ajaxdestination="";
function getdata(what,where) { // get data from source (what)
try {
xmlhttp = window.XMLHttpRequest?new XMLHttpRequest():
new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) { /* do nothing */ }
document.getElementById(where).innerHTML ="<center><img src='loading.gif'></center>"; // Define the destination DIV id, must be stored in global variable (ajaxdestination)
ajaxdestination=where;
xmlhttp.onreadystatechange = triggered; // when request finished, call the function to put result to destination DIV
xmlhttp.open("GET", what);
xmlhttp.send(null);
return false;
}
function triggered() { // put data returned by requested URL to selected DIV
if (xmlhttp.readyState == 4) if (xmlhttp.status == 200)
document.getElementById(ajaxdestination).innerHTML =xmlhttp.responseText;
}
Inside my div I include 'page1a.php' with php, wich outputs a value from my database and contains a link to 'code1a.php' where I have a php code that updates this value. (This is just a test and will do more than update a value in the future).
update value
Inside code1a.php where I have a php code that updates my database, after the database has been updated, is there a way to update my div (content1) with 'page1a.php' again?
I have tried everything i could think of and search the web for a few days, but not found a solution to my problem.
The script can be found on: http://www.battrewebbsida.se/index2.php
There are many variants to do this, your solution isn't best to do it, but here's the modified your javascript code, which is that what you want.
By Javascript
var ajaxdestination="";
var tmpcache = '';
function getdata(what,where) { // get data from source (what)
try {
xmlhttp = window.XMLHttpRequest?new XMLHttpRequest():
new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) { /* do nothing */ }
tmpcache = document.getElementById(where).innerHTML;
document.getElementById(where).innerHTML ="<center><img src='loading.gif'></center>"; // Define the destination DIV id, must be stored in global variable (ajaxdestination)
ajaxdestination=where;
xmlhttp.onreadystatechange = triggered; // when request finished, call the function to put result to destination DIV
xmlhttp.open("GET", what);
xmlhttp.send(null);
return false;
}
function triggered() { // put data returned by requested URL to selected DIV
if (xmlhttp.readyState == 4) if (xmlhttp.status == 200)
document.getElementById(ajaxdestination).innerHTML =tmpcache;
}
By PHP
after doing your updates in 'code1a.php' send header location to your first 'page1a.php' file
header("Location: ".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'/page1a.php');
NOTE: dont forget about ob_start() at the top of script.
I have been working on this code for a while and I am finally stumped and cannot figure out what the heck to do to get this issue fixed.
I have a jquery code that works beautifully for the get profile, but when i need to return the values in a div, it only shows the first profile of the user, but if a user posts more then once on the blog, it will not show the profile information. I have tried to append more information for each profile div to be different, but its still not working.
Here is the jQuery code for the GET user profile and return response.
function showUser(str)
{
var profileDiv = document.getElementById("profile_"+ str);
if (str=="")
{
return;
}
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)
{
profileDiv.innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","getuser.php?q="+str,true);
xmlhttp.send();
}
Also here is the PHP script that i am using to pass the information
"<div id=\"info\" onmouseover=\"showUser(" .$blogrow['id_user'].")\"><imgalign= \"left\" style=\"vertical-align:top;\" class=\"imgb\" height=\"41\" width=\"41\" src=\"profilepics/".$blogrow['pic']."\" />".$blogrow['author']." <br>".$blogrow['timestamp']."<br></div><br>";
echo "</div>";
here is the div part as well that stores the information
echo "<div id=\"txtHint\"><div id=\"profile_".$blogrow['id_user']."\"></div></div>";
The problem relies on your HTML markup, which is invalid. Element ids must be unique in a HTML page but I see a lot of repeated ids such as #info, #theDiv, #txtHint and #profile_X
A quick fix for your problem would be to change all those and any other repeating ids to a class and then use the ajax code provided by #Rohan Kumar but using a class selector to append the content to every mention of the user in the page
function showUser(str)
{
$.ajax({
url:'getuser.php',
data:{q:str},
type:'GET',
success:function(data){
$(".profile_"+ str).html(data);
}
});
}
This is definitely not the most efficient or elegant solution but I think it would work. If you were to try and improve your code I would suggest binding all divs of class .info to a mouseenter handler, using data-attributes to get the user id and maybe maintaining a list of the profiles retrieved so you don't end up making redundant calls to your php
Using $.ajax it will more simple like,
function showUser(str)
{
$.ajax({
url:'getuser.php',
data:{q:str},
type:'GET',
success:function(data){
$("#profile_"+ str).html(data);
}
});
}
But, before this you need to add any version of jQuery
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...
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();
I have a little script which uses AJAX and PHP to display an image. You can see below that if I call the function mom() it looks in the PHP file index.php?i=mom and displays the image I'm looking for.
But I need the javascript to be lighter as I have 30 images and for each one I have to modify and copy the script below. Is there not a simpler way to have the functions be different and still call a different page?
<script type="text/javascript">
function mom()
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
HandleResponse(xmlHttp.responseText);
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
function HandleResponse(response)
{
document.getElementById('mom').innerHTML = response;
}
</script>
My Trigger is this
<a href="#" onclick='mom();' />Mom</a>
<div id='mom'></div>
You could modify your function so it takes a parameter :
// The function receives the value it should pass to the server
function my_func(param)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
// Pass the received value to the handler
HandleResponse(param, xmlHttp.responseText);
}
}
// Send to the server the value that was passed as a parameter
xmlHttp.open("GET", "index.php?i=" + param, true);
xmlHttp.send(null);
}
And, of course, use that parameter in the second function :
function HandleResponse(param, response)
{
// The handler gets the param too -- and, so, knows where to inject the response
document.getElementById(param).innerHTML = response;
}
And modify your HTML so the function is called with the right parameter :
<!-- for this first call, you'll want the function to work on 'mom' -->
<a href="#" onclick="my_func('mom');" />Mom</a>
<div id='mom'></div>
<!-- for this secondcall, you'll want the function to work on 'blah' -->
<a href="#" onclick="my_func('blah');" />Blah</a>
<div id='blah'></div>
This should work (if I understand correctly)
<script type="text/javascript">
function func(imgName)
{
var xmlHttp = getXMLHttp();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4)
{
document.getElementById(imgName).innerHTML =
}
}
xmlHttp.open("GET", "index.php?i=mom", true);
xmlHttp.send(null);
}
</script>
MARTIN's solution will work perfectly.
By the way you should use some javascript framework for Ajax handling like jQuery.
It will make your life easy.
If you are having light weight images you preload the images on your page.
I solved this by making an array of in your case xmlHttp and a global variable, so it increments for each request. Then if you repeatedly make calls to the same thing (eg it returns online users, or, whatever) then you can actually resubmit using the same element of the array too.
Added example code:
To convert it to a reoccuring event, make a copy of these 2, and in the got data call, just resubmit using reget
var req_fifo=Array();
var eleID=Array();
var i=0;
function GetAsyncData(myid,url) {
eleID[i]=myid;
if (window.XMLHttpRequest)
{
req_fifo[i] = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
req_fifo[i] = new ActiveXObject("Microsoft.XMLHTTP");
}
req_fifo[i].abort();
req_fifo[i].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(i);
req_fifo[i].open("GET", url, true);
req_fifo[i].send(null);
i++;
}
function GotAsyncData(id) {
if (req_fifo[id].readyState != 4 || req_fifo[id].status != 200) {
return;
}
document.getElementById(eleID[id]).innerHTML=
req_fifo[id].responseText;
req_fifo[id]=null;
eleID[id]=null;
return;
}
function reget(id) {
myid=eleID[id];
url=urlID[id];
req_fifo[id].abort();
req_fifo[id].onreadystatechange = function(index){ return function() { GotAsyncData(index); }; }(id);
req_fifo[id].open("GET", url, true);
req_fifo[id].send(null);
}
The suggestions to parameterize your function are correct and would allow you to avoid repeating code.
the jQuery library is also worth considering. http://jquery.com
If you use jQuery, each ajax call would literally be this easy.
$('#mom').load('/index.php?i=mom');
And you could wrap it up as follows if you'd like, since you say you'll be using it many times (and that you want it done when a link is clicked)
function doAjax(imgForAjax) { $('#'+imgForAjax).load('/index.php&i='+imgForAjax);}
doAjax('mom');
It makes the oft-repeated ajax patterns much simpler, and handles the issues between different browsers just as I presume your getXMLhttp function does.
At the website I linked above you can download the library's single 29kb file so you can use it on your pages with a simple <script src='jquery.min.js'></script> There is also a lot of great documentaiton. jQuery is pretty popular and you'll see it has a lot of questions and stuff on SO. ajax is just one of many things that jQuery library/framework (idk the preferred term) can help with.