How to create a huge table of checkboxes (I mean HUGE!) - javascript

I am busy creating a website where a user has to select some checkboxes from a huge matrix of checkboxes. 100 by 100 = 10 000 boxes to be more specific!
The way I have set out doing this is by creating 100 vertical divs, each with 100 checkboxes in them.
This seems to work OK but it ends up being a HUGE amount of code! So much, that when I hit refresh in Dream Weaver, it crashes!
I'm pretty new at HTML and Javascript. Is there a better way of doing this??
I included a very small basic example of what I have done
<html lang="en"><head><meta name="generator" content="PSPad editor, www.pspad.com">
<title>Checkbox No Vertical Space</title>
<style type="text/css">
#aDiv,
#bDiv,
#cDiv{
float:left;
width:12px;
}
#aDiv input,
#bDiv input,
#cDiv input{
clear:left;
float:left;
margin:0;
padding:0;
width:12px;
height:12px;
}
</style></head><body>
<div id="aDiv">
<input type="checkbox" value="a1">
<input type="checkbox" value="a2">
<input type="checkbox" value="a3">
<input type="checkbox" value="a4">
<input type="checkbox" value="a5">
<input type="checkbox" value="a6">
</div>
<div id="bDiv">
<input type="checkbox" value="b1">
<input type="checkbox" value="b2">
<input type="checkbox" value="b3">
<input type="checkbox" value="b4">
<input type="checkbox" value="b5">
<input type="checkbox" value="b6">
</div>
<div id="cDiv">
<input type="checkbox" value="c1">
<input type="checkbox" value="c2">
<input type="checkbox" value="c3">
<input type="checkbox" value="c4">
<input type="checkbox" value="c5">
<input type="checkbox" value="a6">
</div>
</body></html>
Thanks!
Allan

This code performs well:
var i, j, div, cb, frag;
frag = document.createDocumentFragment();
cb = document.createElement( 'input' );
cb.type = 'checkbox';
for ( i = 0; i < 100; i += 1 ) {
div = document.createElement( 'div' );
for ( j = 0; j < 100; j += 1 ) {
div.appendChild( cb.cloneNode( false ) );
}
frag.appendChild( div );
}
document.body.appendChild( frag );
Live demo: http://jsfiddle.net/Kyswa/1/show/
(although my machine has performance issues when scrolling the page)

I went ahead and made a jQuery version of this, and made sure the width was dynamically calculated to ensure that you have 100x100 checkboxes cross browser. I also added some html5 data attributes to the checkboxes, so you wont have to calculate it every time. Also, there's a single event hooked up to a containing div, so events will perform well. Here's the code:
HTML
<div id="checkboxes">
</div>​
CSS
#checkboxes {
line-height: 0;
}
#checkboxes input[type="checkbox"] {
margin: 0px;
padding: 0px;
}​
JavaScript + jQuery 1.7
$(function(){
var target = $('#checkboxes');
var x, y, checkbox;
for(x = 0; x < 100; x++)
{
for(y = 0; y < 100; y++)
{
checkbox = $('<input></input>', {
'type': 'checkbox',
'data-x': x,
'data-y': y
});
target.append(checkbox);
}
}
target.width(checkbox.outerWidth() * 100);
target.on('change', 'input:checkbox', function(){
var $this = $(this),
x = $this.data('x'),
y = $this.data('y'),
checked = $this.prop('checked');
alert('checkbox changed (' + x + ', ' + y + '): ' + checked);
});
});​
Example
http://jsfiddle.net/xixonia/Uq7CU/1/
Here's a fun version where you can draw by moving your mouse over the checkboxes:
http://jsfiddle.net/xixonia/Uq7CU/2/

This may not be proper HTML or follow recommended guidelines, but you could use a <table></table>. Get rid of your <div></div>'s, make one <div></div> with an id of "grid", and add this to your javascript:
var grid = "";
grid += "<table>";
for (var row = 0; row < 100; row++)
{
grid += "<tr>";
for (var col = 0; col < 100; col++)
{
grid += "<td>";
grid += "<input type='checkbox' value='" + row + "-" + col + "'>";
grid += "</td>";
}
grid += "</tr>";
}
grid += "</table>";
document.getElementById("grid").innerHTML = grid;
Please let me know if this doesn't work or if it has any errors!

