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.
Related
If I have a list of elements, and via javascript the user moves the elements in another order, can I, after each move, launch a php code (like a php page) but without having to call it in the browser?
Create an XmlHttpObject for the URL, send() it, check results to see if the call was successful, and discard the responseText. As an example, suppose you have the new order in a variable testUrl, e.g., "http://domain.com/script.php?order=1,4,3,2"
var xmlHttpObject = new XMLHttpRequest();
xmlHttpObject.open("GET", testUrl, false);
xmlHttpObject.send();
var xmlText = xmlHttpObject.responseText;
if (xmlText == 'Success')
// do nothing
else
alert (xmlText);
An addition to the above answer - for the sake of posterity, in case someone has to debug your code some day :) I use the following function call to get that object: (I believe it makes the JS more readable and portable). You can check the return value and if null, alert the user that AJAX is not supported by the browser.
function getXmlHttpObject () {
var xmlHttpObject = null;
try {
xmlHttpObject = new XMLHttpRequest();
} catch (ex) {
try {
xmlHttpObject = new ActiveXObject('Msxml2.XMLHTTP');
} catch (ex) {
xmlHttpObject = new ActiveXObject('Microsoft.XMLHTTP');
}
}
return xmlHttpObject;
}
I'm trying to to use Javascript to update the innerHTML of a webpage after an onclick event. My Javascript (java.js) uses this code to access a PHP page which echoes back the text that goes in the innerHTML. The thing is, I want to update the innerHTML of two items (a "color" table and an "item" table) which are not located next to each other and have different element ID's. Each call from java.js works fine individually (like if one is commented out), but when both of them are run, whichever one is first will get stuck on the "loading" message and the second one will work. Loading "content.php?item='5'&color='5'" in a web browser shows both tables.
I suspect this is something to do with the mechanics of $_GET[] (which I don't totally understand; this is my first time working with PHP). But the calls should happen sequentially and the keys ('item' and 'color') don't conflict, so I can't figure out what's going wrong.
java.js:
function makeActive(active_tab) {
//item table
callAHAH('content.php?item='+active_tab, 'item', 'getting items for tab '+active_tab+'. Wait...', 'Error');
//color table
callAHAH('content.php?color='+active_tab, 'color', 'getting colors for tab '+active_tab+'. Wait...', 'Error');
}
content.php:
if (isset($_GET['color'])) {
require 'color.php';
$index = 1*$_GET['color'];
$arr = $ITEM_TYPES[$index];
echoColorTable($arr); //makes table in color.php
} else {
echo "color not set "; //debug
}
if (isset($_GET['item'])) {
require 'item.php';
$index = 1*$_GET['item'];
echoItemTable($index); //makes table in item.php
} else {
echo "item not set "; //debug
}
The problem is with the callAHAH function you linked to. It doesn't have a var keyword when it declares req. So it is a global variable and there can only ever be one request at once. It also reuses that global variable in the responseAHAH function. In general global variables are a bad idea for reasons like this. I recommend ditching the callAHAH function altogether and using something like this which does the exact same thing without using a global variable:
function loadInto(url, id, loading, error) {
var ajax;
var el = document.getElementById(id);
el.innerHTML = loading;
if (typeof XMLHttpRequest !== 'undefined')
ajax = new XMLHttpRequest();
else // Some people still support IE 6
ajax = new ActiveXObject("Microsoft.XMLHTTP");
ajax.onreadystatechange = function(){
if(ajax.readyState === 4){
if(ajax.status == 200){
el.innerHTML = ajax.responseText;
}else{
el.innerHTML = error;
}
}
};
ajax.open('GET', url);
ajax.send();
}
It's also not named callAHAH, and that's always a plus.
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 comments board on my page, to which I load different topics according to the page the user is on with XMLHttpRequest in a changeTopic() function. I originally had this at the end of my submit form php:
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_POST['page']);
The problem is that I don't want to refresh the whole page, only the DIV that contains the messages. I tried running the changeTopic() function by inserting it inside script tags with echo. For one, I couldn't get .$_GET['topic']. working inside echo even if I made a variable of it first, but also I tried running the function by hard inserting one of the possible values with the following results:
1) While the messages section refreshed right, I lost the form as it's contained in the index.html while I only load the messages from an external gettopic.php with query string.
2) I got a weird result where I lost an external file that was loaded into a completely different div altogether. This file changes the hash of the main page, which is checked with every refresh and the right file is loaded according the hash, so using the whole page refresh never resulted in this.
// EDIT
function changeTopic(topic) {
if (topic=="") {
document.getElementById("messagelist").innerHTML="";
return;
}
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("messagelist").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("POST", "gettopic.php?t="+topic,true);
xmlhttp.send();
}
The main application on my page is a SVG map which I've done with RaphaelJS. The user can load information pages into another div 'info' from this SVG map. The pages are loaded with a similar function which in addition changes the #hash and runs the changeTopic() as well to change the message board so people can have a conversation about each topic.
The PHP form takes the normal filled info as well as the hidden 'pageid' which is set by the current page the user is browsing, and sends it to the database. The different messages are sorted by this pageid so the changeTopic() function only brings the right messages: gettopic.php?t=topic ('pageid').
After submitting the form I'd like only the messagespart to refresh and the form to clear. At the moment it's either a whole page refresh (user looses their position on the SVG map) or partial refresh where I lose the form (get a blank spot instead) and that weird information-page missing.
you can do something like this:
var ajaxfoo = function(obj) {
var xmlHttp = null;
try {
xmlHttp = new XMLHttpRequest();
}catch(e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e) {
xmlHttp = null;
}
}
}if (xmlHttp) {
obj.method = obj.method.toUpperCase();
xmlHttp.open(obj.method, obj.url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
if(obj.method == 'POST') {
if(typeof(obj.params) != 'undefined') {
xmlHttp.setRequestHeader("Content-length", obj.params.length);
}
}
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
var json = eval(xmlHttp.responseText);
if(json.success) {
if(typeof(obj.success) == 'function'){obj.success(xmlHttp.responseText);}
}
else {
if(typeof(obj.failure) == 'function') {obj.failure(xmlHttp.responseText);}
}
}
};
if(obj.method == 'POST' && typeof(obj.params) != 'undefined') {
xmlHttp.send(obj.params);
}
else {
xmlHttp.send(null);
}
}
};
function callfoo(topicname) {
ajaxfoo({
method: 'GET',
url: 'gettopic.php?t='+topicname,
success: function(response) {
var json = eval(response);
alert('success callback function! '+json.data);
},
failure: function(response) {
var json = eval(response);
alert('failure callback function! '+json.data);
}
});
}
and in
success: function(response) {
var json = eval(response);
alert('success callback function! '+json.data);
},
you can add your innerHTML stuff :)
the gettopic.php
should then echo something like:
{success: true, data: [{id: 1, "title": "test title", "description": "moo"},{id: 2, "title": "test title", "description": "moo"},{id: 3, "title": "test title", "description": "moo"}]}
And the you can access this by calling
json.data[0].title
json.data[1].title
json.data[2].title
json.data[0].description
...
so you can simply build your innerHTML stuff by doing something like
doc....innerHTML = '<h2>'+json.data[0].title+'</h2>';
Use jQuery - great tool. It could look like
$(function(){
//when you want to reload your div, just put this line
$("#div_element").load('your_new_page.php');
});
and that's it !
I'm quite confused about what you are doing, but XMLHttpRequest should be the one running changeTopic() in the readystatechange handler.
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.