Issue with stretching of grid when grid gets generated below 16 rows - javascript

I am generating a grid on page load. When you generate a grid below 16 the grid gets stretched like this:
https://imgur.com/a/1IPnXn0
I have tried to adjust the width of the row with css. I have also made changes to the container with css. I believe this has something to do specifically with the width of the .row css which is set to 25.25%
working codepen
https://codepen.io/dhuang6/pen/ZVKWGe
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="container">
<div id="Btns">
<button id="recreate"
onclick="resizeGrid(this.value)">remake
grid</button>
</div>
<br />
</div>
<script src="script.js"></script>
</body>
</html>
window.onload = function(){
var createGrid = prompt("How many rows do you want?");
for(i = 0; i <= createGrid; i++){
var row = document.createElement('div');
row.className = "row";
row.id = "row" + i;
for(k= 0; k <= createGrid; k++ ){
var box = document.createElement('div');
box.className = "box";
row.appendChild(box);
}
container.appendChild(row);
}
return container;
}
#container {
width: 50%;
height: 50%;
margin-top:50px;
margin-left: auto;
margin-right: auto;
background: "white";
overflow:hidden;
box-sizing: border-box;
}
.row{
border:1px solid red;
height:1em;
width:25.25%;
overflow:hidden;
box-sizing: border-box;
}
.box{
display: inline-block;
width: 8.25%;
height: 1em;
border: 1px solid red;
border-bottom: 0px;
border-left: 0px;
float:right;
overflow:hidden;
box-sizing: border-box;
margin: auto;
}
When you inspect the element of the .row of the html the width is usually set to 265px or something really long like that. I believe that is part of the problem. When you generate a grid larger than 16 this issue doesn't occur.
Thank you for helping me.

You need to dynamically set the box width: https://codepen.io/brien-givens/pen/wRdGJa

Here is a working version using a table instead of divs.
There are alot of css changes so make sure to look over the code carefully or copy it verbatim. Also because of the way tables work the grid is basically turned 90deg so keep that in mind.
//try flexbox
/*
adding a button and having the submit grab the value for the backend function
*/
//trying to make a function for creating divs
window.onload = function(){
var createGrid = prompt("How many rows do you want?"),
table = document.getElementById('table');
console.log(createGrid);
for(i = 0; i <= createGrid; i++){
var row = document.createElement('tr'); //changed from div
row.className = "row";
row.id = "row" + i;
for(k= 0; k <= createGrid; k++ ){
var box = document.createElement('td'); //changed from div
box.className = "box";
row.appendChild(box);
}
table.appendChild(row); //changed from container.
}
return container;
}
//create a grid
//generates a grid with the original div container already on index.html you need to start messing with the code you work with to gain a better understanding of what it's doing
function grid() {
var container = document.getElementById("container");
for (i = 0; i <= 16; i++){
for(k = 0; k <= 16; k ++){
var box = document.createElement("div");
box.className = "box";
// row.appendChild(box);
}
container.appendChild(row);
}
return container;
}
// grid(document.body);
function resizeGrid(){
clearGrid();
//missing a clear grid function!
}
//right now the resizing is adding to the bottom of the old grid.
function clearGrid(){
}
document.addEventListener("mouseover",(e)=>{
if(!e.target.classList.contains("box")){
return;
}
e.target.style.background = "#3d3d3d";
})
/*
added the container that holds the grid to manipulate the css.
made it appear more like the etch-a-sketch board.
width: 25.25%;
*/
#container {
width: 50%;
height: 50%;
margin-top:50px;
margin-left: auto;
margin-right: auto;
background: "white";
overflow:hidden;
box-sizing: border-box;
}
#table {
width: 100%;
border-collapse: collapse;
}
/*
there is a bit of extra space being generated on the right side of the grid.
row seems to be causing the issue will need to review.
Checked the grid creation which seems to be fine.
*/
.row{
border:1px solid red;
height:1em;
width:25.25%;
overflow:hidden;
box-sizing: border-box;
}
.box{
width: 8.25%;
height: 1em;
border: 1px solid red;
overflow:hidden;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="Btns">
<button id="recreate" onclick="resizeGrid(this.value)">remake grid</button>
</div>
<br />
</div>
<table id="table"></table>
<script src="script.js"></script>
</body>
</html>

Move the button to end of the page to make the first child selector work and apply this CSS
#container {
width: 50%;
height: 50%;
margin-top:50px;
margin-left: auto;
margin-right: auto;
background: "white";
overflow:hidden;
box-sizing: border-box;
}
.row{
line-height: 0;
}
.row:first-child .box{
border-top: 1px solid red;
}
.box{
display: inline-block;
width: 15px;
height: 15px;
border: 1px solid red;
box-sizing: border-box;
border-left: none;
border-top: none;
margin: 0;
}
.box:first-child{
border-left: 1px solid red;
}

