Angular's nested arrays can be transformed into a grid interface with ease

I am looking to generate a grid template from a nested array. The current method works well if the elements naturally have the same height, but issues arise when values are too long and some elements end up with different heights.

<div id="container" [style.grid-template-columns]="'repeat(outerArray.length, 1fr)'" [style.columnGap.rem]="1" *ngIf="outerArray.length != 0">
  <div class="outerArray" *ngFor="let inner of outerArray">
    <div *ngFor="let item of inner">
      {{item}}
    </div>
  </div>
</div>

The resulting items should be placed like this:

inner1value1 inner2value1 inner3value1

inner1value2 inner2value2 inner3value2

inner1value3

The desired grid look would be like this: (array with 8 inner arrays) https://i.sstatic.net/zop9Z.png

I aim to maintain the same width for each element in a column (while allowing columns to have different widths) and keep the same height in a row.

The table approach worked reasonably well, but the issue was that values from one inner array populate rows rather than columns, which doesn't align with what I need.

<table *ngIf="outerArray.length != 0">
  <tbody>
    <tr *ngFor="let inner of outerArray">
      <td *ngFor="let item of inner;">
        {item}}
      </td>
    </tr>
  </tbody>
</table>

The arrays have varying sizes (initially longer, then the rest have one fewer item).

A sample array may look like this:

let outerArray = [
  [
    "short",
    "bit longer",
    "example value"
  ],
  [
    "not so long, but longer string",
    "short words",
    "bitLonger twoWords"
  ],
  [
    "shorter array",
    "different lengths of strings"
  ],
  [
    "another shorter array",
    "string"
  ]
]

The number and length of arrays can vary; sometimes there is one array with 8 elements, while other times there are 8 arrays with 2 elements. Strings typically consist of one or two words, but occasionally words may have up to 15 characters, requiring multiple lines to fit within the screen width when there are only a few inner arrays.

My ideal solution is to create divs without nesting and position them correctly using CSS styling.

Answer №1

To ensure a proper layout, it is essential to have only one set of inner divs rather than a nested structure. To achieve this, I am utilizing ng-container for the inner loop. The uniqueness of ng-container lies in its ability to run multiple loops without generating additional HTML elements, resulting in a single set of divs.

When defining the property

[style.grid-template-columns]="'repeat('+outerArray.length+', 1fr)'"
, it is crucial to maintain a clear distinction between strings and JavaScript variables to avoid rendering issues.

Prior to the modification, the code was outputting repeat(outerArray.length, 1fr) as a static string instead of dynamically inserting the outerArray length. Hence, I adjusted the code to concatenate the necessary components as follows: 'repeat('(string) + outerArray.length(number) + ', 1fr)'(string)

In addition, the use of [style.grid-template-rows] is recommended with similar configurations as columns for comprehensive styling.

If uniform row height is desired, you can apply the provided CSS comment that adds an ellipsis effect to the element, ensuring consistent cell heights across rows.

Complete Code:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  styles: [`
  #container {
    display: grid;
  }
  /* .same-height {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  } */
  `],
  template: `
    <div id="container" [style.grid-template-columns]="'repeat('+outerArray.length+', 1fr)'" [style.grid-template-rows]="'repeat('+outerArray.length+', 1fr)'" [style.columnGap.rem]="1" *ngIf="outerArray.length != 0">
      <ng-container class="outerArray" *ngFor="let inner of outerArray">
        <div *ngFor="let item of inner" style="background-color: red;color: white; margin-bottom:2px;" class="same-height">
          {{item}}
        </div>
      </ng-container>
    </div>
  `,
})
export class App {
  outerArray = [
    ['short', 'bit longer', 'example value'],
    ['not so long, but longer string', 'short words', 'bitLonger twoWords'],
    ['shorter array', 'different lengths of strings'],
    ['another shorter array', 'string'],
  ];
}

bootstrapApplication(App);

Access the Stackblitz Demo Here

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

Images with scratches visible in Chrome

This puzzle may seem easy to some, but it's been quite challenging for me. I've encountered a discrepancy in how Firefox and Chrome render images (specifically technical drawings). Despite my attempts to use image-rendering: -webkit-optimize-cont ...

When using ngFor, a conversion from a string literal type to a regular string occurs, resulting in an error that states: "Element implicitly has an 'any' type because an expression of type 'string' cannot be utilized..."

When utilizing the iterator *ngFor, it converts a string union literal type ("apple" | "banana") to a string type. However, when attempting to use it as an index of an array expecting the correct string union literal type, an error occu ...

npm ERROR! Encountered an unexpected symbol < within the JSON data at position 12842

