Loop through XML Parser? - javascript

I am developing an app, where on the click of a button, a list of the document information stored in an XML file is shown on screen in a <ul> tag. The current JavaScript in the function is;
function viewXMLFiles() {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
document.getElementById("docname").innerHTML = xmlDoc.getElementsByTagName("document_name")[0].childNodes[0].nodeValue;
document.getElementById("filetype").innerHTML = xmlDoc.getElementsByTagName("file_type")[0].childNodes[0].nodeValue;
document.getElementById("fileloc").innerHTML = pathToRoot + "/" + document.getElementById("docname").innerHTML;
document.getElementById("docname1").innerHTML = xmlDoc.getElementsByTagName("document_name")[1].childNodes[0].nodeValue;
document.getElementById("filetype1").innerHTML = xmlDoc.getElementsByTagName("file_type")[1].childNodes[0].nodeValue;
document.getElementById("fileloc1").innerHTML = pathToRoot + "/" + document.getElementById("docname1").innerHTML;
}
but i want to set it so that even if more file information is added, the function will display it too. i have already looked at Jquery xml parsing loops this question, but i couldn't get the function to work. Here's the XML file;
<document_list>
<document>
<document_name>Holidays.pdf</document_name><br />
<file_type>.pdf</file_type> <br />
<file_location>TEST</file_location> <br />
</document>
<document>
<document_name>iPhone.jsNotes.docx</document_name><br />
<file_type>.docx</file_type><br />
<file_location>TEST</file_location><br />
</document>
</document_list>
And this is the HTML i am using. There's a button and the <ul> tags i'm using;
<button onclick = "viewXMLFiles(); document.getElementById('showDocumentLink').style.display = 'block';">View Document Info</button><br>
<div id = "doclist">
<h2>Document 1;</h2>
<label>Document Name;</label><br><span id = "docname"></span><br>
<label>File Type</label><br><span id = "filetype"></span><br>
<label>File Location</label><br><span id = "fileloc"></span><br>
</div>
<div id = "doclist">
<h2>Document 2;</h2>
<label>Document Name;</label><br><span id = "docname1"></span><br>
<label>File Type</label><br><span id = "filetype1"></span><br>
<label>File Location</label><br><span id = "fileloc1"></span><br>
</div>
Can anyone help me put this into a loop? I have linked jQuery and jQTouch so i can use both of them.
Thank you so much in advance xx

Use following loop code.
<script>
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
// now do whatever you like with above variable
});
</script>

Using Irfan's answer as a base, to get the values into your labels add a counter, then just insert the values grabbed from the XML parsing loop into the corresponding span.
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
var doccount = 0;
//will be used to find the HTML elements
var namelabel = "docname";
var typelabel = "filetype";
var locationlabel = "fileloc";
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
//after the first document we need to add the number to the span id
if(doccount > 0){
namelabel = "docname" + doccount;
typelabel = "filetype" + doccount;
locationlabel = "fileloc" + doccount;
}
//insert the XML values into the label
$('span#'+namelabel).html(name);
$('span#'+typelabel).html(file_type);
$('span#'+locationlabel).html(file_location);
//increment the counter
doccount++;
});
</script>

Here is a native JavaScript implementation so you can see how you'd do it that way and compare, etc.
function viewXMLFiles() {
// var everything
var xmlhttp = new XMLHttpRequest(),
xmlDoc,
nodes, i, j, counter = -1, suffix,
document_name, file_type, file_location;
// request page
xmlhttp.open("GET", "TestInfo.xml", false),
xmlhttp.send();
// false meant synchronous req. so can go straight to reading document
xmlDoc = xmlhttp.responseXML;
// loop over <document> nodes
nodes = xmlDoc.childNodes; // shorthand
j = nodes.length;
for (i = 0; i < j; ++i) {
if ('document' === nodes[i].tagName.toLowerCase()) {
// nodes[i] is a <document>, increment counter
++counter;
// get nodes of intrest
document_name = nodes[i].getElementsByTagName("document_name")[0];
file_type = nodes[i].getElementsByTagName("file_type")[0];
file_location = nodes[i].getElementsByTagName("file_location")[0];
// do what you want with these, e.g.
suffix = counter || ''; // don't append a number for 0
document.getElementById('docname'+suffix).textContent = document_name.textContent;
document.getElementById('filetype'+suffix).textContent = file_type.textContent;
document.getElementById('fileloc'+suffix).textContent = pathToRoot + "/" + file_location.textContent;
}
}
}
Furthermore, you should consider the validity of your HTML, as I mentioned in my comment;
there should be no spaces around the equals sign of an attribute name/value pair, i.e. <tag attrib="val"/> not <tag attrib = "val"/>
every id attribute should have a unique value, not shared with any other on the document, i.e. not <tag id="shared"/><tag id="shared"/>

