Create dynamic cells for CSS grid using JavaScript

I have been manually generating grid cells in a specific pattern by copying and adjusting <div> elements. Although this method works, I am interested in creating an algorithm that can automatically generate the desired layout. The left box in the example below illustrates the dynamic calculation I am aiming for.

function createGridCells(){
let cells = '';
  for(let a = 1; a <= 10; a++){
    for(let b = 1; b <= a; b++){
        cells += `<div style="background:#fd8362; grid-area: ${a % b} / ${a % b} / ${a % b} / ${a % b}">
        ${b}
      </div>`
    }
  }
  return cells;
}

document.getElementById("grid-body-algorithm").innerHTML = createGridCells();
#grid-body,
#grid-body-algorithm {
    float:left;
    margin-right:30px;
    box-shadow: 0 0 10px rgba(0, 0, 0, .2);
    text-align: center;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(5, 1fr);
    justify-content: center;
    align-content: end;
    border-radius: 5px;
    width:150px;
    height:150px;
    color:#444444;
    padding:1px;
}

#grid-body > *,
#grid-body-algorithm > *{
  border:1px solid white;
}
<div id="grid-body">
  <div style="background:#fd8362; grid-area: 1 / 1 / 1 / 1">1</div>

  <div style="background:#ffad97; grid-area: 2 / 1 / 2 / 1">1</div>
  <div style="background:#ffad97; grid-area: 1 / 2 / 1 / 2">2</div>

  <div style="background:#ffded6; grid-area: 3 / 1 / 3 / 1">1</div>
  <div style="background:#ffded6; grid-area: 2 / 2 / 2 / 2">2</div>
  <div style="background:#ffded6; grid-area: 1 / 3 / 1 / 3">3</div>

  <div style="background:#fff0ec; grid-area: 4 / 1 / 4 / 1">1</div>
  <div style="background:#fff0ec; grid-area: 3 / 2 / 3 / 2">2</div>
  <div style="background:#fff0ec; grid-area: 2 / 3 / 2 / 3">3</div>
  <div style="background:#fff0ec; grid-area: 1 / 4 / 2 / 4">4</div>
</div>

<div id="grid-body-algorithm">
  
</div>

Answer №1

By examining the desired output, it is evident that the color of a cell is determined by the taxicab distance from the top-left corner, while the column number dictates the text content of the cell.

When implementing the inner loop, it is important to set a maximum limit on the taxicab distance. This limit can be customized as a parameter in your function. In this specific example, the maximum distance is set at 3 (which means cells up to 3 taxicab steps away from the top-left cell are considered).

Moreover, the color intensity seems to decrease with an increase in taxicab distance. To achieve this effect, adjustments can be made to the alpha component of the background color using the RGBA model. The alpha value ranges between 0 and 1.

Instead of generating HTML directly, I chose to create a document fragment for more controlled manipulation of cell attributes using JavaScript syntax, resulting in a more object-oriented approach.

The CSS styles provided have not been altered in this implementation.

In addition to the existing code, I have introduced an input field that enables users to specify the maximum taxicab distance:

function calcCells(maxDistance) {
  const fragment = document.createDocumentFragment();
  for (let row = 1; row <= 5; row++) {
    // row + col - 2 represents the taxicab distance from the top-left corner
    for (let col = 1, distance = row - 1; distance <= maxDistance && col <= 5; col++, distance++) { 
        const cell = document.createElement("div");
        // Adjust background transparency based on the calculated alpha value
        cell.style.background = `rgba(240,120,80,${1 - (distance + 0.5) / (maxDistance + 1)})`;
        cell.style.gridArea = [row, col, row, col].join(" / ");
        cell.textContent = col;
        fragment.appendChild(cell);
    }
  }
  return fragment;
}

const inputDistance = document.querySelector("input");
const outputGrid = document.getElementById("grid-body-algorithm");

