Simple checkbox drawing program does not load - javascript

I'm creating a checkbox drawing program using HTML and JavaScript. It basically (at this early stage) involves drawing an 100 x 100 square of checkboxes. The problem is, every time I try to load the page, it doesn't load. It simply displays the spinning half circle (I'm using chrome) forever. Can you tell me what I'm doing wrong? Here is my code:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript">
function drawBoxes()
{
for(var i = 0;i<100;i++)
{
for(var j = 0;j<100;j++)
{
document.getElementById('drawarea').innerHTML += "<input type = 'checkbox'>";
}
document.getElementById('drawarea').innerHTML += "<br />";
}
}
</script>
<title>Checkbox drawer</title>
</head>
<body onload = "drawBoxes()">
<div id = "controlbar" style = "height:100px;float:top;background-color:#FF0000;"><p>hello</p></div>
<p id ="drawarea"></p>
</body>
</html>
UPDATE: After adding jcubic's catch of the <input> tag, the first <div> (in red) loads, but the checkboxes don't.

Instead of manipulating the DOM 100*100 times, just build a string and set the value once at the end of the loops:
var html = "";
for(var i = 0;i<100;i++)
{
for(var j = 0;j<5;j++)
{
html += "<input type = 'checkbox'>";
}
html += "<br />";
}
document.getElementById('drawarea').innerHTML = html;
Here's the JSFiddle to see that this load very quickly: http://jsfiddle.net/8hVBQ/

Related

Is there an error in my code or have I simply written it wrong?

I'm making a code where if you press the button after the name it will move to the other list. Pressing a button give me the error: "missing ) after argument list". I can't seem to find anything wrong in the code.
<!DOCTYPE html>
<html>
<title>Favoritter</title>
<body>
<p>Hotell</p>
<p id="hotellDiv"></p>
<p>Favoritter</p>
<p id="favDiv"></p>
</body>
<script>
let hotelliste = ["Norwegian Wild", "Stofjord Hotel", "Norefjell Ski og Spa", "Brikdalsbre Fjellstove", "Gudvangen Fjordtell"];
let favoritter = [];
skrivhliste();
skrivfliste();
function skrivhliste(){
document.getElementById("hotellDiv").innerHTML = "";
for (var j = 0; j < hotelliste.length; j++){
document.getElementById("hotellDiv").innerHTML += hotelliste[j] + "<input type=\"button\" onclick=\"leggTil("+hotelliste[j]+")\"><br>";
}
}
function skrivfliste(){
document.getElementById("favDiv").innerHTML = "";
for (var j = 0; j < favoritter.length; j++){
document.getElementById("favDiv").innerHTML += favoritter[j] + "<input type=\"button\" onclick=\"fjern("+favoritter[j]+")\"><br>";
}
}
function leggTil(hotell){
if (hotelliste.indexOf(hotell) > -1) {
hotelliste.splice(hotelliste.indexOf(hotell), 1);
}
favoritter.push(hotell);
skrivhliste();
}
function fjern(hotell){
if (favoritter.indexOf(hotell) > -1) {
favoritter.splice(favoritter.indexOf(hotell), 1);
}
hotelliste.push(hotell);
skrivfliste();
}
</script>
</html>
Look at this:
"<input type=\"button\" onclick=\"fjern("+favoritter[j]+")\">
What string are you going to end up with when you insert the value of favoritter[j]?
<input type="button" onclick="fjern(Norwegian Wild)">
There you don't have the string "Norwegian Wild", you have the variable Norwegian followed by a space followed by the variable Wild (and neither of those variables exist).
If you are programatically generating JavaScript then you need to generate the quotes that go around strings you generate.
This is hard to do well. Especially when that JS gets embedded in HTML that you are also generating on the fly. You have multiple levels of escape sequences to deal with.
Avoid generating strings like this. Use direct DOM methods instead.
For example:
Once, so it can be reused:
function clickHandler(event) {
const button = event.currentTarget;
const hotel = button.dataset.hotel;
leggTil(hotel);
}
Then inside your loop:
const button = document.createElement('input');
button.type = 'button';
button.value = 'display label';
button.dataset.hotel = hotelliste[j];
button.addEventListener('click', clickHandler);
document.getElementById("hotellDiv").appendChild(button);
Your code is ok, please make a string into onclick function like below.
Pass the value in single quotes into both onclick function.
document.getElementById("favDiv").innerHTML += favoritter[j] + "<input type=\"button\" onclick=\"fjern('"+favoritter[j]+"')\"><br>";

Issue with getting a keyup function to get sum of input field values using plain Javascript

I'm working on a personal project and I've run into an issue that I haven't been able to solve.
Here is a function that generates new table rows into a table (with id of "tableData") when a button is clicked:
function addNewRow(){
var tableEl = document.getElementById("tableData");
var newLine = '<tr class="newEntry">';
var classArray = ["classA", "classB", "classC", "classD"];
for (var i = 0; i < classArray.length; i++){
newLine += '<td><input class="' + classArray[i] + '"></td>';
}
newLine += '</tr>';
tableEl.insertAdjacentHTML("beforeend", newLine);
}
document.getElementById("addRow").addEventListener("click", addNewRow, false);
//the element with id="addRow" is a button
I've simplified the code for the above function for the sake of readability as it's not the focus of the problem. When the button is clicked, a new row is added successfully.
The problematic part involves another function that takes the sum of the respective classes of each row and displays them in a div.
The goal is to get the sum of the values of all input fields with matching class names. For example, let's say I use the addNewRow function to get six rows. Then I want to have the div showing the sum of the values of all input fields with the class name of "classA"; the number in that div should be the sum of those six values, which gets updated as I type in the values or change the existing values in any of the input fields with class name of "ClassA".
function sumValues(divId, inputClass){
var sumVal = document.getElementsByClassName(inputClass);
var addedUp = 0;
for (var j = 0; j < sumVal.length; j++){
addedUp += Number(sumVal[j].value);
}
document.getElementById(divId).innerHTML = addedUp;
}
Here are a couple (out of several) failed attempts:
document.input.addEventListener("keyup", sumValues("genericDivId", "classA"), false);
document.getElementsByClassName("classA").onkeyup = function(){sumValues("genericDivId", "classA");}
Unfortunately, after scouring the web for a solution and failing to find one, I just added an event listener to a button that, when clicked, would update the div to show the sum of values. Also had to modify the sumValues function to take values from an array rather than accepting arguments.
My question is: How can I modify the code so that the sum value updates as I type in new values or change existing values using pure Javascript (vanilla JS)?
You are very close, document.getElementsByClassName() returns an array of DOM objects, you need to set the onkeyup function for each and every element by looping through that array.
var classA = document.getElementsByClassName('classA'); // this is an array
classA.forEach(function(elem){ // loop through the array
elem.onkeyup = function(){ // elem is a single element
sumValues("genericDivId", "classA");
}
}
Hopefully this fixes your issue
Maybe the example below is not same with your situation, but you'll get the logic, easily. Anyway, do not hesitate to ask for more guide.
document.getElementById("row_adder").addEventListener("click", function() {
var t = document.getElementById("my_table");
var r = t.insertRow(-1); // adds rows to bottom - change it to 0 for top
var c = r.insertCell(0);
c.innerHTML = "<input class='not_important_with_that_way' type='number' value='0' onchange='calculate_sum()'></input>";
});
function calculate_sum() {
var sum = ([].slice.call(document.querySelectorAll("[type=number]"))).map(e=>parseFloat(e.value)).reduce((a, b) => a+b);
document.getElementById("sum").innerHTML = sum;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>
<p>
<strong>Sum</strong>:<span id="sum">0</span>
</p>
</div>
<button id="row_adder">
Click me
</button>
<table id="my_table">
</table>
</body>
</html>

Is there a way to display content on same page after a button is clicked?

I am trying to get my content to display on the same page as my button. But when i enter the values and press display the square i am forming is displayed on a new white webpage.
I ask the user to enter two values (height and width), I also ask for a character to form the border of the square, but i have not been able to do that part yet so i just hard coded a # character in for the border in the meantime
What i would like to know is how to display my square on the same page and not in a seperate page.
I use an external JavaScript file: Here is its code. Its named "SquareScript.js":
function Display()
{
var a = document.getElementById("value1").value;
var b = document.getElementById("value2").value;
var outputText = "";
for (var i = 0; i < a; i++)
{
outputText += "#";
}
outputText +="<br>";
for (var r = 0; r < b; r++)
{
outputText += "#";
for(var p = 0; p < a-2; p++)
{
outputText +="&nbsp&nbsp";
}
outputText += "#";
outputText +="<br>";
}
for (var i = 0; i < a; i++)
{
outputText += "#";
}
}
Here is my webpages code:
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" type = "text/css" href = "Assignment3.css">
<style>
table {background-color:white;color:black;}
body {background-image: url('squares.png');}
</style>
</head>
<body>
<div class = "heading">
<h1><img src = "Interested.png" width = 100px height = 100px></img>WELCOME TO BUILD A SQUARE</h1>
</div>
<script src = "SquareScript.js">
</script>
<table>
<tr>
<td>
Please Enter value number 1:&nbsp&nbsp<input type = "text" id = "value1">
</td>
</tr>
<tr>
<td>
Please Enter value number 2:&nbsp&nbsp<input type = "text" id = "value2">
</td>
</tr>
<tr>
<td>
Please Enter a character:&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<input type = "text" id = "character">
</td>
</tr>
<tr>
<td>
<button onclick = "Display()">Display</button>
</td>
</tr>
<div id="output" style = "background-color:blue;"><script>
document.getElementById("output").innerHTML(outputText);
</script></div>
</table>
</body>
</html>
Any useful tips will be appreciated and please consider the fact that I am still new to web development so my code is obviously very basic. Please let me know if you require anything more of me.
The way document.write() works is that when it's called outside the HTML page, it automatically creates a new document and writes into that (see the documentation). This is what's going on in your case: the function is called outside of the HTML (in SquareScript.js) and so it's making a new document, which is the "new white webpage" you're seeing.
You could solve this problem by calling document.write() from within the HTML page. Or you could forego using document.write() and instead reference an element on the existing page (a more flexible solution). By creating a new element in your HTML where the output of your functions should appear (like <div id="output"></div>), you can use document.getElementById("output") to put your script's output into that element.
You don't need to call this every time you want to add content. Instead, create a new variable to hold your output text as you generate it.
var outputText = "";
Then as you go through your loops, you can add to outputText:
for (var i = 0; i < a; i++) {
outputText += "#";
}
Then after all your loops are complete, you can insert the content into the output div by making the following function call as the last thing in your display() function:
document.getElementById("output").innerHTML(outputText);
Do not use document.write. Create <div id="result"></div> on your page and place your output there. You should create a string variable containing your HTML output. Then you can display this HTML using the following code:
document.getElementById("result").innerHTML = my_html_output;

Dynamically generating a button using DOM and editing onclick event

I trying to generate an input (type="button") and setting the onclick-Event to a function, which should hand over a parameter. The whole object should be appended to a div and thats it. Basically this is my try, but I can't see why it does not work.
I pasted the code to jsfiddle, hence its easier for you to reproduce. Click here.
What am I'm doing wrong? I'm learning it by trial and error, so please explain whats wrong. Thanks a lot!
[edit] for the case jsfiddle will be down one day, here is the code I tried to run... :)
<!doctype html>
<html>
<head>
<title>onclick event example</title>
<script type="text/javascript" language="javascript">
var i = 0;
var h = new Array();
function addButton() {
i++;
var container = document.getElementById("check0");
var h[i] = document.createElement("input");
h[i].type = 'button';
h[i].name = 'number' + i;
h[i].value = "number" + i;
h[i].id = 'number' + i;
h[i].onclick = function() {
showAlert(i)
};
container.appendChild(h[i]);
}
function showAlert(number) {
alert("You clicked Button " + number);
}​
</script>
</head>
<body>
<div id="check0">
<input type="button" value="klick mich" id="number0" onclick="addButton()"/>
</div>​
</body>
</html>
Here is the fixed fiddle for you.
var h[i] = ... is invalid JavaScript.
What you write in the "JavaScript" frame on jsfiddle is executed onload, so this code is not yet present when the HTML you provide is executed (and neither is the addButton() function).
<script>
var i = 0;
var h = new Array();
function addButton() {
i++;
var container = document.getElementById("check0");
h[i] = document.createElement("input");
h[i].type = 'button';
h[i].name = 'number' + i;
h[i].value = "number" + i;
h[i].id = 'number' + i;
h[i].onclick = function() {
showAlert(i)
};
container.appendChild(h[i]);
}
function showAlert(number) {
alert("You clicked Button " + number);
}
</script>
<div id="check0">
<input type="button" value="klick mich" id="number0" onclick="addButton()"/>
</div>​
Try using h.push(...) instead of trying to send to a non created element in the array
var x = document.getElementById('pagination');//pagination is an empty div in html
var y ='';
for(var i = 0; i <= (pageMax); i++){
y = y+"<a id ='pageNumber"+i+"' onclick='changePage("+(i+1)+");'>"+(i+1)+"</a>\n ";
} x.innerHTML=y }
i used this to make a pagination for a table. The function will create a row of numbers until button max. 'changePage("+(i+1)+"); ... will call a function and send the i index(number that the page is) of the pagenumber. also i dynamically create a id unique for each number.

Javascript and CSS working on Firefox but not working on IE

I have this code which working on Firefox but not working on IE missing last character on IE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>wrapped</title>
<script type="text/javascript" language="javascript">
function set_padd(){
var tt = document.getElementById("span_padding").innerHTML;
var txt = new Array();
txt = tt.split(" ");
var atxt = '';
var f_txt = '';
var wrd_pr_linr = 4;
var cnt = 1;
for(var i = 0; i < txt.length; i++){
if(txt[i].length > 0){
txt[i] = txt[i].replace(' ','');
if(cnt < wrd_pr_linr){
if(txt[i].length > 0){
atxt += ' '+txt[i].replace(' ','');
cnt++;
}
}else{
f_txt += '<a class="padd_txt" >'+atxt+'</a><br />';
atxt = '';
cnt = 1;
}
}
}
document.getElementById("span_padding").innerHTML = f_txt;
}
</script>
<style type="text/css">
.padd_txt{padding:7px;background:#009;color:#FFF;line-height:26px;font-size:14px;}
body{font-family:'Trebuchet MS', Arial, Helvetica, sans-serif; font-size:24px; line-height:1.2em;}
span{background-color: #009; width:200px; color: #FFF;" class="blocktext;}
</style>
</head>
<body onload="set_padd();">
<div style="width: 350px;">
<p>
<span id="span_padding">
This is what I want to
happen where one
long string is wrapped
and the text has this
highlight color behind
it.
</span>
</div>
</body>
</html>
Output on Firefox is:
This is
I want to
happen where one
string is wrapped
and the text
this highlight
behind it.
and output on IE:
This is what
want to happen
one long string
wrapped and the
has this highlight
missing last two words.
The results are different on IE and Firefox because of IE's habit of throwing away whitespace around tags. But your function is broken on both browsers, as it throws away the last word of each line and potentially the whole last line without ever outputting it.
Seems a bit laborious too. How about using a regex to match each group of up to four words:
function set_padd() {
var span= document.getElementById('span_padding');
var text= span.firstChild.data;
span.innerHTML= '';
var lines= text.match(/\S+(\s+\S+){0,3}/g);
for (var i= 0; i<lines.length; i++) {
var el= document.createElement('a');
el.className= 'padd_txt';
el.appendChild(document.createTextNode(lines[i]));
span.appendChild(el);
span.appendChild(document.createElement('br'));
}
}
There are several obvious problems with your code:
In your i, where cnt < wrd_pr_linr is false, you're resetting the count and wrapping a span around the current atxt, but you're not doing anything with txt[i], so it's missed off as the increment increases on the next turn around. You could fix this by adding i--; after cnt++;.
If your loop terminates whilst cnt < wrd_pr_linr is true, your else statement that creates the DOM string will not be executed and the value of atxt is just ignored. You need to run the same code block when your if statement is about to terminate.
If it were me, I'd look into a much neater, simpler, regex based solution:
function set_padd(){
var f_txt;
var tt = document.getElementById("span_padding").innerHTML;
// replace every third space with "{!BREAK!}"
tt = tt.replace(/(.*?\s+.*?\s+.*?)\s+/g, "$1{!BREAK!}");
// Splitting on that string creates an array with 3 words in each index
tArr = tt.split("{!BREAK!}");
// Join the array again with the HTML you need between each index
f_txt = tArr.join('</a><br/><a class="padd_txt">');
// Wrap the text with the start tag and the end tag
f_txt = '<a class="padd_txt">' + f_txt + '</a>';
// Viola!
document.getElementById("span_padding").innerHTML = f_txt;
}
Take out the comments, swap the regex for something similar to bobince's and you can get it to look really small:
function set_padd(){
var tt = document.getElementById("span_padding").innerHTML;
var f_txt = '<a class="padd_txt">'
+ tt.match(/\S+(\s+\S+){0,2}/g)
.join('</a><br/><a class="padd_txt">')
+ '</a>';
document.getElementById("span_padding").innerHTML = f_txt;
}

Categories