Creating a grid of divs from two input fields - javascript

Given two input fields, I would like to create a grid that takes the first input as the rows, and second input as the columns, and appears once a separate button is clicked.
I know how to make a grid NxN, but I want a grid NxY, that specifically gets created via a button.
const grid = document.querySelector("#gridDiv");
const rowSize = document.querySelector("#rowInput");
const colSize = document.querySelector("columnInput");
const button = document.querySelector("button");
function NxY(n, y) {
let rowsArr = [];
let columnArr = [];
for (let i = 0; i < n; i++) {
columnArr.push(i);
}
for (let i = 0; i < y; i++) {
rowsArr.push(columnArr);
}
render(rowsArr)
}
function render(arr) {
arr.forEach((items) => {
let outerDiv = document.createElement("div")
outerDiv.classList.add("row");
items.forEach((item) => {
let dv = document.createElement("div");
dv.classList.add("cell");
outerDiv.appendChild(dv);
});
grid.appendChild(outerDiv);
});
}
NxY(3, 4);
This will automatically produce the grid specified at the bottom, but my issue is figuring out how to add an eventListener to the button that will correctly guide it to creating the proper grid.

Try this snippet
$('#btnInsert').click(function(){
$('#mtable tbody').html('');
var row_count = $('#row').val();
var col_count = $('#col').val();
if(row_count && col_count){
//entry is valid
while(row_count > 0){
//add new row
$('#mtable tbody').append($("<tr>"));
row_count--;
}
while(col_count > 0){
//add new column
$('#mtable tr').append($("<td>"));
$('#mtable tbody tr').each(function(){$(this).children('td:last').append($('<input type="checkbox">'))});
col_count--;
}
}else{alert('Invalid entry');}
});
$('#btnInsert2').click(function(){
$('#mDiv').html('');
var row_count = $('#row2').val();
var col_count = $('#col2').val();
if(row_count && col_count){
//entry is valid
while(row_count > 0){
//add new row
$('#mDiv').append($("<div class='row'>"));
row_count--;
}
while(col_count > 0){
//add new column
$('#mDiv').children('.row').each(function(){$(this).append($('<div class="col col-md-4">'))});
col_count--;
}
}else{alert('Invalid entry');}
});
td{padding:5px;}
.col{margin:5px;
min-height: 50px;
background: #aaaaaa;}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<h3>For Tables </h3>
<input id="row" type="number" max="20" placeholder="Enter no. of rows"/>
<input id="col" type="number" max="20" placeholder="Enter no. of columns"/>
<button id="btnInsert">Generate Grid</button>
<table border="1" id="mtable">
<tbody></tbody>
</table><br/><br/><br/><br/>
<h3>For Divs </h3>
<input id="row2" type="number" max="20" placeholder="Enter no. of rows"/>
<input id="col2" type="number" max="20" placeholder="Enter no. of columns"/>
<button id="btnInsert2">Generate Grid</button>
<br>
<div class="container" id="mDiv"></div><br/><br/><br/><br/>

Related

Dynamic Table: Instead of Cells give INPUT Fields for one specific column (how to?)

I am making a grocery list, and I have created a dynamic table from an array of objects. A table that an user can update.
Now what I want to do is that the aantal(meaning quantity) can be modified by using the steps input option:
input type="number" id="points" name="points" step="3"
So the expected output would be this table where aantal would be a steps input. That will change the total price of course when modified by the user. Which right now its already doing the calculation.
I am not so experienced with generating tables. I think I need to make a new variable with a for loop that would change the cells for aantal. But how would I go about this? I have been messing around a little bit. And I am a bit stuck. I hope my question is clear.
Update: I am using a For in loop, and so far I can generate INPUT fields but not in the right spot. My condition and table generating is not going well yet :)
Update: I realized I can make another header with the steps input, I realize also its a type=number input field. oops Now I will do that and try to get the proper values into the array.
Here is my code:
let myTable = document.querySelector('#table');
//array met objecten erin {} staat voor een object
let product = [
{omschrijving:"Brood", waarde:1, aantal:3, total:0},
{omschrijving:"Brocolli", waarde:0.99, aantal:2, total:0},
{omschrijving:"Krentenbollen", waarde:1.20, aantal:4, total:0},
{omschrijving:"Noten", waarde:2.99, aantal:2, total:0}
]
//update totals
for(let i=0;i<product.length;i++)
{
product[i].total = product[i].waarde*product[i].aantal;
}
let headers = ['Name', 'Prijs', 'Aantal', 'Totaal'];
let table = document.createElement('table');
let headerRow = document.createElement('tr');
headers.forEach(headerText => {
let header = document.createElement('th');
let textNode = document.createTextNode(headerText);
header.appendChild(textNode);
headerRow.appendChild(header);
});
table.appendChild(headerRow);
product.forEach(emp => {
let row = document.createElement('tr');
Object.values(emp).forEach(text => {
let cell = document.createElement('td');
let textNode = document.createTextNode(text);
cell.appendChild(textNode);
row.appendChild(cell);
})
table.appendChild(row);
});
myTable.appendChild(table);
function updateTable() {
test = [];
b1 = document.getElementById('naam').value;
b2 = document.getElementById('prijs').value;
b3 = document.getElementById('qty').value;
test.push({omschrijving:b1, waarde:b2, aantal:b3, total:0});
for(let i=0;i<test.length;i++)
{
test[i].total = test[i].waarde*test[i].aantal;
}
test.forEach(emp => {
let row = document.createElement('tr');
Object.values(emp).forEach(text => {
let cell = document.createElement('td');
let textNode = document.createTextNode(text);
cell.appendChild(textNode);
row.appendChild(cell);
})
table.appendChild(row);
});
myTable.appendChild(table);
console.log(product);
}
body {
text-align: center;
}
div {
display: inline-block;
}
button {
display: inline-block;
padding: 10px 20px;
}
#table {
display: block;
margin-top: 20px;
}
th, td {
border: 1px solid black;
padding: 5px;
}
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css">
<title>Boodschappenlijst</title>
</head>
<body>
<h1> Boodschappenlijst </h1>
<div id="container"></div>
<div>
<div id="table"></div>
</div>
<p>Naam</p>
<input type="text" name="item" id="naam" /><br />
<p>Aantal</p>
<input type="text" name="quantity" id="qty" /><br />
<p>Prijs</p>
<input type="text" name="price" id="prijs" /><br/><br />
<input type="button" value="Add Product" onclick="updateTable()" id="add"><br /><br />
<script src="script.js"></script>
</body>
</html>