Do you have to have checkboxes?
<!doctype html>
<html lang="en">
<head>
<meta charset= "utf-8">
<title>Small Page</title>
<style>
table{layout:fixed;width:95%;margin:0 auto;}
td{border:ridge thin gray;width:1%;font-size:8px;color:white;background-color:white;padding:0}
td:hover{background-color:blue}
input{font-size:smaller}
</style>
</head>
<body>
<h1>Boxes<br>
<input type="text" size="20" value=""></h1>
<script>
onload= function(){
document.getElementsByTagName('table')[0].onclick= function(e){
e= e || window.event;
var r= 0, c= 0, row, col,
who= e.target || e.srcElement,
msg= document.getElementsByTagName('input')[0];
if(who.tagName== 'TD'){
who.style.backgroundColor= 'red';
msg.value= who.id.replace('r','row: ').replace('c',' col: ');
}
}
}
var r= 1, c= 1, str= '<table cellspacing="0" cellpadding="0">\n<tbody>';
while(r<101){
str+= '\n<tr>';
c= 1;
while(c<101){
str+= '<td id="r'+r+'c'+c+'">x</td>';
++c;
}
str+= '</tr>';
++r;
}
str+='</tbody>\n</table>\n';
document.write(str);
</script>
<br>
</body>
</html>

Related

Loop error on <fieldset> tags - inserting closing tag before it should

As part of a web app I'm building in Google Apps Script, I'm trying to create a checkbox field that shows one checkbox for each learner/student, arranged in rows of 3. The learner data is being taken from a spreadsheet (this bit is working fine).
I want the checkboxes to look like this:
image of 6 checkboxes, in 2 rows of 3
The problem I am having is that my code is inserting the closing fieldset tag in the wrong place (too early) and so the checkboxes don't look right (I'm using the jquery mobile 1.4.5 framework).
I've been staring at the code and tinkering with it for hours, I'm hoping it's something simple I just can't see and hoping someone can help me fix it.
The code I am using is basically a nested loop - the outer loop should create the fieldset tags for each row, and the inner loop should create each checkbox. My code is as follows:
First the container div
<div id="learners">Loading...</div>
The javascript to grab the data and replace the container div above with it...
// The code in this function runs when the page is loaded.
$(function() {
google.script.run.withSuccessHandler(showLearners)
.getLearnerData();
});
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
for (var i = 0; i < learners.length; i++) {
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\">");
for (var j = 0; j < 3; j++) {
learnerCheckboxes.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"<label for=\"learner" + i + "\">" + learners[i][0] + "</label>" +
"</div>"
);
i++
}
learnerCheckboxes.append("</fieldset>");
}
}
The problem is, when the code runs, the closing </fieldset> is inserted too early... here's the output from this code:
<div id="learners">
<fieldset class="ui-grid-b">
</fieldset><!-- THIS IS THE PROBLEM - IT SHOULD BE AT THE BOTTOM OF THIS GROUP?-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner0" data-mini="true">
<label for="learner0">David</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner1" data-mini="true">
<label for="learner1">Dominic</label>
</div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner2" data-mini="true">
<label for="learner2">Eliza</label>
</div>
<fieldset class="ui-grid-b">
</fieldset><!-- THIS SHOULD BE AT THE BOTTOM OF THIS GROUP-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner4" data-mini="true">
<label for="learner4">Francois</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner5" data-mini="true">
<label for="learner5">James</label></div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner6" data-mini="true">
<label for="learner6">Louise</label>
</div>
</div>
It took a lot of trial and error because I don't use jquery. I do it the old fashion way. But I finally got it to work. You can play with the CSS to get it to look like you want.
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div id="learners">Loading...</div>
<script>
(function() {
google.script.run.withSuccessHandler(showLearners).getLearnerData();
})();
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
let i = 0;
while( i < learners.length ) {
let id = "fieldset"+i;
let fieldset = $('<fieldset class="ui-grid-b" id="'+id+'"></fieldset>')
learnerCheckboxes.append(fieldset);
for (var j = 0; j < 3; j++) {
let div = $('<div class="ui-block-' + cols[j] + '"></div>')
fieldset.append(div);
id = "learner"+i;
let input = $('<input type="checkbox" name="learner" id="' + id + '" data-mini="true">');
let label = $('<label for="' + id + '">' + learners[i][0] + '</label>' );
div.append(input);
div.append(label);
i++;
if( i === learners.length ) break;
}
}
}
</script>
</body>
</html>
Code.gs
function getLearnerData() {
try {
Logger.log("In getLearnerData");
return [["Dave"],["Tom"],["Larry"],["Mary"],["Joe"],["Sam"],["John"]];
}
catch(err) {
Logger.log("Error in getLearnerData: "+err);
}
}
Results
Thanks TheWizEd for the idea to dynamically name the fieldset tags - this is what lead to the solution. By dynamically creating the fieldset ID, I can use the inner loop to append the checkboxes BETWEEN the fieldset tags. Here's the code:
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
var rowCount = 1;
for (var i = 0; i < learners.length; i++) {
//in this next line, use rowCount to create a unique fieldset id
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\" id=\"checkRow" + rowCount + "\"></fieldset>");
//then grab it
var checkRow = $("#checkRow" + rowCount)
for (var j = 0; j < cols.length; j++) {
//and append the checkboxes to the newly created fieldset
checkRow.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<div class=\"ui-checkbox ui-mini\">" +
"<label for=\"learner" + i + "\" class=\"ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-checkbox-off\">" +
learners[i][0] + "</label>" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"</div>" +
"</div>"
);
i++;//we're in the inner loop, so have to manually increment i
}
rowCount++;
}
}

