I have an input form which in realtime display the results from three different cgi-based lookups.
My first approach was to have three iframes which i change the .src for every search, which works but feels unnecessary:
<iframe id="iframe1">
document.getElementById("iframe1").src="/cgi-bin/one.cgi";
My second approach was having three object:s which have their .data changed, but that also feels and looks bad:
<object id="object1">
document.getElementById("object1").data="/cgi-bin/one.cgi";
Both of the above examples works - functionally, but I would like to know a better way to do it. For example how do I get the same results using DIVs ? I.e. no iframe:s or object:s.
The alternative is to use AJAX. This means that you have to create and send an XMLHttpRequest. When the response is received, you have to put it into a <div>.
Here's a minimalistic example:
var div = document.getElementById("results");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
div.innerHTML = this.responseText;
} else {
div.innerHTML = "<h1>Error " + this.status + "</h1><p>The content could not be loaded.</p>";
}
}
};
xhttp.open("GET", "/cgi-bin/one.cgi", true);
xhttp.send();
For cross-browser compatibility, I recommend to use this function or the jQuery ajax function.
Related
I'm a beginner in Javascript and i'm trying to get an element from an embed tag. This embed tag contains a pdf.
I want to get the button "next page" from the pdf viewer, and simulate a click on it, in order to automaticly scroll to the next page of the pdf.
My HTML code is something like this (really simplified) :
<html>
<body>
<div id="display-zone">
<embed id="myPdf" src="./myPdf.pdf">
#document
<html>
<body>
<!-- The button I want to get in my JavaScript -->
<button id="next" class="toolbarButton pageDown"></button>
</body>
</html>
</embed>
</div>
</body>
</html>
My JS code to print the pdf viewer on the web page :
affichage.innerHTML = "<embed class=\"media\" id=\""+ongletsMedias[i].firstChild.data+"\" src= \""+ongletsMedias[i].firstChild.data+"\" width= \"1000\" height= \"800\">";
// ongletsMedias[i].firstChild.data equals to "myPdf"
t = 5000; // time before starting pdfDefile()
setTimeout(pdfDefile,t,ongletsMedias[i].firstChild.data,i,1); //call the function to scroll pdf pages
And finally my function pdfDefile() that I'm calling in order to scroll the pdf pages :
function pdfDefile(dir,i,page) {
var xhttp = new XMLHttpRequest();
var t = 0;
xhttp.onreadystatechange = function() {
var checkbox = document.getElementById('checkbox');
if (this.readyState == 4 && this.status == 200 && checkbox.checked) {
document.getElementById("span").innerHTML = this.responseText; // display the number of pages of my pdf
var t = 5000;
if (page < parseInt(this.responseText)) { //test for recursive call
/*HERE is where I want to get the "next" button */
setTimeout(pdfDefile,t,dir,i,page+1);// recall this function while there is a next page to display
} else {
setTimeout(jouerMedia,t,i+1);// call the main fuction, no problem here
}
}
};
xhttp.open("GET", "nbPagesPDF.php?pages="+dir, true);
xhttp.send();
}
I already look at an existing topic (Get element in embed tag), but I can't make it work in my JS.
So please, can you help me to make my code great again (may it have been ;-) ) ?
Regards
Try
var embed = document.getElementById('myPdf');
// Wait for document to load inside embed element
embed.on('load', function() {
embed.getElementById('next').click();
});
(I am using jQuery in this example for adding the event listener, not sure if you are using it on your project?)
Without jQuery you could do:
var embed = document.getElementById('myPdf');
embed.onload = function() {
embed.getElementById('next').click();
};
It might be possible you can not trigger a click event on that button since a user action often must have taken place to trigger click's from js.
I have a webpage wherein I want that onclick of a link or buttonn; the content of a particular div of webpage get updated and replaced with the content which I have scripted in other html page. How to do that?
There are several ways to do that .
<script>
function loaddata()
{
var xhr = new XMLHttpRequest();
xhr.open("GET","page.html",true);
xhr.onload = function(){
if(this.readyState === 4)
{
var div = document.getElementById("divid"); // the div where you want to load the data
div.innerHTML = this.responseText;
}
}
xhr.send();
}
</script>
html code
<button onclick="loaddata()">click</button>
<div id="divid"></div>
there are other ways to do that . but i have shown only javascript one
hope this helps you what you are looking for
EDIT 2: Problem solved. The jquery pluggin created a div. I was barking up the wrong tree.
Thanks for all your swift answers! long time reader of stackoverflow but first time i've posted a question!
EDIT: So the reason why I want to change the id is to change the rating of a rating bar(I use the jrating jquery pluggin). The pluggin uses the digits in the beginning of the id to set the initial rating. Now I want to use ajax when I load a new player and that new player has a new rating that I want to update. Is this enough context?
Im at a loss here. I want to change the id of a selected div but it doesnt work!
I does seem to change the div id because document.title has the correct id when I give it the id of the div I just changed. However When I open the source code of my webpage the id didnt change...
function changePlayer() {
xmlhttp = createXHR();
xmlhttp.onreadystatechange = function () {
document.title = "onreadystatechange";
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.title = "4 and 200 is ok!";
var xmlDocument = xmlhttp.responseXML;
var playerId = xmlDocument.getElementsByTagName("id")[0].childNodes[0].nodeValue;
var playerName = xmlDocument.getElementsByTagName("firstName")[0].childNodes[0].nodeValue;
var playerlastName = xmlDocument.getElementsByTagName("lastName")[0].childNodes[0].nodeValue;
var playerTeamId = xmlDocument.getElementsByTagName("teamId")[0].childNodes[0].nodeValue;
var playerPicUrl = xmlDocument.getElementsByTagName("mainPic")[0].childNodes[0].nodeValue;
var playerShooting = xmlDocument.getElementsByTagName("shooting")[0].childNodes[0].nodeValue;
document.getElementById("playerNameAndTeam").innerHTML = "<b>" + playerName + " " + playerlastName + "</b>" + "<br>" + playerTeamId;
document.getElementById("playerPicture").src = "img/players/" + playerPicUrl;
$("[id*='_shooting']").attr("id", playerShooting / 10 + "_shooting"); //attr("id", "5.1_shooting");
document.title = $("[id*='_shooting']").attr("id");
$("[id*='_shooting']").css("background-color", "blue");
$("[id*='playerNameA']").css("background-color", "blue");
}
}
xmlhttp.open("GET", "playerPageMVC/AJAX/getInfoPlayer.php", true);
xmlhttp.send();
}
function createXHR() {
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} else { // code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
Try with Native JS like replacing this line :
$("[id*='_shooting']").attr("id",playerShooting/10 + "_shooting");
By this one :
$("[id*='_shooting']")[0].id = playerShooting/10 + "_shooting";
Caution : If $("[id*='_shooting']") match many elements, only the first will be changed.
EDIT : If you want to keep jQuery technic, depends on your version, you can try using prop(...) instead of attr(...)
when I tried changing ID with a sample code using JQuery it worked. You can view example here. Just change the id attribute
You are suppose to check the id change by inspecting element not by checking the loaded source of the web page.
If you mean your:
$("[id*='_shooting']").attr("id", playerShooting / 10 + "_shooting");
You can check that id by simply doing these:
$("[id*='_shooting']").attr("id", playerShooting / 10 + "_shooting");
alert($("#"+ playerShooting / 10 + "_shooting").attr("id"));
By viewing the source, you only view the original source, not the DOM as it exists in a current state.
Im using the below code of ajax
// JavaScript Document
function createTeam() {
var name=document.getElementById("name").value;
if(name==null || name==""){
var div3 = document.getElementById("errorMessage");
var text = "Enter Team";
div3.style.display = "block";
div3.style.color = "red";
div3.style.fontSize = "65%";
div3.innerHTML = text;
}else{
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","/TeamServlet?name="+name+"&task=create",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send();
xmlhttp.onreadystatechange= readResponse;
}
function readResponse(){
if (xmlhttp.readyState == 4)
{
response = xmlhttp.responseText;
$('#button').hide("slow");
if(response == "false"){
var div2 = document.getElementById("errorMessage");
var text = "Unable to create team.";
div2.style.display = "block";
div2.style.color = "red";
div2.style.fontSize = "65%";
div2.innerHTML = text;
}
if(response == "true"){
var div = document.getElementById("errorMessage");
var text1 = "Team created.";
div.style.display = "block";
div.style.color = "red";
div.style.fontSize = "65%";
div.innerHTML = text1;
}
}
}
}
But what happens is when I use this ajax the URL doesnt appear on the address bar of the browser.how can I achieve that? The only url that comes is that after I submit my login form, and that is this http://localhost:8080/LoginServlet?task=login
but after this,even if I navigate to other jsps/servlets none of those url come.How can I fix this ajax code?
This is the basic purpose of AJAX: do Asynchronous request, on the "background". All request done with AJAX doesn't trigger the loading icon of the browser nor change the current URL.
If you want to do something like that, you should have a look to the HTML5 History API. Because it's a huge subject, I can't show you "one" answer but I give you some resource to get in:
explanation & demo http://html5doctor.com/history-api/
explanation & demo http://dev.opera.com/articles/view/introducing-the-html5-history-api/
explanation & demo http://diveintohtml5.info/history.html
explanation & demo http://robertnyman.com/2011/08/03/html5-history-api-and-improving-end-user-experience/
demo http://html5demos.com/history
The problem you'll find is that this API is not supported in all browsers, so you'll need to use a polyfill to make your code cross-browser compatible. Here is a list of cross-browser polyfill you can use:
History.js https://github.com/browserstate/history.js
PJAX (pushState + ajax = pjax) http://pjax.heroku.com/
hashchange jQuery event http://benalman.com/projects/jquery-hashchange-plugin/
HistoryManager Mootools Plugin http://mootools.net/forge/p/historymanager/
SWFAddress http://www.asual.com/swfaddress/ & jQuery Address http://www.asual.com/jquery/address/
jQuery History Plugin https://balupton.com/projects/jquery-history
jQuery Ajaxy http://balupton.com/projects/jquery-ajaxy
Hasher https://github.com/millermedeiros/hasher/
sHistory https://github.com/tatsh/sHistory
This list is maintained by the Modernizr team, the lasted version is available at https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
Why would you want to display url of an ajax request in address bar? Ajax requests are to be performed if you want to make calls to the server without navigating away from current page. If you want to change url in address bar then you will have to redirect the user to the said url, you don't need Ajax for that.
I'm pretty new to anything AJAX and ran into the following problem. I hope someone here is able to help me out. I'm sure it's an easy fix but I just don't see it :(
What I'm trying to do is change the onmouseover and onmouseout events dynamically for the element, here are the relevant bits of code:
The HTML Element (notice there are multiple of these, hence the dynamic part of their id)
<?
if (ownsgame($id, $userid)) {?>
<a><img src="images/collection/got.gif" id="ownedimage<?=$id?>" title="<?=$itemtitle?> (<?=$platformdisplay?>) is in your collection" alt="You own this game" align="center" width="62" height="22" onclick="changeOwned('<?=$id?>')" onmouseover="changeImageSrc('ownedimage<?=$id?>', 'images/collection/del.gif')" onmouseout="changeImageSrc('ownedimage<?=$id?>', 'images/collection/got.gif')"/></a>
<? } else { ?>
<a><img src="images/collection/add.gif" id="ownedimage<?=$id?>" title="Add <?=$itemtitle?> (<?=$platformdisplay?>) to your collection" alt="You do not own this game" align="center" width="62" height="22" onclick="changeOwned('<?=$id?>')" onmouseover="changeImageSrc('ownedimage<?=$id?>', 'images/collection/add.gif')" onmouseout="changeImageSrc('ownedimage<?=$id?>', 'images/collection/add.gif')"/></a>
<?} ?>
The JavaScript function:
function changeImageSrc(id, src) {
document.getElementById(id).src = src;
}
The (relevant) AJAX code:
var http = createRequestObject();
var jsid = "";
function changeOwned(id) {
http.open('get', 'changeowned.php?id=' + id + '&user=<?=$userid?>');
jsid = id;
http.onreadystatechange = processResponse;
http.send(null);
}
function processResponse() {
if((http.readyState == 4) && (http.status == 200)){
var response = http.responseText;
var elementid = 'ownedimage' + jsid;
var element = document.getElementById(elementid);
if (response == "1") {
image = "images/collection/got.gif";
alt = "you own this game";
mouseoverstr = 'images/collection/del.gif';
mouseoutstr = 'images/collection/got.gif';
element.removeEventListener('mouseout', function(){changeImageSrc('ownedimage' + jsid, 'images/collection/add.gif')}, false);
element.removeEventListener('mouseover', function(){changeImageSrc('ownedimage' + jsid, 'images/collection/add.gif')}, false);
} else {
image = "images/collection/add.gif";
alt = "add this game to your collection";
mouseoverstr = 'images/collection/add.gif';
mouseoutstr = 'images/collection/add.gif';
element.removeEventListener('mouseout', function(){changeImageSrc('ownedimage' + jsid, 'images/collection/got.gif')}, false);
element.removeEventListener('mouseover', function(){changeImageSrc('ownedimage' + jsid, 'images/collection/del.gif')}, false);
}
element.src = image;
element.alt = alt;
element.addEventListener('mouseover', function(){changeImageSrc('ownedimage' + jsid, mouseoverstr)}, false);
element.addEventListener('mouseout', function(){changeImageSrc('ownedimage' + jsid, mouseoutstr)}, false);
}
}
It seems to work fine at first but produces some weird behaviour. The referenced PHP works fine and produces the correct response. The srcand alt of the image get changed as well. In fact, it first looks like the new mouseover/out work too. But when you click on more than one image on the site (which have different IDs) they suddenly start influencing each other. When you mouseover over one, the other changes its image aswell. Why is this happening? I really am clueless as the jsid part is fine and I don't understand why the mouseover suddenly changes two images. It looks as if multiple eventhandlers for different IDs are assigned to the same image element. No idea why that is though. I hope some of you with more AJAX knowledge can help me here, quite frustrated :(
A couple of things there: :-)
1) addEventListener and removeEventListener work with the newer DOM2 handler chain, which is completely separate from the older "DOM0" style (the onXYZ attributes). So you can't remove a handler via removeEventListener that you've originally assigned via an onXYZ attriubte. To do that, assign "" to the attribute's reflected property.
element.onmouseover = "";
2) When you use removeEventListener, you must pass in the same function reference that you used originally. So this will never remove anything:
element.removeEventListener('mouseout', function(){changeImageSrc('ownedimage' + jsid, 'images/collection/got.gif')}, false);
...because it creates a brand new function to pass into removeEventListener, and since that function isn't on the event handler chain, the call is ignored.
I'd probably approach the problem by having a single event handler, but then changing the data it works with. You can do that by storing the alternate image URLs on the actual element itself, using a data-xyz attribute (say, data-oversrc and data-stdsrc or some such). Then your two functions (one for mouseover, one for mouseout) that change the URL based on the image:
function handleMouseOver() {
this.src = this.getAttribute('data-oversrc');
}
function handleMouseOut() {
this.src = this.getAttribute('data-stdsrc');
}
I'd drop the onXYZ handlers from the elements entirely, and replace them with a one-time addEventListener (attachEvent on IE) that assigns both of those.
data-xyz attributes, like all custom attributes, are invalid in HTML4 and earlier. As of HTML5, they validate, and since no major browser has a problem with invalid attributes anyway, you can start using them right away.
Off-topic #1: These days, I usually recommend using a JavaScript library to smooth over browser differences and implement useful functionality for you. For instance, your code using addEventListener and removeEventListener will fail on IE prior to IE9 because it simply doesn't have those methods. If you use a library like jQuery, Prototype, YUI, Closure, or any of several others, they'll deal with that stuff for you so you can focus on your own value-add.
Off-topic #2: The mouseover event happens repeatedly when the mouse is passing over the element, and both it and mouseout bubbles up the DOM. This means that for hover effects like yours, if you can't use CSS (and you can't on IE6), you're better off using the mouseenter and mouseleave events, most of the time. But those are IE-specific events not supported by most other browsers. Enter any decent JavaScript library. :-) They'll emulate mouseenter and mouseleave on browsers that don't support them directly. Of the list above, I know for certain that jQuery and Prototype do that; I'd be surprised if the others don't have similar functionality.
The issue is the removeEventListener, it's not working like you think it is. What's happening is when you do this:
element.removeEventListener('mouseout',function(){/* handlers */},false);
That function() { } is a new anonymous function you just created, not the existing one on the element as a listener...so when it goes to remove that listener, it just isn't there, because that was a different anonymous function (even if it had the exact same code, it's a different reference) that you assigned via addEventListener.
There are a few work-arounds for this, given that you're making AJAX requests I'm assuming you're not making hundreds/thousands here, so you could just store the handlers you assign for removing them later, like this:
var http = createRequestObject();
var jsid = "";
var handlers = {};
function changeOwned(id) {
http.open('get', 'changeowned.php?id=' + id + '&user=<?=$userid?>');
jsid = id;
http.onreadystatechange = processResponse;
http.send(null);
}
function processResponse() {
if((http.readyState == 4) && (http.status == 200)){
var response = http.responseText,
elementid = 'ownedimage' + jsid,
element = document.getElementById(elementid),
image, alt, mouseoverstr, mouseoutstr;
if (response == "1") {
element.src = "images/collection/got.gif";
element.alt = "you own this game";
mouseoverstr = 'images/collection/del.gif';
mouseoutstr = 'images/collection/got.gif';
} else {
element.src = "images/collection/add.gif";
element.alt = "add this game to your collection";
mouseoverstr = 'images/collection/add.gif';
mouseoutstr = 'images/collection/add.gif';
}
//Create a holder if this is the first time for this elementid
if(!handlers[elementid]) handlers[elementid] = {};
//Remove old handlers
element.removeEventListener('mouseover', handers[elementid].mouseover, false);
element.removeEventListener('mouseout', handers[elementid].mouseout, false);
//Store new handlers
handlers[elementid].mouseover = function(){changeImageSrc('ownedimage' + jsid, mouseoverstr)};
handlers[elementid].mouseout = function(){changeImageSrc('ownedimage' + jsid, mouseoutstr)};
//Add hew handlers as listeners
element.addEventListener('mouseover', handers[elementid].mouseover, false);
element.addEventListener('mouseout', handers[elementid].mouseout, false);
}
}