Home > OS >  How can I get the size of the grid to stay the same regardless of the number of divs inside (the new
How can I get the size of the grid to stay the same regardless of the number of divs inside (the new

Time:01-19

I am working on The Odin Project and I am on the etch-a-sketch section. I believe I have every part working except resizing the grid when a new number is entered. Any help would be greatly appreciated.

const container = document.getElementById("container");
const button = document.querySelector("input");

button.addEventListener('click', ()=> {
    numOfSquares();
})

function numOfSquares() {
    if (button.value === "number of squares") {
        let newNumPerRow = prompt("how many squares per side would you like?", "");
        let parse = parseInt(newNumPerRow);
        makeRows(parse);
    }
}

function hoverColor() {
    let items = document.querySelectorAll('.gridItems');
    items.forEach(item => {
        item.addEventListener('mouseover', () => {
            item.style.backgroundColor = 'orange';
        });
    });
}

function clearGrid() {
    const gridArray = Array.from(container.childNodes);
    gridArray.forEach(element => {
      container.removeChild(element);
    })
  }

function makeRows (numberPerRow) {
    clearGrid();
    const total = (numberPerRow * numberPerRow)   numberPerRow;
    const box = numberPerRow   1;

    for (i=0; i < total; i  ) {
        const div = document.createElement('div');
        container.appendChild(div).className = "gridItems";

        if (i % box === 0) {
        div.style.cssText = "border: 0; height: 0; width: 100%";
        } else {
        div.style.cssText = "border: 1px solid black; height: 25px; width: 25px";
        }

    }
    hoverColor();
}

makeRows(16);

I have tried to change the inline div style in javascript portion underneath the makeRows function, but nothing seems to work. Unless I completely miss something.

CSS

* {
    box-sizing: border-box;
}

#container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
}

HTML

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Etch-A-Sketch Project</title>
    <link rel="stylesheet" href="style.css">
    <script src="index.js" defer></script>
</head>
<body>
    <input type="button" value="number of squares">
    <div id="container">

    </div>
</body>
</html>

CodePudding user response:

I'm not familiar with the project exactly, but taking a look at your js, it looks like you're hard-coding the width value for the elements. Something like this may be helpful if you need to use flex:

function makeRows(numberPerRow) {
    clearGrid();
    const total = numberPerRow * numberPerRow   numberPerRow;
    const box = numberPerRow   1;

    for (i = 0; i < total; i  ) {
        const div = document.createElement("div");
        container.appendChild(div).className = "gridItems";

        if (i % box === 0) {
            div.style.cssText = "border: 0; height: 0; width: 100%";
        } else {
            //dynamically resize?
            div.style.cssText = `border: 1px solid black; height: ${
                1000 / numberPerRow
            }px; width: ${1000 / numberPerRow}px`;
            //dynamically resize?
        }
    }
    hoverColor();
}

Since you are making a grid though, it may be more helpful to use grid layout rather than flex.

https://developer.mozilla.org/en-US/docs/Web/CSS/grid

https://www.w3schools.com/css/css_grid.asp

CodePudding user response:

I'm giving you a solution using display: grid as this is the preferred method to use when creating a grid (it's in the name).

I left the HTML the exact same.

const container = document.getElementById("container");
const button = document.querySelector("input");

button.addEventListener('click', ()=> {
    numOfSquares();
})

function numOfSquares() {
    if (button.value === "number of squares") {
        let newNumPerRow = prompt("how many squares per side would you like?", "");
        let parse = parseInt(newNumPerRow);
        makeRows(parse);
    }
}

function hoverColor() {
    let items = document.querySelectorAll('.gridItems');
    items.forEach(item => {
        item.addEventListener('mouseover', () => {
            item.style.backgroundColor = 'orange';
        });
    });
}

function clearGrid() {
    const gridArray = Array.from(container.childNodes);
    gridArray.forEach(element => {
      container.removeChild(element);
    })
  }

function makeRows (numberPerRow) {
    clearGrid();
    //Set the grid template columns straight from JavaScript
    container.style.gridTemplateColumns = `repeat(${numberPerRow}, 1fr)`;
    
    //Resolved an issue here that was adding an extra row
    const total = numberPerRow * numberPerRow;
    
    //Idk what the point of box was so I removed it for the sake of the answer

    for (i = 0; i < total; i  ) {
        const div = document.createElement('div');
        container.appendChild(div).className = "gridItems";
        
        //Moved the gridItem styling to CSS
    }
    
    hoverColor();
}

makeRows(16);
* {
    box-sizing: border-box;
}

#container {
    display: grid;
    width: 100%; /* Set whichever width you want here */
    aspect-ratio: 1/1;
}

.gridItems {
    border: 1px solid black;
}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Etch-A-Sketch Project</title>
    <link rel="stylesheet" href="style.css">
    <script src="index.js" defer></script>
</head>
<body>
    <input type="button" value="number of squares">
    <div id="container">

    </div>
</body>
</html>

CodePudding user response:

  1. Add this at the top of you js and specify the size of your grid in px. You can add it to makeRows as a variant:
const preservedWidth = 600;
  1. Also add boxWidth to makeRows to calculate the width of your grid element:
    const boxWidth = preservedWidth / numberPerRow;
  1. Change this:
div.style.cssText = "border: 1px solid black; height: 25px; width: 25px";

to:

div.style.cssText = `border: 1px solid black; height: ${boxWidth}; width: ${boxWidth}`;

This is the whole JS code:

const container = document.getElementById("container");
const button = document.querySelector("input");
const preservedWidth = 300;

button.addEventListener('click', ()=> {
    numOfSquares();
})

function numOfSquares() {
    if (button.value === "number of squares") {
        let newNumPerRow = prompt("how many squares per side would you like?", "");
        let parse = parseInt(newNumPerRow);
        makeRows(parse);
    }
}

function hoverColor() {
    let items = document.querySelectorAll('.gridItems');
    items.forEach(item => {
        item.addEventListener('mouseover', () => {
            item.style.backgroundColor = 'orange';
        });
    });
}

function clearGrid() {
    const gridArray = Array.from(container.childNodes);
    gridArray.forEach(element => {
      container.removeChild(element);
    })
  }

function makeRows (numberPerRow) {
    clearGrid();
    const total = (numberPerRow * numberPerRow)   numberPerRow;
    const box = numberPerRow   1;
    const boxWidth = preservedWidth / numberPerRow;

    for (i=0; i < total; i  ) {
        const div = document.createElement('div');
        container.appendChild(div).className = "gridItems";

        if (i % box === 0) {
        div.style.cssText = "border: 0; height: 0; width: 100%";
        } else {
        div.style.cssText = `border: 1px solid black; height: ${boxWidth}; width: ${boxWidth}`;
        }

    }
    hoverColor();
}

makeRows(16);
  • Related