Javascript make table with rows and columns given by user and change each cells colour onclick

I have a code in which the user enters the number of rows and columns. the table of given rows and columns are created with each cell has an event of onClick, where the user clicks on any cell and the background color of the cell changes. in my code how do I change the background color of the cell?
<body>
Grid Height:
<input id="n1" type="number" name="height" min="1" value="1">
Grid Width:
<input id="n2" type="number" name="width" min="1" value="1">
<input type="submit" onclick="makegrid()">
<table width="100px" height="100px" id="myTable" border="1" style="border-collapse:collapse" >
</table>
<script>
var x,rn,cn;
function makegrid()// function called after submit button is clicked
{
rn = parseInt(document.getElementById("n1").value); //fetches the entered rows by user
cn = parseInt(document.getElementById("n2").value); //fetches the entered column by user
for(var r=0;r<rn;r++)
{
x=document.getElementById("myTable").insertRow(r); //insert row to the table
for(var c=0;c<cn;c++)
{
var y= x.insertCell(c); //insert cells to each row
}
}
}
</script>
Add click listener to the document, check if the clicked element is td if yes change the background color of cell.
var x, rn, cn;
function makegrid() // function called after submit button is clicked
{
rn = parseInt(document.getElementById("n1").value); //fetches the entered rows by user
cn = parseInt(document.getElementById("n2").value); //fetches the entered column by user
for (var r = 0; r < rn; r++) {
x = document.getElementById("myTable").insertRow(r); //insert row to the table
for (var c = 0; c < cn; c++) {
var y = x.insertCell(c); //insert cells to each row
}
}
}
document.addEventListener('click', ({target}) => {
if (target.tagName == "TD") {
target.style.backgroundColor = "red";
}
});
Grid Height:
<input id="n1" type="number" name="height" min="1" value="1"> Grid Width:
<input id="n2" type="number" name="width" min="1" value="1">
<input type="submit" onclick="makegrid()">
<table width="100px" height="100px" id="myTable" border="1" style="border-collapse:collapse">
</table>