Related

Etch-A-Sketch: Columns will resize, but rows won't. (CSS Grid)

I am creating an Etch-A-Sketch project as part of The Odin Project's foundations course. I have created a 16x16 grid, and the amount of cells in the grid will change depending on the user's input to a prompt.
My problem is that the amount of cells in the columns will change, but not the amount of cells in the rows. This results in the etch-a-sketch pad being made up of rectangles rather than evenly placed squares.
For example: If the user enters "32", there will be 32 cells in each column. But still only 16 columns. I need the grid to be 32x32 instead of 32x16.
const container = document.querySelector("#container");
const buttonSize = document.querySelector("#gridsize");
const buttonRainbow = document.querySelector("#gridsize");
let cell = document.querySelectorAll('.cell');
let cellAmount = 16;
window.onload = createGrid(cellAmount);
cell.onmouseover = mouseOver();
// creates a 16x16 grid
function createGrid(e){
for (let i = 0; i < e*e; i++){
const div = document.createElement("div");
div.classList.add("cell");
container.appendChild(div);
}
}
// changes cell colors to black on mouseover
function mouseOver(){
let cell = document.querySelectorAll('.cell');
cell.forEach((cell) => {
cell.addEventListener('mouseover', function(){
cell.style.background = "black";
})
})
}
// resizes the grid and resets sketch
buttonSize.addEventListener('click', () => {
for (i = 0; i < cell.length; i++){
cell[i].style.removeProperty("black")
}
let userAmount = prompt("Select your pixel size (Default: 16)");
if (userAmount == ""){
userAmount == 16;
}
while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){
userAmount = prompt("Sorry, please enter a number between 4 and 100.");
}
cellAmount = parseInt(userAmount);
while (container.hasChildNodes()){
container.removeChild(container.firstChild);
}
createGrid(cellAmount);
mouseOver();
});
#container {
margin-top: 25px;
display: inline-grid;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
border: 7.5px solid black;
border-radius: 10px;
height: 575px;
width: 575px;
box-sizing: border-box;
}
.cell {
border: 1px solid black;
box-sizing: border-box;
}
#title {
display: flex;
background-color: crimson;
justify-content: center;
width: 270px;
height: 72px;
margin-left: 815px;
margin-top: 50px;
border-style: solid aqua;
border-radius: 35px;
font-size: small;
}
#buttons {
display: flex;
justify-content: center;
gap: 75px;
margin-top: 40px;
}
#gridsize {
background: black;
color: white;
border: none;
width: 100px;
height: 30px;
font-size: large;
border-radius: 20px;
font-weight: bold;
}
#rainbow {
background: black;
color: white;
border: none;
width: 100px;
font-size: large;
font-weight: bold;
border-radius: 20px;
}
#tipmessage {
text-align: center;
margin-top: 40px;
}
html {
background-color: snow;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Etch-A-Sketch.</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="title">
<h1>Etch-A-Sketch. &#128397</h1>
</div>
<div id="buttons">
<button id="gridsize">Size</button>
<button id="rainbow">Rainbow</button>
</div>
<div id="container"></div>
<div id="tipmessage">
<h3><em>'We don't make mistakes, just happy little accidents' - Bob Ross</em></h3>
</div>
</body>
<script src="script.js" defer></script>
</html>
I have tried changing the CSS grid properties for #container however this has not solved the problem. I have inspected my JS but can't seem to figure out if the problem is coming from the JS, or the CSS.
For example, I tried changing my CSS Grid's columns and rows to "auto" but this completely ruined the grid.
The problem is coming from the CSS. This part:
#container{
...
grid-template-columns: repeat(16, 1fr);
...
}
Because the grid-template-columns amount is hard-coded into the style-sheet it will not change with the new grid size received from the user. If the amount of columns is set to, say 33 and then you edit grid-template-columns via browser tools to match 33 then the divs created will appear as squares.
As it is written there must be 16 columns in the grid and no more or less.
So when you call the function that creates the grid you have to edit the grid-template-columns attribute of #container so that the grid-template-columns of the container is updated along with the amount of cells in the grid.
function createGrid(e){
container.style.gridTemplateColumns = `repeat(${e},1fr)` // This will make the divs square
for (let i = 0; i < e*e; i++){
const div = document.createElement("div");
div.classList.add("cell");
container.appendChild(div);
}
}

