Alright, so I have been killing myself over this for a while now. I simply want to take an XML response containing names from my arduino and then dynamically create buttons. Each button needs to say the name and have the name as its id for the GetDrink function to use to send back to the arduino. If anyone can give me some help, maybe some code to work off of it would be appreciated.
I am able to have a button call the CreateButton function to create more buttons which all work. But I need to dynamically create the buttons off of the XML response. Also, this has to be done strictly using JavaScript and HTML.
<!DOCTYPE html>
<html>
<head>
<title>The AutoBar</title>
<script>
// Drinks
strDRINK1 = "";
function GetArduinoIO()
{
nocache = "&nocache=" + Math.random() * 1000000;
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
var count;
var num_an = this.responseXML.getElementsByTagName('alcohol').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("AlcStatus")[count].innerHTML =
this.responseXML.getElementsByTagName('alcohol')[count].childNodes[0].nodeValue;
}
}
}
}
}
request.open("GET", "ajax_inputs" + strDRINK1 + nocache, true);
request.send(null);
setTimeout('GetArduinoIO()', 1000);**strong text**
strDRINK1 = "";
}
function GetDrink(clicked_id)
{
strDRINK1 = "&" + clicked_id;
document.getElementById("AlcStatus").innerHTML = "Your " + clicked_id + " is being made";
}
function CreateButton(Drink_Name)
{
myButton = document.createElement("input");
myButton.type = "button";
myButton.value = Drink_Name;
placeHolder = document.getElementById("button");
placeHolder.appendChild(myButton);
myButton.id = Drink_Name;
myButton.onclick = function()
{
strDRINK1 = "&" + myButton.id;
document.getElementById("AlcStatus").innerHTML = "Your " + myButton.id + " is being made";
}
}
</script>
<style>
.IO_box {
float: left;
margin: 0 20px 20px 0;
border: 1px solid blue;
padding: 0 5px 0 5px;
width: 320px;
}
h1 {
font-size: 320%;
color: blue;
margin: 0 0 10px 0;
}
h2 {
font-size: 200%;
color: #5734E6;
margin: 5px 0 5px 0;
}
p, form, button {
font-size: 180%;
color: #252525;
}
.small_text {
font-size: 70%;
color: #737373;
}
</style>
</head>
<body onload="GetArduinoIO()" BGCOLOR="#F5F6CE">
<p> <center><img src="pic.jpg" /></center><p>
<div class="IO_box">
<div id="button"></div>
</div>
<div class="IO_box">
<h2><span class="AlcStatus">...</span></h2>
</div>
<div>
<button onclick="location.href='Edit_Bar.htm'">Edit Bar Menu</button>
<div>
</body>
</html>
Something like this?
var xml = "<items><alcohol>Bourbon</alcohol><alcohol>Gin</alcohol><alcohol>Whiskey</alcohol></items>";
var parser = new DOMParser();
var dom = parser.parseFromString(xml, "text/xml");
var alcohol = dom.querySelectorAll('alcohol');
function getDrink(event) {
alert(event.target.value);
}
function makeButton(value) {
var b = document.createElement('button');
b.innerHTML = value;
b.value = value;
b.id = value;
b.addEventListener('click', getDrink);
return b;
}
var list = document.getElementById('buttons');
for(var i = 0; i < alcohol.length; i++ ) {
var b = makeButton(alcohol[i].firstChild.nodeValue);
var li = document.createElement('li');
li.appendChild(b);
list.appendChild(li);
}
<ul id="buttons"></ul>
Related
I want to add 10 points when blue box goes into brown box.
I tried to set score = 0 and points to add = 10 but it doesn't work.
I alert '+10 points' and it shows me the alert so I guess the problem is the DOM ?!?
Any suggestions ?
Thanks !
let moveCounter = 0;
let score = 0;
let obs = 10;
document.getElementById('score').textContent = '0';
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 49; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var obstacles = [];
while (obstacles.length < 10) {
var randomIndex = parseInt(49 * Math.random());
if (obstacles.indexOf(randomIndex) === -1) {
obstacles.push(randomIndex);
var drawObstacle = document.getElementById('square' + randomIndex);
$(drawObstacle).addClass("ob")
}
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(49 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var drawPone = document.getElementById('square' + randomIndex);
$(drawPone).addClass("p-0")
}
}
var addPoints = $('#score');
$('#button_right').on('click', function() {
if ($(".p-0").hasClass("ob")) {
alert('add +10 points !!!')
addPoints.text( parseInt(addPoints.text()) + obs );
}
moveCounter += 1;
if ($(".p-0").hasClass("ob")) {
}
$pOne = $('.p-0')
$pOneNext = $pOne.next();
$pOne.removeClass('p-0');
$pOneNext.addClass('p-0');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.ob {
background-color: brown;
}
.p-0 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box">
</div>
<div class="move">
<button id="button_right">right</button><br>
</div>
<div id="score">
</div>
Thank you very much! I am new to JavaScript/ JQuery
Thank you very much!
You are trying to change the HTML inside of the div with id "score".
Selecting the css element using $("#id") retrieves the DOM element and not its contents so adding the score directly to it has no consequences.
What you want to do is: update the score variable and then set the HTML inside the div to the score value.
So instead of just:
addPoints += obs
you should
score += obs
addPoints.html(score)
I have been trying to create a system that when I hover over a specific div, specific text relating to that div appears. Each div is in the same class, with info at a different div with corresponding indexes. I was wondering if there was any way that I could get the class index of each div by hovering over them in order to show hidden information about them. (by showing the hidden info divs).
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
var allPeople = [];
function win (name, info){
this.name = name;
this.info = info;
}
allPeople[0] = new win ("Shelly", "Is Cool");
allPeople[1] = new win ("Brandon", "Likes to golf");
allPeople[2] = new win ("Steve", "Plays Football");
allPeople[3] = new win ("Mia", "Is a good cook");
var i = 0;
$('document').ready(function(){
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='people'> " + allPeople[i].name +" </div>");
}
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='info'> " + allPeople[i].info +" </div>");
}
});
</script>
<style>
body {
background-color: lightblue;
}
div {
background-image: url("http://themes.wdfiles.com/local--files/semi-trans/semi-transbgtransparent.png");
color: white;
padding: 2%;
margin: 2%;
border: 3px white solid;
}
.info {
display: none;
border-color: red;
}
</style>
</head>
<body>
</body>
</html>
A simple solution can be based on saving the index of each div at creation time as a data attribute like:
$("body").append("<div class='people' data-index='" + i +"'> " + allPeople[i].name +" </div>");
var allPeople = [];
function win (name, info){
this.name = name;
this.info = info;
}
allPeople[0] = new win ("Shelly", "Is Cool");
allPeople[1] = new win ("Brandon", "Likes to golf");
allPeople[2] = new win ("Steve", "Plays Football");
allPeople[3] = new win ("Mia", "Is a good cook");
var i = 0;
$('document').ready(function(){
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='people' data-index='" + i +"'> " + allPeople[i].name +" </div>");
}
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='info' data-index='" + i +"'> " + allPeople[i].info +" </div>");
}
$('.people').hover(function(e) {
$('.info').eq($(this).data('index')).show();
}, function(e) {
$('.info:visible').hide();
});
});
body {
background-color: lightblue;
}
div {
background-image: url("http://themes.wdfiles.com/local--files/semi-trans/semi-transbgtransparent.png");
color: white;
padding: 2%;
margin: 2%;
border: 3px white solid;
}
.info {
display: none;
border-color: red;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
You can use jQuery.index():
var allPeople = [];
function win (name, info){
this.name = name;
this.info = info;
}
allPeople[0] = new win ("Shelly", "Is Cool");
allPeople[1] = new win ("Brandon", "Likes to golf");
allPeople[2] = new win ("Steve", "Plays Football");
allPeople[3] = new win ("Mia", "Is a good cook");
var i = 0;
$('document').ready(function(){
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='people'> " + allPeople[i].name +" </div>");
}
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='info'> " + allPeople[i].info +" </div>");
}
$('.people').hover(function(e) {
$('.info').eq($(this).index() % 4).show();
}, function(e) {
$('.info').eq($(this).index() % 4).hide();
});
});
body {
background-color: lightblue;
}
div {
background-image: url("http://themes.wdfiles.com/local--files/semi-trans/semi-transbgtransparent.png");
color: white;
padding: 2%;
margin: 2%;
border: 3px white solid;
}
.info {
display: none;
border-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A different approach can be based on filtering the array elements (Array.prototype.filter()) in order to get the index of corresponding div.
var allPeople = [];
function win (name, info){
this.name = name;
this.info = info;
}
allPeople[0] = new win ("Shelly", "Is Cool");
allPeople[1] = new win ("Brandon", "Likes to golf");
allPeople[2] = new win ("Steve", "Plays Football");
allPeople[3] = new win ("Mia", "Is a good cook");
var i = 0;
$('document').ready(function(){
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='people'> " + allPeople[i].name +" </div>");
}
for (i = 0; i < allPeople.length; i++){
$("body").append("<div class='info'> " + allPeople[i].info +" </div>");
}
$('.people').hover(function(e) {
var txt = this.textContent.trim();
var peopleInfoIDX = 0;
allPeople.forEach(function(ele, idx) {
if (ele.name == txt)
peopleInfoIDX = idx;
});
$('.info').eq(peopleInfoIDX).show();
}, function(e) {
$('.info:visible').hide();
});
});
body {
background-color: lightblue;
}
div {
background-image: url("http://themes.wdfiles.com/local--files/semi-trans/semi-transbgtransparent.png");
color: white;
padding: 2%;
margin: 2%;
border: 3px white solid;
}
.info {
display: none;
border-color: red;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
Rather than having a linear set of divs where some are people and others are info, you can nest the info with its corresponding people div so that you can target the correct info with CSS.
HTML:
<div class="people-container">
<div class="people">Shelly</div>
<div class="info">Is Cool</div>
</div>
CSS:
.people-container:hover .info {
display: block;
}
So when someone hovers over the person's name, the info can be shown.
Your easiest and non-messy solution would be to output the index onto the div using a data-index attribute.
$("body").append("<div class='people' data-index="+ i +"> " + allPeople[i].name +" </div>");
and later retrieve the data-attribute value with
console.log($(e.target).data('index'))
I have made 24 buttons with a for loop, and want button from number 1 to 24 to give a message like this.
"you clicked on button 1"
"you clicked on button 2" and so on.
I have been able to split the 3 first buttons so they say "button 1" "2" "3", but that is done by 3 if statements, which means i would need 23-24 ish if statements to get them all to do as I want. That's not a very efficient way to do it.
Is there a good way to get the button id to add +1 after "knapp" every time the loop runs ? something like this element.id = "knapp" + 1; < so the id become knapp1, knapp2, knapp3 as the loop keep running 24 times ?
html:
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<script src="Assignment06.js"></script>
<style>
h1 {
text-align: center;
}
div {
background-color: forestgreen;
border: solid 1px #000;
display: inline-block;
width: 100px;
height: 100px;
padding: 10px
}
#panel {
width: 610px;
margin: 0 auto;
}
</style>
</head>
<body>
<h1>Assignment06</h1>
<p id = "panel"></p>
</body>
</html>
Javascript:
function dag(){
knapp = window.alert("Du trykket knapp 1");
}
function dag2(){
window.alert("Du trykket knapp 2");
}
function dag3(){
window.alert("Du trykket knapp 3");
}
function init(){
knapper();
}
function knapper(){
for (var antall = 1; antall <= 24; antall++){
if(antall == 1){
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp";
knapp = element.addEventListener("click", dag);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
else if (antall == 2){
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp2";
knapp2 = element.addEventListener("click", dag2);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
else{
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp3";
knapp3 = element.addEventListener("click", dag3);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
}
}
window.onload = init;
You can save the id in the dataset of the <div /> element.
function knapper() {
var panel = document.getElementById("panel");
for (var antall = 1; antall <= 10; antall++) {
var element = document.createElement("div");
element.innerHTML = antall;
element.dataset.id = antall;
element.addEventListener("click", dag);
panel.appendChild(element);
}
}
function dag(evt) {
alert(evt.target.dataset.id);
}
window.onload = knapper;
#panel div {
width: 50px;
height: 50px;
border: solid 1px black;
float: left;
}
<div id="panel"></div>
To directly answer your question without suggestions:
You already have a counter in the for loop (antall). You can just use that variable and concatenate it on the end of the string that you're using as an id.
element.id = "knapp" + antall;
I want to upload folder to server by d'n'd via AJAX. But already, I have troubles with upload files.
I use e.dataTransfer.items and webkitGetAsEntry() to check - is it file or folder?
If it's file, in function traverseFileTree I get file, but I can't append it to formData.
If I use e.dataTransfer.files, I don't know what is it. File or Folder because webkitGetAsEntry() get error.
What I do wrong?
How transfer files to global array $_FILES.
Source (upload.php):
echo "<pre>";
print_r ($_FILES);
echo "</pre>";
Source (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop</title>
<style>
body {
background: rgba(211,211,100, .5);
font: 20px Arial;
}
.dropzone {
width: 300px;
height: 300px;
border: 2px dashed #aaa;
color: #aaa;
line-height: 280px;
text-align: center;
position: absolute;
left: 50%;
margin-left: -150px;
top: 50%;
margin-top: -150px;
}
.dropzone.dragover {
color: green;
border: 2px dashed #000;
}
</style>
</head>
<body>
<p>Loaded files:</p>
<div id="uploads">
<ul>
</ul>
</div>
<div class="dropzone" id="dropzone">Drop files</div>
<script>
(function() {
var formData = new FormData();
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(e) {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
e.preventDefault();
upload(e.dataTransfer.items);
};
function traverseFileTree(item, path) {
path = path || "";
if (item.isFile) {
item.file(function(file) {
console.log(file); // show info
formData.append('file[]', file); // file exist, but don't append
});
} /*else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(function(entries) {
for (var i=0; i<entries.length; i++) {
traverseFileTree(entries[i], path + item.name + "/");
}
});
}*/
}
var upload = function(items) {
var xhr = new XMLHttpRequest();
for(var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree(item,'');
}
}
xhr.onload = function() {
console.log(this.responseText);
};
xhr.open('post', 'upload.php');
xhr.send(formData);
};
dropzone.ondragover = function() {
this.className = 'dropzone dragover';
this.innerHTML = 'Mouse up';
return false;
};
dropzone.ondragleave = function() {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
return false;
};
})();
</script>
Both file() and readEntries() return results asynchronously. Since it is impossible to know for certain how many files or directories, which themselves could contain additional directories containing still more files or folders, will be selected and dropped by user, the a single or recursive calls to traverseFileTree require some mechanism to determine when all asynchronous operations have completed. This can be achieved using one or more of several approaches.
The present approach increments a variable n, pushes each individual file to an array uploads. If n is 0, process the first file; increment n so that its value 1 greater than the array containing files .length until the array .length is equal to n - 1
uploads.length === n - 1 || n === 0
then copy uploads array using .slice(), set uploads.length and n to 0, pass array of files to function processFiles where files are appended to FormData() object, call to XMLHttpRequest() is made.
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop</title>
<style>
body {
background: rgba(211, 211, 100, .5);
font: 20px Arial;
}
.dropzone {
width: 300px;
height: 300px;
border: 2px dashed #aaa;
color: #aaa;
line-height: 280px;
text-align: center;
position: absolute;
left: 50%;
margin-left: -150px;
top: 50%;
margin-top: -150px;
}
.dropzone.dragover {
color: green;
border: 2px dashed #000;
}
</style>
</head>
<body>
<p>Loaded files:</p>
<div id="uploads">
<ul>
</ul>
</div>
<div class="dropzone" id="dropzone">Drop files</div>
<script>
(function() {
var n = 0, uploads = [];
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(e) {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
e.preventDefault();
upload(e.dataTransfer.items);
};
function processFiles(files) {
console.log("files:", files);
alert("processing " + files.length + " files");
var formData = new FormData();
// append files to `formData`
for (file of files) {
formData.append("file[]", file, file.name)
}
// check `formData` entries
var curr = 0;
for (data of formData.entries()) {
console.log("formData entry " + curr, data);
++curr;
}
delete curr;
// do ajax stuff here
var xhr = new XMLHttpRequest();
xhr.onload = function() {
console.log(this.responseText);
};
xhr.open("POST", "upload.php");
xhr.send(formData);
}
function traverseFileTree(item, path) {
var handleFiles = function handleFiles(item, path) {
path = path || "";
if (item.isFile) {
item.file(function(file) {
uploads.push(file);
console.log(file, n, uploads.length); // show info
if (uploads.length === n - 1 || n === 0) {
alert("traverseFiles complete, uploads length: "
+ uploads.length);
var files = uploads.slice(0);
n = uploads.length = 0;
processFiles(files)
}
});
} else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(function(entries) {
// increment `n` here
n += entries.length;
for (var i = 0; i < entries.length; i++) {
handleFiles(entries[i], path + item.name + "/");
}
});
}
}
handleFiles(item, path);
}
var upload = function(items) {
if (n !== 0 && uploads.length !== 0) {
n = uploads.length = 0;
}
for (var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree(item, "");
}
}
};
dropzone.ondragover = function() {
this.className = 'dropzone dragover';
this.innerHTML = 'Mouse up';
return false;
};
dropzone.ondragleave = function() {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
return false;
};
})();
</script>
</body>
</html>
plnkr http://plnkr.co/edit/OdFrwYH2gmbtvHfq3ZjH?p=preview
See also How can I filter out directories from upload handler in Firefox? , How to read files from folder
I'm making a syntax highlighter in Javascript and HTML. It works fine at the moment but I think it's really inefficient because I have an interval with a time of 0 which runs a function that loops through all of the characters in the text area and then inserts them into a div behind the text area to provide the syntax highlighting.
I think my lexer is really bad too, but at the moment I'm more concerned with the function running like a million times a second that loops through every character in the text area each time.
Can anyone please think of a more efficient way to do this?
There doesn't seem to be any performance problems but I'm not sure if it will work on a lower-powered machine because I don't want it to crash the browser tab because I want to have several on a page so I need it to be as efficient as possible.
I understand that its annoying to be given loads of code and asked to help, but I thought for the problem to be easiest to debug you'd need the entire code.
Here you code:
<html>
<head>
<title>My Syntax Highlighter</title>
<style type="text/css">
#container {
width: 100%;
height: 100%;
position: relative;
padding: 0px;
}
#code {
width: 100%;
height: 100%;
outline:none;
position: absolute;
background-color: transparent;
border: none;
font-family: Courier;
font-size: 22px;
color: rgba(0,0,0,.2) !important;
}
#codeb {
width: 100%;
height: 100%;
position: absolute;
font-family: Courier;
font-size: 22px;
padding: 2px 2px;
color: #000;
}
.keyword {
/*font-weight: bold;*/
color: #E42D82;
}
.string {
/*font-weight: bold;*/
color: #0086b3;
}
</style>
<script type="text/javascript">
function u() {
var code = document.getElementById("code");
var codeb = document.getElementById("codeb");
var c = "";
var tok = "";
var cc = 0;
var t = "";
var takeaway = 0;
var stringStarted = false;
var string = "";
for (var i = 0; i < code.value.length; i++) {
tok += code.value[i];
c += code.value[i];
cc++;
if (tok == "print") {
t = "<span class=\"keyword\">print</span>";
takeaway += 5;
c = c.substring(0, cc - takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "var") {
t = "<span class=\"keyword\">var</span>";
takeaway += 3;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
} else if (tok == "\"") {
tok = "";
if (stringStarted == false) {
stringStarted = true;
string += "\"";
} else {
stringStarted = false;
string += "\"";
t = "<span class=\"string\">" + string + "</span>";
takeaway += string.length;
c = c.substring(0, cc-takeaway) + t + c.substring(cc + t.length);
cc += t.length;
tok = "";
string = "";
}
tok = "";
} else if (tok == " ") {
if (stringStarted == true) {
string += " ";
}
c+= "";
tok = "";
} else {
if (stringStarted == true) {
string += code.value[i];
tok = "";
}
}
codeb.innerHTML = c;
//console.log("test");
};
//alert(string);
if (code.value == "") {
codeb.innerHTML = "";
}
clearI(setInterval(function(){ u(); }, 0));
}
function clearI(interval) {
clearInterval(interval);
}
var interval = setInterval(function(){ u(); }, 0);
</script>
</head>
<body>
<div id="container">
<div id="codeb"></div>
<textarea id="code" autofocus></textarea>
</div>
</body>
</html>