Trying to make a text/sample page for a future project. I want to be able to list a certain amount of objects at a time from the xml document, with a button to load the next however many. Sort of like a browsing catalog. Here's what I got, and I'm pretty sure the problem is at the end of the listbythree function. I just don't know how to plug that function into the specified div element on pageload. any help?
<!DOCTYPE html />
<html>
<head>
<script>
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest(); // code for IE7+, Firefox, Chrome, Opera, Safari
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // code for IE6, IE5
}
xmlhttp.open("GET","books.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
var i=0;
var x=xmlDoc.getElementsByTagName("book");
function listbythree()
{
for (i;i<3;i++)
{
document.write("<div style='display:inline;float:left;background-color:#ffff99;padding:10px;width:300px;height:210px;margin:5px;font-size:14px;'><img style='float:left;padding-right:4px' src=");
document.write(x[i].getElementsByTagName("cover")[0].childNodes[0].nodeValue + " />");
document.write("<em>" + x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue + "</em><br/>");
document.write(x[i].getElementsByTagName("author")[0].childNodes[0].nodeValue + "<br/>");
document.write(x[i].getElementsByTagName("pub")[0].childNodes[0].nodeValue + "<br/>");
document.write(x[i].getElementsByTagName("edition")[0].childNodes[0].nodeValue + "<br/>");
document.write(x[i].getElementsByTagName("genre")[0].childNodes[0].nodeValue + "<br/>");
document.write("Have I Read: " + x[i].getElementsByTagName("read")[0].childNodes[0].nodeValue);
document.write("</div>");
}
document.getElementById("booksbythree").innerHTML=this;
};
function next()
{
if (i<x.length-1)
{
i+3;
listbythree();
}
}
function previous()
{
if (i>0)
{
i-3;
listbythree();
}
}
</script>
</head>
<body onload="listbythree()">
<div id="booksbythree"></div><br/><br/>
<input type="button" onclick="previous()" value="<<" />
<input type="button" onclick="next()" value=">>" />
</body>
</html>
Your for loop only loops when i<3, so it will never show any elements further than the third. You can do the following to fix this. Also your next button is adding 3 to i when your for loop is also adding to i, this would make you skip 3 elements each time you click next.
function listbythree()
{
var j = i+3;
for (i;i<j&&i<x.length;i++)
{
....
}
}
function next()
{
if (i<x.length-1)
{
listbythree();
}
}
On a second note I would suggest that you use jQuery, it can make the AJAX and XML parsing much easier.
Related
I want to develop a News Ticker using three technologies: PHP, Javascript and AJAX.
First, I made a PHP function getFeed() to fetch data from News websites on an Array, then I made a JSON return using this code: echo json_encode($articles, true);
Secondly, I aim to use AJAX and Javascript to make repeated calls to getFeed() function, here is my javascript code:
<script type="text/javasript">
var xmlhttp=false;
function begin() {
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200){
var jsonContent=JSON.parse(this.responseText);
displayT(jsonContent);
}
};
// rssnews.inc.php contain the getFeed() function
xmlhttp.open('GET','rssnews.inc.php', true);
xmlhttp.send();
}
// displayT(content) function display the JSON element
function displayT(content){
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out += '<h4><a href="' + arr[i].link+ '">' +
arr[i].title + '</a></h4><br>';
}
document.getElementById('item').innerHTML = out;
}
</script>
On the HTML page, I have the following components a button (id="start") - on click execute begin() function, a div container (id="Ticker") and a div (id="item") for display data with AJAX
<form>
<button type="submit" class="btn btn-default" id="start" onclick="begin();"> START </button>
</form>
<div id= "ticker" style="border: 1px solid #ccc; height: 500px; weight:600px;">
<div id="item">
<!-- I want to display the fetched data by 4 items at a specific time Interval-->
</div>
</div>
When I click on the start button, I don't get the json data.
How can I solve this problem and how can I ensure that this AJAX calls is the most appropriate way to my Ticker.
Thank you!
The error is essentially saying that the file you are trying to GET with you AJAX call, does not exist at the specified location (which is http://localhost/rss/rssnews.inc.php).
You are using a Relative path, which searches for 'rssnews.inc.php' in the same folder. To go up to the parent directory, use ../.
Or use an Absolute path, as in http://localhost/rss/rssnews.inc.php. (Replace with absolute path to your PHP script)
Update
(after HTTP 401 solved)
displayT function is taking content as input, and is then reffering to arr, which is not defined.
Assuming content is actually an array containing your data in the desired format, replace arr with content:
function displayT(content){
var out = "";
var i;
for(i = 0; i < content.length; i++) {
out += '<h4><a href="' + content[i].link+ '">' +
content[i].title + '</a></h4><br>';
}
document.getElementById('item').innerHTML = out;
}
I'm not one of those people that grew up with programming, or have experienced in high school. I just recently started the basics in College. What I have below is my javascript/html that I have been working on Visual Studio 2012. My goal for it is to display the images one at a time by pressing a button called "Next Name" (as you can see I created a "form" at the bottom of my code). But as I have it now, it prints out all the images in my "hw1.txt" at the same time. Under my for loop, I tried "result = "";" and then "displayList.innerHTML = result;" hoping to just print out one image at least. I tried other things, but it just left my code messy. Please I need help. Any advice, pointers, or whatever is good. Can you also explain your answers in a way that I'll understand too? Just think of me as you're talking to a child or something haha. Thanks.
Note: in "hw1.txt" every 3rd index (starting from index 0) is the name of people, and the index next to it (myArray[i + 1]) is the image file (inside the .txt it goes like 1.jpg, 2.jpg, 3.jpg, and so on...)
<br/>
<span id="displayList">Photo here.</span>
<script type=text/javascript>
if (typeof ActiveXObject != "undefined") // IE
var req = new ActiveXObject("Microsoft.XMLHTTP");
else // Other browsers
var req = new XMLHttpRequest();
req.open('GET', 'hw1.txt', false);
req.send(null);
s = req.responseText;
var myArray = s.split(";");
var result = "";
function nextItem() {
for (i = 3; i < myArray.length; i = i + 3)
result = result + "<img src='" + myArray[i + 1] + "'/>";
displayList.innerHTML = result;
}
</script>
<form name="ClickNext">
<input type="button" value="Next Name" onclick="nextItem()" />
</form>
<span id="displayList">Photo here.</span>
<script type=text/javascript>
if (typeof ActiveXObject != "undefined") // IE
var req = new ActiveXObject("Microsoft.XMLHTTP");
else // Other browsers
var req = new XMLHttpRequest();
req.open('GET', 'hw1.txt', false);
req.send(null);
s = req.responseText;
var myArray = s.split(","); //if images are comma(,) seperated then just split it from comma
var index = 0;
function nextItem() {
if(typeof myArray[index] !== 'undefined') {
displayList.innerHTML = "<img src='" + myArray[index] + "'/>";
index += 1;
}
}
</script>
<form name="ClickNext">
<input type="button" value="Next Name" onclick="nextItem()" />
</form>
First off you don't need the form around that input since you don't really send a form.
Secound you should add an id to your input ( or <a></a> or <button></button> ) such as id="next_name" or I guess you can keep the old way of calling an event. :P
Then, you should:
var position = 0;
var result = '';
document.getElementById('next_name').onclick = function(){
if(position < myArray.length){
result = result + "<img src='" + myArray[position + 1] + "'/>";
displayList.innerHTML = result;
position++;
}
};
The idea is to use a variable to memorize your position within your list of image srouces. Once you use one, you increment your position within the list so next time a user clicks that button you add a different image.
I want to get the stats from my XML when someone is asking for a particular name, but my javascript doesn't work like I want.>br>
Here's my XML :
<player>
<forward><name>Joe</name><stats>45</stats></forward>
<forward><name>Jack</name><stats>42</stats></forward>
<forward><name>Peter</name><stats>34</stats></forward>
<forward><name>Steve</name><stats>21</stats></forward>
<goalie><name>Pat</name><stats>2.34</stats></goalie>
</player>
Here's my HTML (ajax) :
<html>
<head>
<script language="JavaScript">
function LoadDoc(vValue) {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "player.xml",true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
Answer(xmlhttp.responseXML, vValue);
}
}
xmlhttp.send(null);
}
function Answer(doc, ParamValue) {
var counts=doc.getElementsByTagName("forward");
for(var i=0;i < counts.length; i++){
alert(counts.length)
var vname = counts[i].getElementsByTagName('name');
alert(vname[i].firstChild.nodeValue)
var vstats = counts[i].getElementsByTagName('stats');
alert(vstats[i].firstChild.nodeValue);
if (vname[i].firstChild.nodeValue == ParamValue)
{
alert(stats[i].firstChild.nodeValue);
}
}
}
</script>
</head>
<body>
<form>
<input type="field" id="champ" />
<input type="button"
onclick="javascript:LoadDoc(document.getElementById('champ').value);" />
</form>
</body>
</html>
The first ALERT is good finding 4 elements
the second ALERT works giving me JOE.
The third ALERT works giving me 45 (the number) of the stats of the first forward
But strangely, the alert are launch only once... I don't have 4 times the Alert, why it doesn''t turn 4 times inside the loop ?
Any Idea of what's wrong ?
Or a better solution to find the stats ?
Look at the console for any error messages. At a glance, the line alert(stats[i].firstChild.nodeValue); references an undeclared variable stats, so if that line executes, the script should throw a ReferenceError and terminate, which would cause the alerts to fire only once.
Thanks Dagg Nabbit, finally I found it. with the error found previously, I suppose that the vname[i] doesn't exist, so I replace the "i" with "0" so it's now vname[0]. For sure I'm looking the first element named "name" and not the second.I replace the vstats[i] with vstat[0] and it works perfectly.
Ok, so I've got an onclick event (CF-D07 is an example, these are generated programmatically based on a MySQL database):
<input type="checkbox" onclick="var nameUpdate = 'CF-D07';
datechange();" id="CF-D07">
So then, under datechange(), I have this:
function datechange() {
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest(); }
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject
("Microsoft.XMLHTTP");
}
document.body.getElementsByTagName("tr").getElementsById(nameUpdate);
// This section isn't done yet.
// var url = "changedate.psp"
// var params = "user=" + nameUpdate
// xmlhttp.open("GET", url + "?" + params,false);
// xmlhttp.send();
// xmlDoc=xmlhttp.responseXML;
}
The important part of this is this part of the code:
document.body.getElementsByTagName("tr").getElementsById(nameUpdate);
How do I make it so that I get all of the elements with the tag, that then have the id of nameUpdate, based on the onclick event? And then after that, how do I select the innerHTML of the first two 's in the and put it into separate variables?
If I'm understanding you correctly, you should never have more than one element with the same ID on any page. If you need to classify html elements, use the class attribute.
To get the inner html of elements, you can use aptly named innerHTML property of the DOM element:
function datechange(nameUpdate) {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// document.body.getElementsByTagName("tr").getElementsById(nameUpdate);
var trs = document.getElementByClassName(nameUpdate);
for(var i = 0, len = trs.length; i < len; ++i) {
var html = tr.innerHTML;
// Do what you need to with HTML
}
}
With the above code, your original HTML snippet could look like this:
<input type="checkbox" onclick="datechange('CF-D07')">
This also assumes you'd have a tr somewhere that looks something like this:
<tr class="CF-D07">
<td>...</td>
<td>...</td>
</tr>
To access the <td> elements of a given <tr>, you can use the children property for all child elements, or you can use getElementsByTagName directly on the tr element:
var tr = ... // get the TR somehow
var tds = tr.getElementsByTagName('td');
var allHTML = "";
for(var i = 0, len = tds.length; i < len; ++i) {
allHTML += tds[i].innerHTML;
}
// Do something with allHTML, which is the inner html of all tds put together
Here's my code:
<html>
<header>
<title>Checkup Date</title>
<script type="text/javascript">
function datechange() {
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest(); }
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject
("Microsoft.XMLHTTP");
}
var tr = getElementsById(nameUpdate)
var tds = tr.getElementsByTagName('td');
var user = "";
var date = "";
for(var i = 0, len = tds.length; i < len; ++i) {
user = tds[0];
date = tds[3];
}
var url = "changedate.psp"
var params = "user=" + user + "&date=" + date;
xmlhttp.open("GET", url + "?" + params, true);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
}
</script>
</header>
<body>
<%
Python that doesn't matter
%>
<%= More Python %>
</body>
</html>
My outputted HTML:
<tr id="TL-D03">
<td>nobody</td>
<td>TL-D03</td>
<td>2010-01-01</td>
<td>
<input type="checkbox" onclick="var nameUpdate = 'TL-D03'; datechange();">
What am I doing wrong here? It says getElementById is undefined.
getElementById is a function of document:
var tr = document.getElementById("nameUpdate")
MDN: https://developer.mozilla.org/en/DOM/document.getElementById
Problem 1: you're calling getElementsById. IDs are unique: the function is getElementById. No s.
Problem 2: getElementById is not a global function. You need to call it on the document object:
var tr = document.getElementById(nameUpdate)
After all, your script could reference more than one document (for example, with an iframe), so you need to be explicit about where you expect the element to be.
Also try changing:
<input type="checkbox" onclick="var nameUpdate = 'TL-D03'; datechange();">
to this:
<input type="checkbox" onclick="datechange('TL-D03')">
and
function datechange() {
to this
function datechange(nameUpdate) {
makes more sence
It's document.getElementById(), not getElementsById(), as it only returns one element.
The latter would not be very useful, since id attributes must be unique within an HTML document.
you need to use document.getElementById("yourelementid")
The reason it doesn't work is that var scopes a variable to the function it is defined in, so it isn't readable outside the anonymous function assigned to the onclick handler.
In more general "wrongness" terms, passing data about using globals is generally a bad idea.
Pass it as an argument instead.
function datechange(nameUpdate) {
and
datechange('TL-D03');