Editable table not working

I made a table that you can add text to and edit it inside it.
However if you add more than three rows, It is stuck and not working anymore.
The errors comes from here:
document.getElementById('vda' + z).addEventListener('click', doSomething);
document.getElementById('cvda' + z).addEventListener('click', doSomething2);
It is only adding event listener to the last row added, so if you add more than one row. The not last row won't have a working edit button.
I checked the IDs by inspecting the edit and update buttons elements.
Try adding 3 rows then click on the edit button for one of the row.
you can look at the code here and also https://jsfiddle.net/3e6d4qsv/
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
</head>
<body>
<div style="display:inline-flex;">
<form id="myForm">
<input id="inptext" type="text" placeholder="Your name..."></input>
<input id="inpadress" style="margin-left: 10px;" type="text" placeholder="Your email..."></input>
</form>
<button onclick="myFunction()"style="margin-left: 10px;" id="box">Add</button>
</div>
<br>
<div style="display: inline-flex">
<table id="tablename" style="width:80%; margin-top:15px;">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</table>
<div id="buttons" style="float:right;width: 300px; margin-top:50px;">
</div>
</div>
<script>
var z = 1;
function myFunction() {
var x = document.getElementById("inptext").value;
var y = document.getElementById("inpadress").value;
var form = document.getElementById("myForm");
form.reset();
document.getElementById("tablename").innerHTML = document.getElementById("tablename").innerHTML + '<tr><td id=acvda'+ z + '>' + x + '</td><td id=zcvda' + z + '>' + y + '</td></tr>';
var h = '<button style="margin-left:8px" class="edit" id=vda' + z + '>Edit</button>';
var f = '<div id=zzza'+z+' style=height:10px></div>';
var abc = '<button style="margin-left:-36px" class="update" id="cvda'+z+'">Update</button>';
var total = h + abc + f;
document.getElementById("buttons").innerHTML = document.getElementById("buttons").innerHTML + total;
document.getElementById('vda' + z).addEventListener('click', doSomething);
document.getElementById('cvda' + z).addEventListener('click', doSomething2);
document.getElementById('cvda' + z).style.visibility='hidden';
z = z + 1;
}
function doSomething() {
document.getElementById("inptext").value = document.getElementById("ac"+this.id).innerHTML;
document.getElementById("inpadress").value = document.getElementById("zc"+this.id).innerHTML;
document.getElementById(this.id).style.visibility='hidden';
document.getElementById('c'+this.id).style.visibility='visible';
}
function doSomething2() {
document.getElementById("a"+this.id).innerHTML = document.getElementById("inptext").value;
document.getElementById("z"+this.id).innerHTML = document.getElementById("inpadress").value;
document.getElementById(this.id).style.visibility='hidden';
form.reset();
var edit = this.id;
var edit2 = edit.replace("c", "");
document.getElementById(edit2).style.visibility='visible';
}
</script>
</body>
</html>
The following line remove all your listeners:
document.getElementById("buttons").innerHTML =
document.getElementById("buttons").innerHTML + total;
document.getElementById('vda' + z).addEventListener('click',
doSomething);
use this instead:
var div = document.createElement('div');
div.innerHTML = total;
document.getElementById("buttons").appendChild(div);

