I am making a little script to change website language using PHP and Ajax/jQuery. I want page content to refresh without reloading page. Until now i have made this
$( "a[data-request]" ).click(function() {
var xhr = new XMLHttpRequest();
var request = $(this).attr('data-request');
var what = $(this).attr('data-to');
xhr.open('GET', '{{ site_url }}' + what + '/' + request);
xhr.onload = function() {
if (xhr.status === 200) {
$("#body").load(location.href + " #body");
}
};
xhr.send();
});
When i click on link
<a data-request="english" data-to="home/language" href="#">
It succesfuly performs uri request in background and "reloads" #body element, which is whole body
<body id="body">
However instead of reloading whole page content just disappear and wont reappear again. What am i doing wrong?
Replace xhr.onload because it's not implemented in all browsers, use onreadystatechange instead
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200;
if (xhr.readyState === DONE) {
if (xhr.status === OK)
$("html").html(xhr.response);
}
};
xhr.open('GET', '{{ site_url }}' + what + '/' + request); //<-- note must come after above event handler
note : this would wipe your button too(one you clicked to fetch the page).so instead of body load that data in some div.
EDIT
I suppose your code is something like this
$(document).ready(function(){
$(langDropdown).change(function(){
//get selected language
//do ajax
});
});
Now suppose you change lang. to Spanish server sends you a Spanish version so what you get from server is bit like
<html>
<head> ....title.....
<script src=....></script> //common libs like jquery etc
<script src=my.js></script> //this would be js contaning above code
</head>
<body>
Esta es una pagina
</body>
</html>
Now when you use document.write to put the Italian page the document.ready won't get called(why? because it gets called only on actual page refresh) so change event handlers wont get bound on lang. selection dropdown
Solution:
code outside document.ready will definitely run even when fetched through ajax, but i won't advise that , rather what i would advise is whatever code you want to run on ajax completion (like event binding) write it after document.write is success callback/readyState
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200;
if (xhr.readyState === DONE && xhr.status === OK) {
$("html").html(xhr.response);
$(langDropdown).change(function(){
//binding code
});
}
};
Related
I am loading a page through xmlHttpRequest and I am not getting one variable which come into existance after some miliseconds when page loading is done
so the problem is when xmlHttpRequest sends back the response I do not get that variable in it.
I want it to respond back even after onload.
var xhr = new XMLHttpRequest();
xhr.open("GET", event.url, true);
xhr.onload = function() {
callback(xhr.responseText);
};
xhr.onerror = function() { callback(); };
xhr.followRedirects = true;
xhr.send();
I tried setTimeOut but of no use because may be at that time call is finished
xhr.onload = function() {
console.log('wait for response');
setTimeout(function(){
callback(xhr.responseText);
},2000);
};
I tried readyStateChange , but no success
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
callback(xhr.responseText);
};
};
by the way, I am trying to load amazon signIn page
and the variable which is missing everytime is hidden Input Field metadata1,
I get all other hidden Input fields in response text , except input field, named "metadat1"
I'll be more than Happy, If anyone can help.
Thanks in advance
ohh Finally I did it,
I din't read any javascript, Instead I just extracted scripts which I received in xhr calls and executed it inside a hidden div, and here it is , I got that variable's value
abc(xhr.responseText);
function abc(xhrRes){
var dynamicElement = document.createElement('div');
dynamicElement.setAttribute("id", "xhrdiv");
dynamicElement.setAttribute("style", "display: none;");
dynamicElement.innerHTML = xhrRes;
document.body.appendChild(dynamicElement);
var scr = document.getElementById('xhrdiv').getElementsByTagName("script");
//5 scripts needed to generate the variable
for(i=0;i<5;i++){
eval(scr[i].innerHTML);
if( i+1 == 5){
var response = document.getElementById('xhrdiv').innerHTML;
return response; //and in this response variable I have every thing I needed from that page which I called through xmlhttp Req
}
}
}
---------------------Improved Version-----------------------
Instead of executing script through eval,
keep script content in a file AND Include it, as we normally include the script, that works better.
xhrRes = xhr.responseText;
var dynamicElement = document.createElement('div');
dynamicElement.setAttribute("id", "xhrDiv");
dynamicElement.setAttribute("style", "display: none;");
dynamicElement.innerHTML = xhrRes;
document.body.appendChild(dynamicElement);
var xhrDiv = document.getElementById('xhrDiv');
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = JSfile;
xhrDiv.appendChild(newScript);
(it shows the edit is done my anonymous user, :( because I forgot to Login, while editing)
If the data doesn't exist until some time after the page has loaded then, presumably, it is being generated by JavaScript.
If you request the URL with XMLHttpRequest then you will get the source code of that page in the response. You will not get the generated DOM after it has been manipulated by JavaScript.
You need to read the JavaScript on the page you are requesting, work out how it is generating the data you want to read, and then replicate what it does with your own code.
I have a simple javascript html file that I am using to perform a function that is called from menu item that I added to the Internet Explorer default context menu (through windows registry). The menu click triggers the following javascript:
<script type="text/javascript">
var req = new ActiveXObject("Microsoft.XMLHTTP")
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
var serverResponse = req.responseText;
alert(serverResponse); // Shows "15"
}
}
};
req.open("POST", "https://www.googleapis.com/urlshortener/v1/url?key=myAPIkey", true)
req.setRequestHeader("Content-Type","application/json")
req.send('{"longUrl": "https://bing.com"}')
</script>
If I run this by opening the html file in IE it works fine. I get the response text. However, if I load it through the Context Menu the "onreadystatechange" function is never called.
If I add "alert("test") to the end of my script the test alert pops up followed a fraction of a second later by the serverResponse alert. I assume it has something to do with the alert blocking or forcing the browser to do something but I can't figure out why it works when loaded as a page but not through the Context menu.
I should note that the rest of the script DOES get called, so I know the menu item is working.
EDIT:
The above code snippet runs and displays an alert dialog containing the text of the response from the server whenever it's executed as an html page. If executed through the context menu I never get the "alert(serverResponse)".
However the following version does work when called from the context menu:
<script type="text/javascript">
var req = new ActiveXObject("Microsoft.XMLHTTP")
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
var serverResponse = req.responseText;
alert(serverResponse); // Shows "15"
}
}
};
req.open("POST", "https://www.googleapis.com/urlshortener/v1/url?key=myAPIkey", true)
req.setRequestHeader("Content-Type","application/json")
req.send('{"longUrl": "https://bing.com"}')
alert("test")
</script>
The only difference is the inclusion of the "alert("Test")" line at the end
i wanna know can ajax call triggering onload event on the targeted page?
so it's like this, i have one page (test.html) with simple function to change the content of a div that will run when the page load...
here is the code :
<body onLoad = "a()">
<div id="main">the result is here</div>
</body>
<script>
function a()
{
document.getElementById("main").innerHTML =
"Success";
}
</script>
and i have another page (call.html) with ajax call targeted test.html and show the result inside the div...
here is the code :
<body>
<button onclick="call()">Click</button>
<div id="box"></div>
</body>
<script>
function call()
{
var xmlhttp = new XMLHttpRequest();
var url = "test.html";
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("box").innerHTML =
xmlhttp.responseText;
alert("Success");
}
}
xmlhttp.send();
}
</script>
if i just simply load the test.html, the content inside div will change, but if i use call.html to call that page, the inside won't change...
is this because ajax doesn't trigger function inside onload event?
This is happening because you are trying to open a URL from local i.e. using file:// and not via HTTP or HTTPS.
This thread can give you a better insight on how to proceed further.
I want to load a page from another domain to a div element in my page. I'm using CORS and it works since it shows the file is loaded in console log but I cannot manage to add it to my div.
Here's my code to make it more clear:
<script type="text/javascript">
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest !== "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://localhost:8080/test/header.xhtml");
if (request){
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 400) {
var hpage = request.responseText;
document.getElementById("theader").innerHTML = hpage;
} else {
alert("An error occured! Request Status: +"request.status);
}
}
};
request.send();
}
</script>
<body>
<div id="theader"></div>
</body>
How do I display the loaded page in theader div?
UPDATE
I found out that this happens in firefox and chrome because I use localhost. It works in ie but it only loads the text without css and images. Any idea how can I load the whole page into the div?
I guess my question now will be does the page load with all resources in CORS like it does with iframe? If so how?
A div element is meant to contain only certain HTML elements: in a nutshell the elements that you can find in the body. But not all HTML elements, and in particular not a html or head element. This is why your code does not work.
To solve your problem you either need to use an iframe (but from your question it seems this is not what you want), or put the content of the body element in the div and parse the head and load it in the current head.
Something like that (not tested):
var hpage = document.createElement("html");
hpage.innerHtml = request.responseText;
//Below you might want to write more robust code
//depending on the content of the response and how much you trust it
var head = hpage.getElementsByTagName("head")[0];
var body = hpage.getElementsByTagName("body")[0];
document.getElementById("theader").innerHTML = body.innerHTML;
//Now iterates over the children of head to find
//the script and style elements, and you can append them to the head of the document
var currentHead = document.getElementsByTagName("head")[0];
var scripts = head.getElementsByTagName("script");
for (var i=0; i<scripts.length; i++) {
currentHead.appendChild(scripts[i]);
}
//same thing for style elements,
//you could even do that for all elements
//depending on what the response may contain
I am reloading a part of my page every 5 seconds with Javascript. This works fine!
However, if I add a parameter I am getting the same page without reloading.
If I open it without reloading, I am seeing the jQuery UI progress bars correctly.
If I open the reloading page, they are not shown anymore - although the script get's the unreloading site and write it into the div, so you should see them.
I am afraid this happens because they stylesheets or the jquery part is loosing his old values or is overwritten.
This is the reloading page: http://lasertra.de/table.php
This is how it should be, unreloading page: http://lasertra.de/table.php?refresh=true
Also if I am not reloading the jQuery scripts it doesn't show up correctly, if they scripts are not added in the not reloading page, it doesn't show the progress bars too, so it seems like it is needed.
I am not reloading the whole page, only the signals div which is placed in the body
function update_table()
{
var old_id = document.getElementById('number').value;
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
if(req.readyState == 4)
{
if(req.status == 200)
{
var new_table = req.responseText;
var new_id = document.getElementById('number').value;
if(new_id != old_id)
{
var someSound = soundManager.createSound({
url: 'signal.mp3'
});
someSound.play();
}
document.getElementById("signals").innerHTML = new_table;
setTimeout(update_table, 1000);
}
}
}
var link = "table.php?refresh=true";
req.open("GET", link, false);
req.send();
}