Javascript Uncaught TypeError: Cannot read property 'getElementsByTagName' of null

I'm trying to code a Sudoku generator in JavaScript and I think I did it.
My problem is for visualizing the generated solution inside the input tags I use for the game.
I put this function on the property onload of the body of my html page:
function begin() {
var container=document.getElementById("container");
var div;
for(var i=0; i<9; i++) {
div=document.createElement("div");
div.id=i;
div.setAttribute("class", "square");
for(var j=0;j<9;j++) {
var square=document.createElement("input");
square.setAttribute("type", "text");
square.setAttribute("maxlength", "1");
if(i%2==0) {
square.setAttribute("class", "square1");
}
else {
square.setAttribute("class", "square2");
}
div.appendChild(square);
}
container.appendChild(div);
}
}
And it works perfectly fine, since it show 9 squares (the divs), each with 9 small squares inside(the inputs).
Now the last function is, to show the result is:
function showSudoku(sudoku, i) {
var container = document.getElementById("container");
var cells = container.getElementsByTagName("input");
for(var j=0; j<81; j++)
cells[j].value = sudoku[j];
}
but I get the error
Uncaught TypeError: Cannot read property 'getElementsByTagName' of null
For some reason the variable container is not initialized with the element identified with the id container. Can anyone help me?
[EDIT]
Here is the HTML code:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="utf-8">
<title>Sudoku</title>
<style type="text/css">
body {
text-align: center;
}
#game {
width: 21.2em;
height: 21.15em;
margin: auto;
border: 2px solid #777777;
}
#container {
width: 21.2em;
height: 21.2;
margin: auto;
}
.square {
width: 6.94em;
height: 6.94em;
display: inline-block;
border: 1px solid #A9A9A9
}
.square1 {
height: 3em;
width: 3em;
background-color: white;
border: 1px dashed #CBCBCB;
color: black;
display: inline-block;
}
.square2 {
height: 3em;
width: 3em;
background-color: #DDDDDD;
border: 1px dashed #CBCBCB;
color: black;
display: inline-block;
}
input {
text-align: center;
}
</style>
<script type="text/javascript" src="sudoku.js">
</script>
</head>
<body onload="begin()">
<div id="levels">
<label><input type="radio">Easy</label>
<label><input type="radio">Medium</label>
<label><input type="radio">Hard</label>
</div>
<div id="buttons">
<button id="newgame" onclick="newGame()">NEW GAME</button>
<button id="solve">SOLVE</button>
</div>
<br>
<div id="game">
<div id="container">
</div>
</div>
<br>
<div id="time">
<input id="currentTime" type="text" readonly="readonly">
</div>
</body>
</html>
The buttons and the inputs radio are still unused.
hey you are messing with tagname since you would not specify which input type you are wanting to append in the javascript.
so you should have to go like this as follows:
var nodeLists = document.getElementsByTagName("input");
for(node in nodeLists){
if(nodeLists[node].getAttribute('type') == "text"){
//write code here as you want
}
else{
}
}