Related

How to load dropdown list in html from a properties file?

If anyone could help
I have a properties file as below (db.properties) :-
1=DEV;
2=NATIVE;
and i have to load this value from the properties file into the drop down present in html file
below is my html file :-
<body>
<p> Select the environment </p>
<br>
<select name="env">
<option value="DEV">DEV</option>
<option value="NATIVE">NATIVE</option>
</select>
</body>
the values from the properties file should come automatically into the drop down present in HTML. Even if a new value is added in the properties file that should be present in the drop down.
Can anyone suggest some code to do the same it would be really helpful
Thank you :)
It would be better to have this file is in json format, but you can download it using XMLHttpRequest (it must be on the same server regarding same-origin policy), parse with split("=") and modify DOM tree by means of appendChild and innerHTML.
If you want to have live changes, you can use setTimeout (first time in DOMContentLoaded, subsequently after modifying SELECT).
Hope this helps.
oo = {};
oo.refreshInterval = 1000;
oo.fileToRequest = 'config.txt';
oo.loadList = function() {
var req = new XMLHttpRequest();
var lines;
var select = document.querySelector('select:first-of-type');
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
lines = req.responseText.split('\n');
while (select.firstChild) {
select.removeChild(select.firstChild);
}
lines.forEach(function(value) {
var describer = value.split('=')[1];
var option = document.createElement('option');
var text =
document.createTextNode(
describer.substr(0, describer.length - 1)
);
option.appendChild(text);
select.appendChild(option);
});
}
}
req.open('get', oo.fileToRequest);
req.send(null);
}
window.addEventListener('load', function() {
oo.loadList();
// Refresh the select box.
setInterval(oo.loadList, oo.refreshInterval);
});
You can do it very easily with ajax using jQuery I have created a demonstration here http://plnkr.co/edit/7PbH8AdQxGc9RGmxslkr?p=preview
Your HTML
<p> Select the environment </p>
<br>
<select name="env"></select>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
Your db.properties file
1=DEV;
2=NATIVE;
js
$(function(){
jQuery.ajax({
url: "db.properties"
}).done(function(data){
var options = data.split(/\n/);
$('select[name="env"]').html('');
for (i=0; i<options.length; i++) {
console.log(options[i].split('='));
var optionVal = options[i].split('=').pop().replace(';', "");
$('select[name="env"]').html('<option value="'+ optionVal +'">'+ optionVal +'</option>');
}
})
});
Don't be afraid of using Ajax, it's pretty simple:
<script>
window.onload = function(){
var xhr = new XMLHttpRequest(),
dropdown = document.getElementById("env"),
lines = [], i, count, line, item;
xhr.open('GET', '/db.properties');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (xhr.responseText) {
dropdown.innerHtml = "";
lines = xhr.responseText.split('/\n|\r\n/');
for(i=0,count = lines.length; i < count; i+ = 1){
line = lines[i].split('=');
item = document.createElement('option');
item.text = line[1];
item.value = line[0];
dropdown.appendChild(item);
}
}
}
}
xhr.send();
}
</script>
<body>
<p> Select the environment </p>
<br>
<select name="env" id="env">
</select>
</body>