I keep encountering an error every time I attempt to install a package or run npm install. Despite my limited experience with Angular 4, having only started using it a week ago, I am puzzled by this error. Any guidance on how to resolve it would be greatly ...

Rendering a Nativescript component once the page has been fully loaded

I'm currently working on integrating the WikitudeArchitectView into my TypeScript code. I've successfully registered the element in the main.ts TypeScript file: var architectView = require("nativescript-wikitudearchitectview"); registerElement ...

Blending HTML template and WordPress PHP file

I am facing a challenge while attempting to implement a Wordpress template on one of the pages of my website, specifically at http://www.windowblindshadeshutters.com/blog/. The blog has been successfully created, however, I am having trouble preserving our ...

How can the "Search within page" feature locate words that are divided between different elements?

I need to present text in groups of a specific length while still being able to search for text that spans multiple groups on the page. Additionally, I want to include a character above each group. My current approach is as follows: body { marg ...

HTML formatting for text

I recently created an HTML website using Dreamweaver. I faced an issue while trying to design a section within an article using tables to incorporate both text and images. Unfortunately, the tables did not have rounded edges as I desired. I am reaching out ...

Converting a String into a Type or Component in Angular: A Step-by-Step Guide

Is it feasible in Angular to convert a string into a specific type or component? For instance, if I have the string "ListComponent", could I dynamically add a ListComponent to the application without using mapping techniques? stringComponent = "ListComp ...

Constructing a horizontal slider using vertically floating divs

Struggling to create a basic horizontal image slider using overflow:hidden and floating divs. Despite efforts, the divs keep stacking vertically instead of horizontally. Numerous online examples have been attempted without success. HTML: <div id="slid ...

Preventing Unwanted Scroll with jQuery

I'm currently working on a project where I have several description blocks that are meant to fade in when the corresponding image is clicked. The fading effect works fine, but there's an issue with the page scrolling up each time a new image is c ...

How to create a dynamic background color animation in jQuery similar to a progress bar animation

I have a container with text content (for example: My Name) and it is displayed in a RED background color along with a button. What I am looking for : When the button is clicked, I want to change the background color of the container from RED to BLUE, si ...

Formatting numbers in Angular 4 to display in Million or Thousand format

I need assistance with formatting numbers in my Angular 4 application. I want to display the number in a certain format based on its value. For example, if the number is 12.23 million, it should be displayed as 12.2M (with one decimal place). If the numbe ...

Having trouble with Image and Css not displaying correctly when using CodeIgniter 3 with DomPDF?

I'm currently utilizing CodeIgniter 3 and dompdf to convert an HTML view into a PDF. While I am able to successfully convert the HTML to PDF, the proper styling is not being applied. All necessary CSS files have been included as custom design in the v ...

Aligning the Bootstrap navbar to the right causes the items to shift to the left

UPDATE: The issue has been resolved. It turns out that the navbar was not extending to 100% width and reaching the edges of the screen. I am currently facing a challenge with a Bootstrap 4 navbar, similar to issues I encountered with the previous version. ...

Adjusting the columns of two tables when one table is held in place

My dilemma involves managing two tables: In the scenario, Table 1 remains fixed in place serving as a header that is always visible. Meanwhile, Table 2 acts as the data table. I am not a fan of fixed widths for my tables; I prefer them to dynamically adj ...

Stop the container from wrapping and allow its children to wrap instead

Here is a snapshot of my current layout: <div class="left"> ... </div> <div class="right"> <div class="inner" /> ... several more of these ... <div class="inner" /> </div> My CSS code looks like this: ...

Explanation for aligning anchors within an HTML <div>

I'm faced with this HTML snippet: <div class="row"> <div class="col-md-10 social-icons"> <a href="https://www.youtube.com/" target="_blank"><img src="/images/youtube-i.png"></a> <a href="https://gi ...

Merging Two mat-error Elements in Angular

I recently dived into the world of Angular by following their official tutorial. Curiosity got the best of me and I started experimenting with error handling using Angular Material when a user enters their email. I'm wondering if there's a way to ...

Div controls the margins of all other elements

I am encountering an issue when trying to position #slider, where the navigation and elements above it also move. It seems as though they are contained within #slider, even though they are not. HTML: <div id="slider" class="clearfix"> <d ...

The services generated by OpenAPI Generator typescript-angular are experiencing failures

While utilizing version 2.4.26 of this OpenApi generator ("@openapitools/openapi-generator-cli": "^2.4.26"), I am encountering issues with Angular services (Angular Version 13.2.0). For example, the services are passing too many arguments to the Angular Ht ...