I'm trying to have a div refresh after a callback using ajax functions. Basically, I want /includes/view_game/achievements.inc.php to be reloaded in the div #achievements_tab. The callback (I didn't include it in codes below) works well and triggers the AchievementRefresh function found below (the opacity of the div changes to 0.5, but it remains like this and the refresh is not made).
Those two functions are used for another similar ajax refresh on my site that works well. So I tried to modify the code, but since it's for a slightly different purpose, maybe I have the wrong approach.
function AjaxPost(url, success_function) {
xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Your browser doesn't support AJAX. You should upgrade it!")
return
}
xmlHttp.onreadystatechange = success_function;
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
This AjaxPost function is used in the other function below:
function AchievementRefresh() {
div('achievements_tab').style.opacity = 0.5;
div('highscore_pages').innerHTML = '<img src="'+site_url+'/images/loader.gif" />';
AjaxPost(site_url+"/includes/view_game/achievements.inc.php?", '',
function () {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
)
}
Use load
$('#achievements_tab').load('/includes/view_game/achievements.inc.php');
See: http://api.jquery.com/load/
Edit
E.g.
function AchievementRefresh() {
$('#achievements_tab').css('opacity', 0.5);
$('#highscore_pages').html('<img src="'+site_url+'/images/loader.gif" />');
$('#achievements_tab').load('/includes/view_game/achievements.inc.php')
.success(function() {
$('#achievements_tab').css('opacity', 1);
});
}
Try this.
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
div('achievements_tab').innerHTML = xmlHttp.responseText;
div('achievements_tab').style.opacity = 1;
}
}
};`
Name and id is example.
Also, some changes:
AjaxPost(site_url+"/includes/view_game/achievements.inc.php");
var params= 'name'+encodeURIComponent(name)+'&id='+encodeURIComponent(id)
Parameters shouldn't be in URL.
xmlhttp.send(params);
Related
Having this API:
http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1
How can I write using pure JS request that downloads me different data after button click event?
All I get from this code is the same quote all the time:
function getQuote (cb) {
var xmlhttp = new XMLHttpRequest();
var quoteURL = "http://quotesondesign.com/wp-json/posts?filter[orderby]=rand"
xmlhttp.onreadystatechange = function() {
if (xmlhttp.status == 200 && this.readyState==4) {
cb(this.responseText);
}
};
xmlhttp.open("GET", quoteURL, true);
xmlhttp.send();
}
document.querySelector('button').addEventListener("click", function() {
getQuote(function(quote) {
console.log(quote);
});
})
I tried xmlhttp.abort() and stuff but it didnt want to cooperate.
Thanks in advance!
Your response is being cached by the browser. A common trick to avoid this is to perform a request to
http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&r={random_number}
Notice how the r={random_number} will make the URL different each time.
This is a caching problem. Add a timestamp as a query parameter and you should be able to bust the cache.
Is there a way that I can run a function then call window.location.reload() to refresh the page? Currently when I do this the page is refreshing but the function isn't running.
function postComment() {
var name;
if (document.getElementById("yourName").value == "") {
name = "(Anonymous)";
} else {
name = document.getElementById("yourName").value;
}
var uri = "http://tgg.tcs.com/AP/Open/Service.svc/comment?name=" + name;
var xhr = new XMLHttpRequest();
xhr.open("POST", uri, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8")
xhr.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(JSON.stringify(document.getElementById("comment").value));
}
You need to use a callback
function yourFunction(arg, callback) {
doSomeStuff(arg);
callback();
}
yourFunction('argument', window.location.reload);
If doSomeStuff function is async, you have to do
function yourFunction(arg, callback) {
doSomeStuff(arg, callback);
}
yourFunction('argument', window.location.reload);
also, if you refresh the page, you will refresh the scripts as well, so it depends on what does your function do, you may need a cookie if the data the function generates has to be persistant
I understand that jQuery will not run when the DOM content is being loaded via AJAX. But I'm confused as to the reason why. My understanding was that the DOM elements didn't exist at the time the jQuery was initiated therefore it won't find the correct IDs or classes.
But I have a situation where the jQuery is only called AFTER all the content has been loaded via AJAX. yet it still does not work.
Here is my code. I am trying to get the function decorateGains() to run after AJAX completes.
loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type){
var xmlhttp;
if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}
else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200){document.getElementById("home-table").innerHTML=xmlhttp.responseText;}
}
xmlhttp.open("GET","actions/get-data-"+type+".php",true);
xmlhttp.send();
decorateGains();
}
You can see that I am including a call to the function decorateGains() right at the end of the loadData() function.
The decorateGains() function does run, as I can see my console message. However it does not do the task that it should.
function decorateGains() {
console.log('here');
$(".gains").each(function() {
var num = +($(this).text());
if (num > 0) {
console.log('here');
$(this).addClass("positive");
}
if (num < 0) {
console.log('here');
$(this).addClass("negative");
}
});
}
(The script searches for all elements with a class of .gains and adds a new class of positive or negative depending on the content of the element. Essentially it decorates the .gains element to be red or green depending on whether the number is negative or positive).
This is because the AJAX call is asynchronous. The request has not been completed (and therefore the new content has not been appended to the DOM) when you call your decorateGains() function. You need to place the call to the function inside the onreadystatechange handler, after setting the innerHTML:
loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("home-table").innerHTML = xmlhttp.responseText;
decorateGains(); // <-- move this in here
}
}
xmlhttp.open("GET", "actions/get-data-" + type + ".php", true);
xmlhttp.send();
}
Now, I have a problem with the ajax call which is when the web page is loaded, in the onload event of body, I assign it to call the functions which are startCount() and updateTable() this two functions contain the code that use ajax call to get the data from DB on the server side. The problem is when the ajax return it will return only one call and another call does not response. Please help me what happen and how I can slove it.
This is the onload in the body
<body onLoad="setAjaxConnection();startCount();updateTable()">
I use the XMLHttpRequest with the normal javascript, I do not use jQuery....
Use javascript closures. This link may help
http://dev.fyicenter.com/Interview-Questions/AJAX/How_do_I_handle_concurrent_AJAX_requests_.html
function AJAXInteraction(url, callback) {
var req = init();
req.onreadystatechange = processRequest;
function init() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
function processRequest () {
if (req.readyState == 4) {
if (req.status == 200) {
if (callback) callback(req.responseXML);
}
}
}
this.doGet = function() {
req.open("GET", url, true);
req.send(null);
}
this.doPost = function(body) {
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send(body);
}
}
function startCount() {
var ai = new AJAXInteraction("/path/to/count.php", function(){alert("After startCount");});
ai.doGet();
}
function updateTable() {
var ai = new AJAXInteraction("/path/to/update.php", function(){alert("After updateTable");});
ai.doGet();
}
Have the 'onSuccess' of one call initiate the next ajax call. So you would call startCount() and when that returns you fire off updateTable().
function setAjaxConnection(){
//call Ajax here
setAjaxConnectionResponce;
}
function setAjaxConnectionResponce(){
//on readystate==4
startCount();
}
function startCount(){
// code for count
updateTable();
}
function updateTable(){
// code for update
}
<body onLoad="setAjaxConnection();">
I have a bunch of divs with weird id and each of them contains a video. They're actually video embed codes but they're not usual to me. Here's one example:
<div id="evp-1fae4e37639894816f03591bc7009c68-wrap" class="evp-video-wrap"></div><script type="text/javascript" src="http://domain.com/evp/framework.php?div_id=evp-1fae4e37639894816f03591bc7009c68&id=cmVsYXRpb25zaGlwLW1hcmtldGluZy0xLmZsdg%3D%3D&v=1278525356"></script><script type="text/javascript">_evpInit('cmVsYXRpb25zaGlwLW1hcmtldGluZy0xLmZsdg==');</script>
What I want to do is create a video playlist. As a part of that, I created list using divs also which use the onclick attribute to trigger my JS function to switch between videos. Here's how it looks:
<div class="vid-list" onclick="switchvideo('http://domain.com/html-vids/headline-vids/second-vid.html', 2)"><p>This a video tutorial for blah blah blah.</p></div>
The problem is, each time I switch to another video the div id of the embed code changes also because otherwise it won't work. So I need to change that before loading the video script inside the div. I tried to achieve that using the following JS function:
function switchvideo(url, vidnumber)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",url,false);
xmlhttp.send();
}
var div_node = document.getElementByClass('evp-video-wrap');
if ( vidnumber == 2 ) {
div_node.id = 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap';
}
document.getElementById(div_node.id).innerHTML=xmlhttp.responseText;
}
Apparently it's not working. I suspect the problem are the lines in bold above. I tried to get the element by 'class' and its id by using 'div_node.id'. I am assuming that by doing 'document.getElementByClass', I am getting the reference to that element so I could use it to manipulate its other attributes. But I am not sure... Could anyone pls enlighten me??
There is no getElementByClass() method. There is a getElementByClassName() but it's not available in every browser.
Here is one you can use:
// http://www.dustindiaz.com/getelementsbyclass/
function getElementsByClass(searchClass, node, tag) {
var classElements = new Array();
if (node == null) node = document;
if (tag == null) tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if (pattern.test(els[i].className)) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
Then you can call it as
getElementByClass('evp-video-wrap');
Your ajax is a bit tricky, but here is a more general one:
function getXmlHttpObject() {
var xmlHttp;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if (!xmlHttp) {
alert("Your browser does not support AJAX!");
}
return xmlHttp;
}
function ajax(url, onSuccess, onError) {
var xmlHttp = getXmlHttpObject();
xmlHttp.onreadystatechange = function() {
if (this.readyState === 4) {
// onSuccess
if (this.status === 200 && typeof onSuccess == 'function') {
onSuccess(this.responseText);
}
// onError
else if(typeof onError == 'function') {
onError();
}
}
};
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
return xmlHttp;
}
Finally your code becomes:
function switchvideo(url, vidnumber) {
var div_node = getElementByClass('evp-video-wrap')[0];
// make a call to the url, and execute the
// callback when the response is available
ajax(url, function( responseText ){
if (vidnumber == 2) {
div_node.id = 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap';
}
document.getElementById(div_node.id).innerHTML = responseText;
});
}
You can see the whole code [here]
getElementByClass isn't a standard method. Is it possible for you to use a framework for this? jQuery has a nice mechanism to search for an element by class, as do the other frameworks. It also makes it much easier to do the AJAX bits in a cross-browser supported way.
function switchvideo(url, vidnumber)
{
$.get(url, function(data) {
var div_node = $('.evp-video-wrap');
if (vidnumber == 2) {
div_node.attr('id', 'evp-78c0b7c4f6d3377954825f145734fd5c-wrap');
}
div_node.html( data );
});
}
An alternative would be to write your own getElementByClass or specific code to search for a DIV by class. Note: I assume you're only interested in the first match.
function getDivByClass( klass )
{
var regex = new RegExp( '(^|\\s+)' + klass + '(\\s+|$)' );
for (div in document.getElementsByTagName('div')) {
if (regex.text( div.className)) {
return div;
}
}
return null;
}