Restore exact innerHTML to DOM

I'd like to save the html string of the DOM, and later restore it to be exactly the same. The code looks something like this:
var stringified = document.documentElement.innerHTML
// later, after serializing and deserializing
document.documentElement.innerHTML = stringified
This works when everything is perfect, but when the DOM is not w3c-comliant, there's a problem. The first line works fine, stringified matches the DOM exactly. But when I restore from the (non-w3c-compliant) stringified, the browser does some magic and the resulting DOM is not the same as it was originally.
For example, if my original DOM looks like
<p><div></div></p>
then the final DOM will look like
<p></p><div></div><p></p>
since div elements are not allowed to be inside p elements. Is there some way I can get the browser to use the same html parsing that it does on page load and accept broken html as-is?
Why is the html broken in the first place? The DOM is not controlled by me.
Here's a jsfiddle to show the behavior http://jsfiddle.net/b2x7rnfm/5/. Open your console.
<body>
<div id="asdf"><p id="outer"></p></div>
<script type="text/javascript">
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
var e = document.getElementById('asdf')
console.log(e.innerHTML);
e.innerHTML = e.innerHTML;
console.log(e.innerHTML); // This is different than 2 lines above!!
</script>
</body>
If you need to be able to save and restore an invalid HTML structure, you could do it by way of XML. The code which follows comes from this fiddle.
To save, you create a new XML document to which you add the nodes you want to serialize:
var asdf = document.getElementById("asdf");
var outer = document.getElementById("outer");
var add = document.getElementById("add");
var save = document.getElementById("save");
var restore = document.getElementById("restore");
var saved = undefined;
save.addEventListener("click", function () {
if (saved !== undefined)
return; /// Do not overwrite
// Create a fake document with a single top-level element, as
// required by XML.
var parser = new DOMParser();
var doc = parser.parseFromString("<top/>", "text/xml");
// We could skip the cloning and just move the nodes to the XML
// document. This would have the effect of saving and removing
// at the same time but I wanted to show what saving while
// preserving the data would look like
var clone = asdf.cloneNode(true);
var top = doc.firstChild;
var child = asdf.firstChild;
while (child) {
top.appendChild(child);
child = asdf.firstChild;
}
saved = top.innerHTML;
console.log("saved as: ", saved);
// Perform the removal here.
asdf.innerHTML = "";
});
To restore, you create an XML document to deserialize what you saved and then add the nodes to your document:
restore.addEventListener("click", function () {
if (saved === undefined)
return; // Don't restore undefined data!
// We parse the XML we saved.
var parser = new DOMParser();
var doc = parser.parseFromString("<top>" + saved + "</top>", "text/xml");
var top = doc.firstChild;
var child = top.firstChild;
while (child) {
asdf.appendChild(child);
// Remove the extra junk added by the XML parser.
child.removeAttribute("xmlns");
child = top.firstChild;
}
saved = undefined;
console.log("inner html after restore", asdf.innerHTML);
});
Using the fiddle, you can:
Press the "Add LadyGaga..." button to create the invalid HTML.
Press "Save and Remove from Document" to save the structure in asdf and clear its contents. This prints to the console what was saved.
Press "Restore" to restore the structure that was saved.
The code above aims to be general. It would be possible to simplify the code if some assumptions can be made about the HTML structure to be saved. For instance blah is not a well-formed XML document because you need a single top element in XML. So the code above takes pains to add a top-level element (top) to prevent this problem. It is also generally not possible to just parse an HTML serialization as XML so the save operation serializes to XML.
This is a proof-of-concept more than anything. There could be side-effects from moving nodes created in an HTML document to an XML document or the other way around that I have not anticipated. I've run the code above on Chrome and FF. I don't have IE at hand to run it there.
This won't work for your most recent clarification, that you must have a string copy. Leaving it, though, for others who may have more flexibility.
Since using the DOM seems to allow you to preserve, to some degree, the invalid structure, and using innerHTML involves reparsing with (as you've observed) side-effects, we have to look at not using innerHTML:
You can clone the original, and then swap in the clone:
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var clone = e.cloneNode(true);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
snippet.log("2: " + e.innerHTML);
e.parentNode.replaceChild(clone, e);
e = clone;
snippet.log("3: " + e.innerHTML);
Live Example:
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var clone = e.cloneNode(true);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
snippet.log("2: " + e.innerHTML);
e.parentNode.replaceChild(clone, e);
e = clone;
snippet.log("3: " + e.innerHTML);
<div id="asdf">
<p id="outer">
<div>ladygaga</div>
</p>
</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Note that just like the innerHTML solution, this will wipe out event handlers on the elements in question. You could preserve handlers on the outermost element by creating a document fragment and cloning its children into it, but that would still lose handlers on the children.
This earlier solution won't apply to you, but may apply to others in the future:
My earlier solution was to track what you changed, and undo the changes one-by-one. So in your example, that means removing the insert element:
var e = document.getElementById('asdf')
console.log("1: " + e.innerHTML);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
var outer = document.getElementById('outer');
outer.appendChild(insert);
console.log("2: " + e.innerHTML);
outer.removeChild(insert);
console.log("3: " + e.innerHTML);
var e = document.getElementById('asdf')
snippet.log("1: " + e.innerHTML);
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
var outer = document.getElementById('outer');
outer.appendChild(insert);
snippet.log("2: " + e.innerHTML);
outer.removeChild(insert);
snippet.log("3: " + e.innerHTML);
<div id="asdf">
<p id="outer">
<div>ladygaga</div>
</p>
</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Try utilizing Blob , URL.createObjectURL to export html ; include script tag in exported html which removes <div></div><p></p> elements from rendered html document
html
<body>
<div id="asdf">
<p id="outer"></p>
</div>
<script>
var insert = document.createElement("div");
var text = document.createTextNode("ladygaga");
insert.appendChild(text);
document.getElementById("outer").appendChild(insert);
var elem = document.getElementById("asdf");
var r = document.querySelectorAll("[id=outer] ~ *");
// remove last `div` , `p` elements from `#asdf`
for (var i = 0; i < r.length; ++i) {
elem.removeChild(r[i])
}
</script>
</body>
js
var e = document.getElementById("asdf");
var html = e.outerHTML;
console.log(document.body.outerHTML);
var blob = new Blob([document.body.outerHTML], {
type: "text/html"
});
var objUrl = window.URL.createObjectURL(blob);
var popup = window.open(objUrl, "popup", "width=300, height=200");
jsfiddle http://jsfiddle.net/b2x7rnfm/11/
see this example: http://jsfiddle.net/kevalbhatt18/1Lcgaprc/
MDN cloneNode
var e = document.getElementById('asdf')
console.log(e.innerHTML);
backupElem = e.cloneNode(true);
// Your tinkering with the original
e.parentNode.replaceChild(backupElem, e);
console.log(e.innerHTML);
You can not expect HTML to be parsed as a non-compliant HTML. But since the structure of compiled non-compliant HTML is very predictable you can make a function which makes the HTML non-compliant again like this:
function ruinTheHtml() {
var allElements = document.body.getElementsByTagName( "*" ),
next,
afterNext;
Array.prototype.map.call( allElements,function( el,i ){
if( el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE' ) {
if(el.textContent === '') {
next = el.nextSibling;
afterNext = next.nextSibling;
if( afterNext.textContent === '' ) {
el.parentNode.removeChild( afterNext );
el.appendChild( next );
}
}
}
});
}
See the fiddle:
http://jsfiddle.net/pqah8e25/3/
You have to clone the node instead of copying html. Parsing rules will force the browser to close p when seeing div.
If you really need to get html from that string and it is valid xml, then you can use following code ($ is jQuery):
var html = "<p><div></div></p>";
var div = document.createElement("div");
var xml = $.parseXML(html);
div.appendChild(xml.documentElement);
div.innerHTML === html // true
You can use outerHTML, it perseveres the original structure:
(based on your original sample)
<div id="asdf"><p id="outer"></p></div>
<script type="text/javascript">
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
var e = document.getElementById('asdf')
console.log(e.outerHTML);
e.outerHTML = e.outerHTML;
console.log(e.outerHTML);
</script>
Demo: http://jsfiddle.net/b2x7rnfm/7

"FORBIDDEN You don't have permission to access /greenfloyd/php/bm_edit_xml.php on this server."

I've been sweating over this the last three days, I am baffled!
The input html launches an xml scan of a web site to gather text, images and links which populate a form for the user to select what they want to save. (The output eventually becomes a bookmark stored at greenfloyd.org.) The problem began a month or so ago, the scan started crashing with a "Forbidden 403" error pointing to my php code file, on the gf server (dir/file permission at 0644). The problem revolves around the links (url and text) gathered and placed into a box , the url is put in the value, and the link text into the innerHTML. The default is that none of the links are selected, the user can then select one or more links from this box, or manually add a link via two fields that get put into the select box, and become part of the form.
<form id = "bmInputForm" onsubmit = "bmSub(); return false;" onreset = "bmInputFormReset();" action = "http://greenfloyd.org/greenfloyd/php/bm_input_xml.php" method = "post" enctype = "multipart/form-data" class = "readerBox">...
<code><input type = "url" id = "link1Url" class = "input_size" size = "40" maxlength = "250" value ="" onclick = "this.select();" title = "Enter a standard url for this related link.">
<input id = "link1Title" class = "input_size" size = "40" maxlength = "150" value = "" onclick = "this.select();" title = "Enter a short title for this related link.">
<button type = "button" onclick = "relatedAdd()" title = "Add to related links list.">[+]</button>
<hr style="width:25%;">
<select id = "relatedSelect" name = "related_select[]" multiple title = "To select/unselect hold down the Ctrl key and click an option." onchange = "relatedCheck();" style = "width:80%;"></select></code>
The scan is an ajax xml call and returns elements from the target url, including the following:
<code>//echo "<related url='".rawurlencode($valid_url)."' txt='".htmlspecialchars($related_text, ENT_QUOTES,'UTF-8')."'></related>";
err = false;
try { var relatedNode = ( xmlDoc.getElementsByTagName("related") ) ? xmlDoc.getElementsByTagName("related") : false; }
catch(err) { err = true; relatedNode = false; }
result += ( !relatedNode ) ? "<li>Scanner unable to retrieve relatedNode || "+err+"</li>" : "<li>Link scan found: "+relatedNode.length+" entries.</li>";
if( relatedNode.length > 0 )
{
clearCache("relatedSelect");
var selObj = document.getElementById("relatedSelect");
for(var i = 0; i < relatedNode.length; i++)
{
val = unescape(relatedNode[i].getAttribute("url"));
str = unescape(relatedNode[i].getAttribute("txt"));
opt = document.createElement("option");
opt.value = val;
opt.innerHTML= ( str.length > 50 ) ? str.substring(0,48)+"..." : str;
selObj.appendChild(opt);
}
}
</code>
All the above is working fine. But everything goes south at submit time when the urls, (the value), are external relative to greenfloyd.org. Then, I get the "Go away and don't come back message..." On the other hand, if the urls point to greenfloyd there's no problem and the bookmark is published, with links. It's almost like I were trying to call the local script from some other domain. The uls are not in any linkable context, they are treated as plain text in the value attribute of the option. Although I do combine the url with the text using a seperator (,) between them so that php can unpack the value to produce seperate url and text fields that are stored on msqli... it's hacky, but it works, or at least it use to and I've yet to find a better alternative. One other odd thing: when I gather the links in greenfloyd.org there are a couple external links and they are accepted!?
<code>
function bmSub()
{
...
var selObj = document.getElementById("relatedSelect");
var url, txt, val, sendCt=0;
for ( var i = 0; i < selObj.options.length; i++ )
{
if ( selObj.options[i].selected )
{
url = selObj.options[i].value.trim();
txt = selObj.options[i].innerHTML;
val = url+"*,*"+txt; // pack url and txt into the value attribute, php unpacks it into 2 db fields
selObj.options[i].value = val;
sendCt +=1;
}
}
resultDisplay("Link count: "+sendCt);
var formElement = document.getElementById("bmInputForm");
var formData = new FormData(formElement);
var urlX = encodeURI("http://greenfloyd.org/greenfloyd/php/bm_input_xml.php?sid="+Math.random());
xmlObj = GetXmlHttpObject();
xmlObj.open("POST", urlX, false);
xmlObj.send(formData);
// pause echo "<return err='$err' msg='$msg'></return>";
try
{
xmlDoc = xmlObj.responseXML;
var returnNode = xmlDoc.getElementsByTagName("return");
err = ( returnNode[0].getAttribute("err") == "1" ) ? true : false;
msg = unescape(returnNode[0].getAttribute("msg"));
}
catch(e)
{
msg = "bmSub status : "+e+"<br>xml: "+xmlObj.statusText+", "+xmlObj.status+", size: "+xmlObj.responseText.length;
err = true;
}
resultDisplay(msg);
if ( err ) return;
</code>

Passing array -- scope

I want to pass an array from one external .js file to another.
Each of these files works fine by themselves, but I am having a problem passing the array from pickClass.js to displayStudent.js, and getting the names and "remaining" value to display in the html file. I know it has something to do with how the arrays are declared, but I can't seem to get it to work properly.
The first file declares the array choice:
(masterStudentList.js):
var class1 = ['Brown, Abe','Drifter, Charlie','Freed, Eve'];
var class2 = ['Vole, Ug','Xylo, William','Zyzzyx, Yakob'];
The second picks which array to use based on the radio buttons (pickClass.js):
var classPicked = array(1);
function randomize(){
return (Math.round(Math.random())-0.5); }
function radioResult(){
var chooseClass = document.getElementsByName("chooseClass");
for (i = 0; i < chooseClass.length; i++){currentButton = chooseClass[i];
if (currentButton.checked){
var selectedButton = currentButton.value;
} // end if
} // end for
var output = document.getElementById("output");
var response = "You chose ";
response += selectedButton + "\n";
output.innerHTML = response;
chosenClass = new Array();
if (selectedButton == "class1")
{chosenClass = class1;}
else
{chosenClass = class2;}
var text = "";
var nametext = "";
var i;
for (i = 0; i < chosenClass.length; i++) {
text += chosenClass[i]+ ' / ';
}
var showText = "";
l = chosenClass.length;
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
//return = classPicked;
document.getElementById("classList").innerHTML = classPicked;
} // end function
This works properly.
I then want to pass "classPicked" to another .js file (displayStudent.js) which will randomize the student list, loop and display the students for a few seconds, and then end with one student name.
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5); }
function showBasket(){
mixedBasket = basket.sort( randOrd ); //randomize the array
var i = 0; // the index of the current item to show
document.getElementById("remaining").innerHTML = basket.length;
fruitDisplay = setInterval(function() {
document.getElementById('showStud')
.innerHTML = mixedBasket[i++]; // get the item and increment
if (i == mixedBasket.length) i = 0; // reset to first element if you've reached the end
}, 100); //speed to display items
var endFruitDisplay = setTimeout(function()
{ clearInterval(fruitDisplay);
var index = mixedBasket.indexOf(document.getElementById('showStud').innerHTML);
mixedBasket.splice(index,1);
}, 3500); //stop display after x milliseconds
}
Here is the html (master.html). It's just rough -- I'll be working on the layout later:
<html>
<head>
<script src="masterStudentList.js" type="text/javascript"></script>
<script src="pickClass.js" type="text/javascript"></script>
<script src="displayStudent.js" type="text/javascript"></script>
</head>
<body>
<h2>Choose Class</h2>
<form action = "">
<fieldset>
<input type = "radio"
name = "chooseClass"
id = "radSpoon"
value = "class1"
checked = "checked" />
<label for = "radSpoon">Class 1</label>
<input type = "radio"
name = "chooseClass"
id = "radFlower"
value = "class2" />
<label for = "radFlower">Class 2</label>
<button type = "button"
onclick = "radioResult()"> Choose Class
</button>
<div id = "output">
</fieldset>
</form>
</div>
<center>
<h1> <span id="chooseStud"></span><p></h1>
<script> var fruitSound = new Audio();
fruitSound.src = "boardfill.mp3";
function showFruitwithSound()
{
fruitSound.play(); // Play button sound now
showBasket()
}
</script>
Remaining: <span id = "remaining" ></span>
<p>
<button onclick="showFruitwithSound()">Choose Student</button>
</center>
pickedClassList = <p id = classList> </p>
</body>
</html>
You shouldn't use global variable like this (I encourage you to read more on this theme) and I'm not sure I understand what you're trying to do... but the solution of your issue should be to move the basket = classPicked; line into your showBasket method :
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
// whatever
}
should be :
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
basket = classPicked; //This is where the array should be passed
// whatever
}
This way, each time you call showBasket, this method will use the last value of classPicked.
Otherwise, basket will always keep the reference on the first value of classPicked.
Why ? because each time you assign a new Array to the basket variable (classPicked = Array(l);) instead of changing directly it's content by :
emptying it : while (classPicked.length > 0) { classPicked.pop(); }
and then adding new data : classPicked.concat(chosenClass)
You can't pass things to files; you could call a function defined in displayStudent.js, pass it classPicked, and have it assign it to basket.
I noticed this at the end of your second chunk of code ...
} // end function
This could indicate the classPicked is declared inside a function (I don't see one on the code). Because it is inside function scope, your set of code that is trying to use it cannot.
Push the declaraction of classPicked outside of the function.
var classPicked = Array(1);
function thisusesclasspicked() {
...
Also, please start indenting your code properly, it will become much easier to maintain and read.
UPDATE FROM COMMENTS:
I see the declaration now ...
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
... however, you are re-assigning the array with an element of one just before you attempt to make modifications to it ... You are emptying it there: classPicked = Array(l);

Saving a selected document as a response document with XPages

i am new to xpages, but i want to try to create a response document for a main document which is the order document. there is a product document which display the view of all product in the database and with a checkbox, both document are on one page. using the below code on the onclick event if the checkbox
var colName = view1Collection.getColumnValue("Name");
var prodNameScope = sessionScope.get("scopeProdName");
var docIdScope = sessionScope.get("scopeDocID");
var selDocID = view1Collection.getUniversalID();
if(docIdScope .contains(selDocID )) {
prodNameScope .remove(colName );
docIdScope .remove(selDocID );
} else {
prodNameScope .add(colName );
docIdScope .add(selDocID );
}
Postopen event:
var nameList = new java.util.ArrayList();
sessionScope.put('scopeProdName', nameList );
var idList = new java.util.ArrayList();
sessionScope.put('scopeDocID', idList );
On the next pages the item displayed well, but i want the selected item to be copied and save as a response document to the main document.
i have tried the below script but did not work:
var PN = sessionScope.get("scopeProdName[indexRowdata]");
document1.replaceItemValue("_Title", PN);
anyone have idea how i could go about this.
thanks in advance.
if you display the articles in a view control you can get the id:s of then using
var myArray = sessionScope.get("projectName");
var PNu = sessionScope.get("projectNumber");
document1.replaceItemValue("ProjectName", myArray);
document1.replaceItemValue("ProjectNumber", PNu);
var PN:java.util.ArrayList = sessionScope.get("scopeProdName");
document1.save()
var Id:java.util.ArrayList=sessionScope.get("scopeDocID");
for(var x=0;x<Id.size();x++){
var doc=database.getDocumentByUNID(Id.get(x));
var newdoc:NotesDocument=doc.copyToDatabase(database);
newdoc.makeResponse(document1.getDocument());
newdoc.save();
}

Categories

Resources