Creating a grid using for loops jquery

I am trying to create a 16x16 grid using jquery. I have a main div, and then I'm trying to create the grid within it. I am using for loops, but when the code below runs, I get a 16x32 grid.
Could anyone explain what is going on and why that is happening?
<html>
<head>
<title>etch-a-sketch</title>
<link type="text/css" rel="stylesheet" href="stylesheet.css"/>
</head>
<body>
<div id=main>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type='text/javascript' src='app.js'></script>
</body>
#main {
height: 192px;
width: 192px;
background-color: antiquewhite;
}
.squares {
height: 10px;
width: 10px;
margin: 1px;
background-color: aquamarine;
display: inline-block;
}
$(document).ready(function() {
for(var x = 0; x < 16; x++) {
for(var y=0; y<16; y++) {
$("<div class='squares'></div>").appendTo('#main');
}
}
});
You get a 16x16 grid. When you're using "inline", spaces take place. Just change the CSS code to this:
#main {
height: 192px;
width: 192px;
background-color: antiquewhite;
}
.squares {
height: 10px;
width: 10px;
margin: 1px;
background-color: aquamarine;
display: block;
float: left;
}
Note:
display: block;
float: left;
I think your thought process was off.. I think the best way to make a 16x16 grid (256 boxes total) would be the way I went below and use css to style them.
The HTML
<div id="main">
</div>
The CSS
#main {
width: 100%;
}
.squares {
width:6%;
height: 50px;
border: 1px solid red;
display:inline-block;
}
The Javascript
for(var x = 0; x < 256; x++) {
$("<div class='squares'>hi</div>").appendTo('#main');
}

Issues about grouping and appending div

[EDIT] I tried to dynamically create 6 horizontal lines every 1 second using setTimeout method. So it should shows every 6 horizontal lines as a group for every 1 second. Here, I call 6 horizontal lines as group. However, I want to append each group horizontally rather than vertically. When trying to append a group and the width of the border is not long enough to hold a new group, append the new group to next lines. And also I want a "pilar" between each grounp of 6 horizontal lines, and I only want to create 8 group of horizontal lines. The first picture below is what I get after running my code. The second one is what I need. The code below is my html, css, and js code. Hope someone could help me out. Thank you in advance.
html:
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="code.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="code_js.js"></script>
</head>
<body>
<div id = "output">
</div>
</body>
</html>
css:
.deco {
border-bottom: 1px solid black;
width: 120px;
margin-left:0px;
margin-bottom:10px;
z-index: 2;
position: relative;
/*display: inline-block;*/
margin-right: 20px;
}
#output {
background: #ffe6e6;
width: 600px;
height: 800px;
position:absolute;
}
js:
$(document).ready(function() {
makeItHappen(0);
});
function makeItHappen(order) {
for (var i = 0; i < 7; i++) {
var hr = document.createElement('hr');
hr.className = "deco"
hr.id = "hr" + i;
$('#output').append(hr);
}
makeTable(function() {
if(++order < 7) {
makeItHappen(order);
}
});
}
function makeTable(callback) {
setTimeout(function() {
callback();
}, 1000);
}
You can use display:flex to get the output you are expecting
$(document).ready(function() {
makeItHappen(0);
});
function makeItHappen(order) {
var output = $("#output");
var div = $("<div></div>");
div.attr('id', order);
for (var i = 0; i < 7; i++) {
var hr = document.createElement('hr');
hr.className = "deco"
hr.id = "hr" + i;
$(div).append(hr);
}
output.append(div);
makeTable(function() {
if (++order < 7) {
makeItHappen(order);
}
});
}
function makeTable(callback) {
setTimeout(function() {
callback();
}, 1000);
}
.deco {
border-bottom: 1px solid black;
width: 120px;
margin-left: 0px;
margin-bottom: 10px;
z-index: 2;
position: relative;
/*display: inline-block;*/
margin-left: 10px;
}
#output div:nth-child(2n+1) {
border-right: 5px solid green;
margin-top: 5px;
}
#output div:nth-child(2n) {
border-right: 5px solid green;
margin-top: 5px;
height: auto;
}
#output {
display: flex;
flex-wrap: wrap;
}
#output {
background: #ffe6e6;
width: 500px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output">
</div>
Hope it helps