function refresh() {
    const maxDistance = +inputDistance.value;
    outputGrid.innerHTML = ""; // Clear previous content
    outputGrid.appendChild(calcCells(maxDistance));
}

inputDistance.addEventListener("click", refresh);
refresh();
#grid-body,
#grid-body-algorithm {
    float:left;
    margin-right:30px;
    box-shadow: 0 0 10px rgba(0, 0, 0, .2);
    text-align: center;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(5, 1fr);
    justify-content: center;
    align-content: end;
    border-radius: 5px;
    width:150px;
    height:150px;
    color:#444444;
    padding:1px;
}

#grid-body > *,
#grid-body-algorithm > *{
  border:1px solid white;
}
<div id="grid-body-algorithm"></div>
distance: <input type="number" value="3" min="0" max="8">

Answer №2

If you want to ensure that the DOM structure is fully loaded before accessing elements, consider using an eventListener or the defer attribute.

Avoid using innerHTML to create elements as it can be slow and poses a risk of XSS Injection. Instead, opt for methods like appendChild or insertAdjacentHTML.

Using CSS for styling rather than inline styles is recommended for cleaner code. Additionally, utilizing SASS can further streamline your styling process.

When creating grid elements dynamically, remember to use separate variables for rows and columns in your loops. The first loop should handle rows while the second loop manages columns:

window.addEventListener('DOMContentLoaded', function() {
  for (let i = 1, n = 5; i < 5; i++) {
    for (let j = 1; j < n; j++) {
      document.querySelector('#grid-body-algorithm').insertAdjacentHTML('beforeend', `
        <div data-row="${i}" data-col="${j}">${j}</div>`
      );
    }
    n--;
  }
})
#grid-body-algorithm {
  width: 150px;
  height: 150px;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(5, 1fr);
  padding: 2px;
  gap: 2px;
  border: 1px solid black;
}

[data-row="1"] { grid-row: 1 / 2; }
[data-row="2"] { grid-row: 2 / 3; }
[data-row="3"] { grid-row: 3 / 4; }
[data-row="4"] { grid-row: 4 / 5; }
[data-row="5"] { grid-row: 5 / 6; }