Inserting rows to a table based on user input

I have tried to generate the rows using javascript, but i'm learning jquery and I wish to use it to implement this functionality.
HTML
<form id="sizePicker">
Grid Height:
<input type="number" id="input_height" name="height" min="1" value="1">
Grid Width:
<input type="number" id="input_width" name="width" min="1" value="1">
<input type="submit">
</form>
<table id="pixel_canvas"></table>
JAVASCRIPT/JQUERY
function makeGrid() {
var table = document.getElementById("pixel_canvas");
//var table = $('#pixel_canvas');
table.innerHTML = "";
while($('#pixel_canvas tr').length > 0)
table.deleteRow(0);
var inputHeight = $('#input_height').val();
var inputWidth = $('#input_width').val();
for(var i = 0; i < inputHeight; i++){
var row = table.insertRow(i);
for(var j = 0; j < inputWidth; j++){
var cell = row.insertCell(j);
}
}
return false;
}
sizePicker.submit(function(evt){
evt.preventDefault();
makeGrid();
});
Here, the table DOM methods such as insertRow() and insertCell() is inactive if I implement the same methods using jquery.
var table = $('#pixel_canvas');
var row = table.insertRow(i); // The browser responses not a function
insertRow is Javascript DOM function. So, with JQuery you have to fetch the DOM element and not the jquery object. Use $('#pixel_canvas').get(0) to fetch the DOM element.
function makeGrid() {
var table = $('#pixel_canvas').get(0);
table.innerHTML = "";
while($('#pixel_canvas tr').length > 0)
table.deleteRow(0);
var inputHeight = $('#input_height').val();
var inputWidth = $('#input_width').val();
for(var i = 0; i < inputHeight; i++){
var row = table.insertRow(i);
for(var j = 0; j < inputWidth; j++){
var cell = row.insertCell(j);
}
}
return false;
}
$('#sizePicker').submit(function(evt){
evt.preventDefault();
makeGrid();
});
table, th, td {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="sizePicker">
Grid Height:
<input type="number" id="input_height" name="height" min="1" value="1">
Grid Width:
<input type="number" id="input_width" name="width" min="1" value="1">
<input type="submit">
</form>
<table id="pixel_canvas"></table>

Swap data between two checked elements

Here is a somewhat simplified version of the code I am currently using:
https://jsfiddle.net/2zauty83/8/
Javascript
function checkboxlimit(checkgroup) {
var checkgroup = checkgroup
for (var i = 0; i < checkgroup.length; i++) {
checkgroup[i].onclick = function() {
var checkedcount = 0
for (var i = 0; i < checkgroup.length; i++)
checkedcount += (checkgroup[i].checked) ? 1 : 0
if (checkedcount > 2) {
this.checked = false
}
}
}
}
var sort_form = document.forms.sortus;
var sort_checkboxes = sort_form.elements['squarepick[]'];
checkboxlimit(sort_checkboxes);
CSS
input.square {
margin: 0;
padding: 0;
display: none;
}
.sorttile {
cursor: pointer;
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid #CCCCCC;
margin: 1px;
}
.sorttile:hover {
border: 2px solid #AAAAAA;
}
HTML
<form enctype='multipart/form-data' method='POST' id='sortus'>
<input id='1-1' class='square' type='checkbox' name='squarepick[]' value='1-1' />
<label class='sorttile' for='1-1' style='background-color:#FF0000;'>
<input type='hidden' name='1-1' value='#FF0000' />
</label>
<input id='1-2' class='square' type='checkbox' name='squarepick[]' value='1-2' />
<label class='sorttile' for='1-2' style='background-color:#FFFF00;'>
<input type='hidden' name='1-2' value='#FFFF00' />
</label>
<input id='1-3' class='square' type='checkbox' name='squarepick[]' value='1-3' />
<label class='sorttile' for='1-3' style='background-color:#00FF00;'>
<input type='hidden' name='1-3' value='#00FF00' />
</label>
<br/>
<input id='2-1' class='square' type='checkbox' name='squarepick[]' value='2-1' />
<label class='sorttile' for='2-1' style='background-color:#00FFFF;'>
<input type='hidden' name='2-1' value='#00FFFF' />
</label>
<input id='2-2' class='square' type='checkbox' name='squarepick[]' value='2-2' />
<label class='sorttile' for='2-2' style='background-color:#0000FF;'>
<input type='hidden' name='2-2' value='#0000FF' />
</label>
<input id='2-3' class='square' type='checkbox' name='squarepick[]' value='2-3' />
<label class='sorttile' for='2-3' style='background-color:#FF00FF;'>
<input type='hidden' name='2-3' value='#FF00FF' />
</label>
<br/>
<input id='3-1' class='square' type='checkbox' name='squarepick[]' value='3-1' />
<label class='sorttile' for='3-1' style='background-color:#000000;'>
<input type='hidden' name='3-1' value='#000000' />
</label>
<input id='3-2' class='square' type='checkbox' name='squarepick[]' value='3-2' />
<label class='sorttile' for='3-2' style='background-color:#999999;'>
<input type='hidden' name='3-2' value='#999999' />
</label>
<input id='3-3' class='square' type='checkbox' name='squarepick[]' value='3-3' />
<label class='sorttile' for='3-3' style='background-color:#FFFFFF;'>
<input type='hidden' name='3-3' value='#FFFFFF' />
</label>
</form>
Basically each colored square represents a checkbox, allowing you to select any two boxes. Additionally, each box has a hidden input field associated with it.
For simplified demonstration purposes, the demo uses "background-color", but my actual code uses "background-image".
What I would like to do is make it so that when two squares are picked, upon selecting the second box, the two boxes trade each other's "background-image" values, effectively making it appear like the two squares traded places.
In addition, however, I also need to swap the values of the hidden-type input fields.
Finally, the two checkboxes should be deselected, although that part is easy. What I'm having trouble with is the first two parts. I thought I had some idea of how to make it work, but my experiments haven't been working out (My knowledge of javascript is still fairly crude).
Any ideas on how to make this work?
The first thing you need to do is set up an event listener so you know when a box has been checked. The second thing you need to do is to keep track of what got checked. Finally, you want to perform a series of operations based on what was checked.
var formEl = document.getElementById("sortus");
// Track our checked boxes
var checked = [];
var swap = function () {
var boxA = checked[0];
var boxB = checked[1];
// Get hidden fields using checkbox ID
var hiddenA = document.getElementsByName(boxA.id)[0];
var hiddenB = document.getElementsByName(boxB.id)[0];
var boxAbackgroundImage = boxA.style.backgroundImage;
var hiddenAvalue = hiddenA.value;
// Switch images!
boxA.style.backgroundImage = boxB.style.backgroundImage;
boxB.style.backgroundImage = boxAbackgroundImage;
// Swap hidden input values
hiddenA.value = hiddenB.value;
hiddenB.value = hiddenAvalue;
};
var reset = function () {
for (var i = 0; i < checked.length; i++) {
checked[i].checked = false;
}
checked = [];
};
var isDuplicate = function (el) {
for (var i = 0; i < checked.length; i++) {
if (checked[i] === el) {
return true;
}
}
return false;
};
formEl.addEventListener("click", function (e) {
var el = e.target;
// Was it a checkbox clicked?
if (el.className == "square") {
// Is it already checked?
if (!isDuplicate(el)) {
checked.push(el);
if (checked.length === 2) {
swap();
reset();
}
}
}
});
I didn't test this code but I hope it gives you a clear sense of what you need to do.
Basic function for your above requirement can be found in the below link,
Fiddler Link
function checkboxlimit(checkgroup)
{
var checkgroup = checkgroup
for (var i = 0; i < checkgroup.length; i++) {
checkgroup[i].onclick = function()
{
var checkedcount = 0
for (var i = 0; i < checkgroup.length; i++)
checkedcount += (checkgroup[i].checked) ? 1 : 0
if (checkedcount > 2) {
this.checked = false
}
swapImage();
}
}
}
function swapImage()
{
var prevStyle="";
var prevId="";
for (var i = 0; i < sort_checkboxes.length; i++) {
if(sort_checkboxes[i].checked)
{
if(prevId!="")
{
document.getElementById(prevId).nextElementSibling.style.backgroundColor = sort_checkboxes[i].nextElementSibling.style.backgroundColor;
document.getElementById(prevId).nextElementSibling.children[0].value = sort_checkboxes[i].nextElementSibling.style.backgroundColor;
sort_checkboxes[i].nextElementSibling.style.backgroundColor = prevStyle;
sort_checkboxes[i].nextElementSibling.children[0].value = prevStyle;
prevStyle = "";
prevId = "";
}
else
{
prevId=sort_checkboxes[i].id;
prevStyle = sort_checkboxes[i].nextElementSibling.style.backgroundColor;
}
}
}
}

jQuery add ID increment to .html() appending on input onchange and refresh onchange value

I apologize for the wordy title but I haven't found a solution to my problem yet. I am a newbie with jQuery and web development so any guidance would be appreciated.
I have a <input> that allows user to enter a value (number) of how many rows of a set of input fields they want populated. Here's my example:
<div id="form">
<input id="num" name="num" type="text" />
</div>
<p> </p>
<div id="form2">
<form action="" method="post" class="form_main">
<div class="data">
<div class="item">
<input id="name" name="name[]" type="text" placeholder="name" /><br/>
<input id="age" name="age[]" type="text" placeholder="age" /><br/>
<input id="city" name="city[]" type="text" placeholder="city" /><br/>
<hr />
</div>
</div>
<button type="submit" name="submit">Submit</button>
</form>
My jQuery:
<script>
var itemNum = 1;
$("#num").on("change", function() {
var count = this.value;
var item = $(".item").parent().html();
//item.attr('id', 'item' + itemNum);
for(var i = 2; i <= count; i++) {
itemNum++;
$(".data").append(item);
}
})
</script>
I'm having problems adding an ID item+itemNum increment to <div class="item">... item.attr() didn't work. It doesn't append once I added that line of code.
Also, how can I get it so that once a user enters a number that populates rows of input fields, that if they change that number it will populate that exact number instead of adding to the already populated rows? Sorry if this doesn't make any sense. Please help!
Here is a DEMO
var itemNum = 1;
$("#num").on("change", function() {
$('.data div').slice(1).remove(); //code for removing previously populated elements.
var count = this.value;
console.log(count);
var item;
//item.attr('id', 'item' + itemNum);
var i;
for(i = 1; i <= count; i++) {
console.log(i);
item = $("#item0").clone().attr('id','item'+itemNum);
//prevent duplicated ID's
item.children('input[name="name[]"]').attr('id','name'+itemNum);
item.children('input[name="age[]"]').attr('id','age'+itemNum);
item.children('input[name="city[]"]').attr('id','city'+itemNum);
itemNum++;
$(".data").append(item);
}
})
Use clone() instead of html()
Try
var itemNum = 1,
item = $(".data .item").parent().html();;
$("#num").on("change", function () {
var count = +this.value;
if (itemNum < count) {
while (itemNum < count) {
itemNum++;
$(item).attr('id', 'item' + itemNum).appendTo('.data')
}
} else {
itemNum = count < 1 ? 1 : count;
$('.data .item').slice(itemNum).remove();
}
})
Demo: Fiddle

Categories