Better way to add and remove fields dynamically?

I made a way to add and remove fields using the input[type"number"]. I use jquery to do this but the way I did is not perfect. If there's a value in the field, the value will get erase if the number value is change because of using .remove(). Is there a better way to doing this?
<body>
<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput"></div>
</body>
<script>
$('#num').bind('keyup mouseup', function () {
$('.dynamicInput .row').remove();
$('.dynamicInput h4').remove();
if ($(this).val() > 0) {
$('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
var num = $(this).val();
for (var i = 0; i < num; i++) {
$('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
}
}
});
</script>
My Fiddle
Try something like this. Instead of removing all of the inputs every time, this just removes the ones on the end, or adds more to the end.
The main difference between this one and yours is that I added var totNum = 0; to keep track of the current number of input there are. I then used that to determine how many to add/remove.
var totNum = 0;
$(document).on('keyup mouseup', '#num', function(){
var num = $(this).val();
if (num != "")
{
if (totNum == 0)
$('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
for (var i = num; i < totNum; i++)
{
$('.dynamicInput .row:last-child').remove();
}
for (var i = totNum; i < num; i++)
{
$('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
}
totNum = num;
if (totNum == 0)
{
$('.dynamicInput h4').remove();
$('.dynamicInput .row').remove();
}
}
});
input[type="number"] {
width: 200px;
height: 30px;
font-family: Arial, sans-serif;
font-size: 20px;
}
.row {
display: block;
margin-bottom: 15px;
}
body {
width: 100%;
padding: 40px;
}
input[type="text"] {
width: 100%;
}
.col1,
.col2 {
width: 45%;
display: inline-block;
margin-right: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<body>
<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput"></div>
</body>
It's easier and less likely to fail using a data structure as a skeleton upon which you can build the view. Note that this technique requires an extra computation in order to save user inputs, this is the reason why I've added the "change" event.
In the following code snippet, I've made two panels side by side. The left one is a list of inputs, very close to yours, easy to adapt to your needs, while the right one allows to see the evolution of the "data" array according to user actions.
Both panels rely on the "data" array, in other words, as soon as new items are added to or removed from "data", or a single item is updated, both panels are fully rebuilt. Note that the "change" event takes advantage of event delegation in order to deal with newly added inputs.
Finally, the "update" functions update the entire data source or a single item of the data source when the corresponding input changes, while the "render" functions draw on the data source to keep the panels in sync with the data. By the way, the right panel is rendered once at starting.
$(function () {
var data = []; // data source
var $num = $('#num'); // input for number of rows
var $left = $('#left'); // left panel
var $right = $('#right'); // right panel
// render the right panel at starting
renderRightPanel();
// when the number of rows changes:
// - rebuild the left panel entirely
// - keep the data list up to date
// - print the array to the right panel
$num.on('keyup mouseup', function () {
renderLeftPanel($(this).val());
updateList();
renderRightPanel();
});
// when a value changes:
// - keep the data item up to date
// - print the array to the right panel
$left.on('change', 'input', function () {
var i = $left.find('input').index(this);
updateItem(i, $(this).val());
renderRightPanel();
});
// updates the data list
function updateList () {
data = $left.find('input').map(function () {
return $(this).val();
}).get();
}
// updates a single data item
function updateItem (index, value) {
data[index] = value;
}
// refreshes the DOM of the right panel
function renderRightPanel () {
$right.html('<pre>data = ' + (
JSON.stringify(data, 0, 4)
) + '</pre>');
}
// refreshes the DOM of the left panel
function renderLeftPanel (nLines) {
var i;
var html = '';
if (nLines > 0) {
html = '<h4>Heading</h4>';
for (i = 0; i < nLines; i++) {
html += '<div><input value="' + (data[i] || '') + '" /></div>';
}
}
$left.html(html);
}
});
body * {
padding: 0;
margin: 0;
}
h4, input {
margin-bottom: .5em;
}
#panels {
border: 1px solid black;
}
#panels > div {
display: table-cell;
padding: 1em;
}
#right {
border-left: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Number of inputs: <input id="num" type="number" value="0" /></div>
<div id="panels">
<div id="left"></div
><div id="right"></div>
</div>
Disable and hide extra elements instead of removing them. That will prevent them from getting posted, and also retain the previous value of all values that have been entered. See fiddle
One last point, if you don't want to retain values of hidden elements, change .hide() to .hide().val("")
<body>
<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput">
<h4>Please fill in the name and email of each extra attendees</h4>
</div>
</body>
<style>
.col1, .col2 { display: inline; width: 48%; margin-right: 2%; }
.row { padding: 5px; }
</style>
<script>
for (var i = 0; i < 20; i++) {
$('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
}
$('#num').bind('keyup mouseup', function () {
var num = parseInt($(this).val());
$('.dynamicInput .row')
.slice(num)
.hide()
.attr('disabled','disabled');
if ( num > 0) {
$('.dynamicInput .row')
.slice(0,num).show()
.removeAttr('disabled');
$('.dynamicInput h4').show();
} else {
$('.dynamicInput h4').hide();
}
}).trigger('keyup');
</script>
Off-hand, you could cache the values within javascript to resist losing them between #num changes. e.g.
(function($){
var $num = $('#num'),
$dynamic = $('.dynamicInput');
cache = {};
$dynamic.on('change', 'input', function(e){
cache[$(this).prop('name')] = $(this).val();
});
$num.on('change keyup mouseup', function(e){
$dynamic.empty();
var val = parseInt($(this).val(), 10);
if (!isNaN(val) && val > 0){
$('<h4>')
.text('Please fill in the name and email of each extra attendees')
.appendTo($dynamic);
for (var i = 0; i < val; i++){
var nameName = 'attendeesName' + i,
emailName = 'attendeesEmail' + i;
var $row = $('<div>',{'class':'row'}),
$col1 = $('<div>',{'class':'col1'}).appendTo($row),
$col2 = $('<div>',{'class':'col2'}).appendTo($row);
$('<input>',{
'type': 'text',
'name': nameName,
'placeholder': 'Name',
'required': 'true'
}).val(cache[nameName] || '').appendTo($col1);
$('<input>',{
'type': 'email',
'name': emailName,
'placeholder': 'Email',
'required': 'true'
}).val(cache[emailName] || '').appendTo($col2);
$row.appendTo($dynamic);
}
}
});
})(jQuery);
input[type="number"] {
width:200px;
height:30px;
font-family:Arial, sans-serif;
font-size:20px;
}
.row {
display:block;
margin-bottom:15px;
}
body{
width:100%;
padding:40px;
}
input[type="text"]{
width:100%;
}
.col1, .col2{
width:45%;
display:inline-block;
margin-right:10px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput"></div>
Here is an attempt to improve the accepted answer:
$(function () {
var $num = $('#num');
var $panel = $('#panel');
var h4 = '<h4>Heading</h4>';
var row = '<div><input /></div>';
$num.on('mouseup keyup', function () {
var n, $inputs;
var value = $(this).val();
if (value <= 0) {
$panel.empty();
}
else {
$inputs = $panel.find('input');
// get the number of inputs already added
n = $inputs.size();
// add your heading if there is no input
if (n === 0) {
$panel.append(h4);
}
// the user wants less inputs
if (value < n) {
$inputs.slice(value).remove();
}
// the user wants more inputs
else if (value > n) {
$panel.append(
// a little trick, see below
new Array(value - n + 1).join(row)
);
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Number of inputs: <input id="num" type="number" value="0" /></div>
<div id="panel"></div>
A word on the "array join trick":
var a = [1, 2, 3, 4];
console.log(a.join('+'));
// prints "1+2+3+4"
var b = new Array(4); // an array of 4 undefined items
console.log(b.join('+'));
// prints "+++"
var c = new Array(3);
console.log('<ul>' + c.join('<li>item</li>') + '</ul>');
// prints "<ul><li>item</li><li>item</li></ul>"
This is what exactly you are looking for,
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#num").keyup(function(){
$('.dynamicInput .row').remove();
$('.dynamicInput h4').remove();
if ($(this).val() > 0) {
$('.dynamicInput').append('<h4>Please fill in the name and email of each extra attendees</h4>');
var num = $(this).val();
for (var i = 0; i < num; i++) {
$('.dynamicInput').append('<div class="row"><div class="col1"><input type="text" name="attendeesName' + i + '" placeholder="Name" required /></div><div class="col2"><input type="text" name="attendeesEmail' + i + '" placeholder="Email" required /></div></div>');
}
}
});
});
</script>
</head>
<body>
<input type="number" id="num" min="0" max="20" required/>
<div class="dynamicInput"></div>
</body>
</html>

Jquery & HTML - dynamically create div-table

Say I have a textfield where the dimensions of the table are given. like 2 3
now I need to write a function that creates a table out of div-tags with those dimensions. The table has to be inserted in the <div id="output"> -element
I was thinking of making a string with osme for-loops that looks like this
<div>
<div> </div>
<div> </div>
</div>
<div>
... (more columns)
</div>
So that looks like a sequence of div-tags and afterwards I would convert this to html and insert it.
But isn't there a more efficient way?
In your Javascript,
<script type="text/javascript">
var rows,cols,str="";
function generateTable()
{
rows = documnt.getElementById('rows').value;
cols = documnt.getElementById('cols').value;
str ="<table>"
for(var i=0;i<rows;i++)
{
str = str+"<tr>";
for(vat j=0;j<cols;j++)
{
str = str+"<td></td>";
}
str =str+"</tr>";
}
str = str + "</table>;
documnt.getElementById('output').innerHTML = str;
}
</script>
In your HTML,
<input type="number" id="rows" placeholder="Number of rows" />
<input type="number" id="cols" placeholder="Number of cols" />
<input type="button" id="submit" value="Submit" onClick="generateTable();" />
<br>
<br>
<div id="output"></div>
Something like this maybe:
var rows = 3; //these would be populated by your text field entries
var columns = 2;
function makeTable() {
html = '<table>';
for(var i=0; i<rows; i++) {
html += '<tr>';
for(var j=0; j<columns; j++) {
html += '<td><p>Some Data</p></td>';
}
html += '</tr>';
}
html += '</table>';
document.getElementById("output").innerHTML = html;
}
table, td {
border: 1px solid black; padding: 5px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Table Maker</title>
</head>
<body>
<div id="output" onClick="makeTable()"><h1>Click me to make a table!</h1></div>
</body>
</html>

How to record the select order of a number of checkboxs?

Look at this HTML example:
<html>
<head>
<title>My Page</title>
</head>
<body>
<form name="myform" action="http://www.mydomain.com/myformhandler.jsp" method="POST">
<div align="center"><br>
<input type="checkbox" name="option1" value="Milk"> Milk<br>
<input type="checkbox" name="option2" value="Butter" checked> Butter<br>
<input type="checkbox" name="option3" value="Cheese"> Cheese<br>
<br>
</div>
</form>
</body>
</html>
And the resulting output from it:
I hope to send the checked checkbox to the servlet, but i also want to get the order user selected these checkbox.
For example,user A do stuff like : select Cheese,select Butter, select Milk->then Cheese,Butter,Milk will be sent to servlet with this order.
If user B do stuff like : select Cheese,select Butter, deselect Butter, select Milk , select Butter->then Cheese,Milk,Butter will be sent to servlet with this order.
Appreciate.
Check the fiddle for the checkbox order here
I used the following JS Code
checkedOrder = []
inputList = document.getElementsByTagName('input')
for(var i=0;i<inputList.length;i++) {
if(inputList[i].type === 'checkbox') {
inputList[i].onclick = function() {
if (this.checked) {
checkedOrder.push(this.value)
} else {
checkedOrder.splice(checkedOrder.indexOf(this.value),1)
}
console.log(checkedOrder)
}
}
}
​
Make a global variable to track the order:
var selectOrder = 0;
Bind this function to your onclick event in your inputs:
function onClickHandler() {
var senderId = this.id;
selectOrder = selectOrder + 1;
document.getElementById(senderId).setAttribute('data-order', selectOrder);
}
That will set a data-* (custom) attribute on each one with the order they were checked. So, when you submit your form, you can grab all of the checkboxes and get the order with .getAttribute('data-order'); Don't forget to reset your selectOrder = 0 when you submit so it will reorder them on the next time through.
Try this code.This works better
<html>
<head>
<title>My Page</title>
<script type="text/javascript">
var arr=new Array();
function fnc(myid)
{
if(document.getElementById(myid).checked == true)
{
arr.push(document.getElementById(myid).value);
alert(arr);
}
else
{
var item1=document.getElementById(myid).value;
for(i=0;i<2;i++)
{
if(arr[i]=item1)
{
found=i;
arr.splice(found,1);
}
}
}
}
</script>
</head>
<body>
<form name="myform" action="http://www.mydomain.com/myformhandler.jsp" method="POST">
<div align="center"><br>
<input type="checkbox" name="option1" value="Milk" id="Milk" onchange="fnc(this.id)"> Milk<br>
<input type="checkbox" name="option2" value="Butter" id="Butter" onchange="fnc(this.id)"> Butter<br>
<input type="checkbox" name="option3" value="Cheese" id="Cheese" onchange="fnc(this.id)"> Cheese<br>
<br>
</div>
</form>
</body>
</html>
Here, give this a try.
It maintains an array of all of the options' values, along with the order in which they were clicked. It handles the case where items are already checked when the page loads, by arbitrarily assigning them an increasing index for the order they were clicked in.
It handles items being unselected, it also can provide you with a little more info as a happy side-effect of the way I've done it. You can for instance get back values of 2, 3, 4 for selection order. If I load the page, then select Milk then cheese before unselecting then reselecting Butter, I get back the values 2,3,4 2,4,3 - I can straight away tell that the last selection made was Butter, and that it had previously been the first item selected. Likely useless, but an interesting consequence to me all the same.
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<style>
#myDiv
{
border: 1px solid black;
display: inline-block;
}
</style>
<script>
window.addEventListener('load', mInit, false);
function mInit()
{
var i, inputList = document.getElementsByTagName('input'), n = inputList.length;
var cbCount = 0;
var curOrder = 0;
for (i=0; i<n; i++)
{
if (inputList[i].type == 'checkbox')
{
cbCount++;
var cur = inputList[i];
cur.addEventListener('change', onCbChange, false);
var mObj = {val:cur.value, selOrder:0};
if (cur.checked)
{
mObj.selOrder = ++curOrder;
}
availOptions.push( mObj );
}
}
}
var availOptions = []; // an array to hold objects - { val, selOrder }
function getItem(value)
{
var i, n = availOptions.length;
for (i=0; i<n; i++)
{
if (availOptions[i].val == value)
return availOptions[i];
}
return null;
}
// just clear it's selOrder member
function mUnselect(value)
{
var Item = getItem(value);
Item.selOrder = 0;
}
// iterate through the list, find the highest value of selOrder, increment it and set this item's selOrder to that
function mSelect(value)
{
var i, n = availOptions.length;
var curMax=0;
for (i=0; i<n; i++)
{
if (availOptions[i].selOrder > curMax)
curMax = availOptions[i].selOrder;
}
curMax++;
getItem(value).selOrder = curMax;
}
function onCbChange()
{
if (this.checked)
mSelect(this.value);
else
mUnselect(this.value);
alert(this.value + ': ' + this.checked);
}
function showCurState()
{
var i, n=availOptions.length;
var mStr = '';
for (i=0; i<n; i++)
mStr += availOptions[i].val + ", selOrder: " + availOptions[i].selOrder + "\n"
alert(mStr);
}
</script>
</head>
<body>
<div id='myDiv' align="left">
<br>
<input type="checkbox" name="option1" value="Milk"> Milk<br>
<input type="checkbox" name="option2" value="Butter" checked> Butter<br>
<input type="checkbox" name="option3" value="Cheese"> Cheese<br>
<br>
<input type='button' onclick='showCurState();' value='Show state'/>
</div>
</body>
</html>

Categories