[data-row="1"][data-col="1"] { background: #fd8362; }
[data-row="1"][data-col="2"],
[data-row="2"][data-col="1"] { background: #ffad97; }
[data-row="1"][data-col="3"],
[data-row="2"][data-col="2"],
[data-row="3"][data-col="1"] { background: #ffded6; }
[data-row="1"][data-col="4"],
[data-row="2"][data-col="3"],
[data-row="3"][data-col="2"],
[data-row="4"][data-col="1"] { background: #fff0ec; }
<div id="grid-body-algorithm"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to delete a particular tag using jQuery?

Illustration: htmlString = '<font><a>Test Message</a></font>'; updatedHtmlString = htmlString.find('font').remove(); Desired Result: <a>Test Message</a> This code snippet is not yielding the expe ...

Capturing the dynamic server response with nested JSON structures

I am in the process of creating a dynamic data-binding function named assemble that requires two input parameters: server response (JSON) - nested JSON object. instruction set (JSON) - a configuration object that dictates the binding. The Issue: The cur ...

Next.js appending [object%20Object] to the URL's endpoint

I encountered an error when launching my next app using "npm run dev". The error occurred during the pre-render attempt: GET http://localhost:3000/aave/fundamentals/economics/[object Object] [HTTP/1.1 404 Not Found 434ms] The issue is not specific to thi ...

Performing ad-hoc queries on a Postgresql database using Node.js and Express to manipulate row data

I am faced with a challenge of selecting one entry randomly from a table containing 46 entries, and then passing the data from that particular query to my handlebars files. I am unsure about how to approach the task of randomly querying the database and re ...

Difficulty in preventing the website from reloading when accessing tabs

I am working on a function that allows users to access the content of a tab without causing the page to reload. Initially, I tried using something like $( "#tab1" ).click(function() { $("#content").load("tab1.html #content > *"); }); but unfortun ...

How to implement setState within a Promise function using useEffect in React functional components with hooks?

I am struggling to set the value of a hook within a Promise function inside a useEffect(), and then store the returned promise value in the fruit hook so that it can be accessed in the return function of MyComponent() This is what I have attempted so far: ...

The shopping cart in our e-commerce website is refreshed in real-time thanks to the integration of J

I am currently enhancing the Codeigniter Cart with JQuery by making an Ajax call for updates. Below is my JQuery function: $(function() { $('.cart_form select').on('change', function(ev) { var rowid = $(this).attr('c ...

Displaying the content of a modal window

I am working on a modal that needs to print only the content within it, nothing else. Here is the setup for the button inside the modal: This should not be printed... <button id="btnPrint">Print (this btn should not be printed!)</button> ...

A guide on rotating loaders and inserting custom text within loaders using CSS

Seeking assistance to modify my code for creating a unique loader design. The inner loader needs to remain static with only top and bottom segments, while the middle loader rotates anti-clockwise and the outer loader rotates clockwise. Additionally, the ...

Encountering issues with running `npm start` following the creation of a fresh React project using create

Encountering an issue with react-scripts after setting up a new react project. I initiated the project using npx create-react-app dashboard. Upon entering the dashboard directory and executing npm start (without any prior actions), the following error is d ...

Automatically updating database with Ajax post submission

I have customized the code found at this link (http://www.w3schools.com/PHP/php_ajax_database.asp) to update and display my database when an input box is filled out and a button is clicked to submit. Below is the modified code: <form method="post" acti ...

Trying to align a Material UI button to the right within a grid item

I'm attempting to right float the button below using material-ui, but I'm unsure of how to achieve this: <Grid item xs={2}> <Button variant="contained" color="secondary&quo ...

unable to save the information to mongoDB

I've been attempting for the past 3 hours to save data from an HTML form to MongoDB using Node.js. When I click submit, it redirects to another page displaying the submitted data in JSON format, but it's not getting stored in the database. Here ...

Whenever I try to include something within the `componentWillUnmount` function,

I'm currently learning React on my own. I've been trying to save session data in my componentWillUnmount method. However, when I add code inside componentWillUnmount, nothing seems to happen. I tried debugging by adding console logs and debugger ...

Unable to successfully import an external HTML file that contains a script tag

I am currently experiencing an issue with my index.html <!doctype html> <html lang="en"> <head> <meta charset="utf-8> <title>MyApp</title> <link rel="import" href="./common.html"> </head> <body> ...

Error in ReactJS: Attempting to access property 'preventDefault' of an undefined value

Looking to implement a simple onClick event/function in ReactJS. Upon clicking the button, I intend to execute a function named "onClick", but I encounter this error message in the console: app.js:62 Uncaught TypeError: Cannot read property 'prevent ...

Syntax error is not caught - why are there invalid regular expression flags being used?

I'm attempting to dynamically create rows that, when clicked, load a view for the associated row. Check out my javascript and jquery code below: var newRow = $('<tr />'); var url = '@Url.Action("Get", "myController", new ...

Having trouble locating elements using Selenium in Python?

Let me start by acknowledging that the process of finding elements has been discussed at length in various resources. Having searched and experimented for several hours, I am facing an issue with looping through buttons using Selenium. Below is the HTML co ...

Javascript recursive method for fetching data entries

Seeking a solution to retrieve interconnected records based on a parent column, where the relation can be one or many on both ends. After attempting a recursive function without success, I found my code became overly complex and ineffective. Is there a st ...

What is the process for integrating GitHub repository code into my client-side JavaScript application?

I am attempting to incorporate the GitHub repository "zipcelx" into my client-side JavaScript, but all I see is an option to download it from npm, which I do not understand. It would be helpful if someone could explain how a module meant for client-side us ...