How to make button that changes grid dimensions using JS?

I have created a 16x16 grid. I'm trying to put a button above the grid, which when the user clicks, will prompt them for new grid dimensions (between 1 and 64). For example, if you click the button and input 25, the dimensions of the grid will change from 16x16 to 25x25.
I'm having trouble in figuring out how to get the user's input into a javascript function, so it outputs the updated grid. Code here:
HTML:
<!doctype html>
<html>
<head>
<title>SketchPad</title>
<link rel="stylesheet" type="text/css" href="style.css" >
</head>
<body>
<h1> SketchPad </h1>
<div id="container">
</div>
<button class="button" type="button" onclick="myFunction()">Choose Your Grid</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="jquery.js"></script>
</body>
</html>
CSS:
h1 {
text-align: center;
color: black;
}
tr, td, table {
border-style: solid;
border-width: 1px;
background-color: gray;
margin: auto;
height: 25px;
width: 525px;
margin-top: 20px;
}
td {
transition: .3s background-color;
}
td:hover {
background-color: red;
}
button {
height: 25px;
width: 225px;
margin: 0 auto;
position: relative;
top: 50%;
left: 40%;
margin-top: -40px;
}
Javascript:
var rows=16;
var cols=16;
document.write("<table>");
for (i=0; i<rows; i++) {
document.write("<tr>");
for (j=0; j<cols; j++) {
document.write("<td>"+"</td>");
}
document.write("</tr>");
}
document.write("</table>");
$( "td").css("color", "red");
$(".button").click(function() {
prompt("Please select your grid size");
});
function grid(rows, cols) {
//function goes here//
}
Try something like the following.
Write a function which empties your container and redraws your grid inside it.
Initialize your grid in a document.ready() hander.
Define an event handler for your button click, which prompts to redraw the grid at a user-defined size.
$(document).ready(function() {
grid(16,16);
});
$(".button").click(function() {
var size = prompt("Please select your grid size");
grid(size, size);
});
function grid(rows, cols) {
var table = "<table>";
var size = (1 / rows * 525) + "px";
for (i=0; i<rows; i++) {
table += "<tr>";
for (j=0; j<cols; j++) {
table += "<td>"+"</td>";
}
table += "</tr>";
}
table += "</table>";
$("#container").empty().append(table);
$("tr").css("height", size);
$("td").css("color", "red").css("width", size);
}
h1 {
text-align: center;
color: black;
}
table {
height: 525px;
width: 525px;
}
tr, td, table {
border-style: solid;
border-width: 1px;
background-color: gray;
margin: auto;
margin-top: 20px;
}
td {
transition: .3s background-color;
}
td:hover {
background-color: red;
}
button {
height: 25px;
width: 225px;
margin: 0 auto;
position: relative;
top: 50%;
left: 40%;
margin-top: -40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1> SketchPad </h1>
<div id="container">
</div>
<button class="button" type="button">Choose Your Grid</button>

Categories

Resources