Muhammad Zeeshan
Muhammad Zeeshan

Reputation: 4641

How to add Row after every 3 columns in angular

What i am trying to do is add a row div after every 3 colum divs

Example Output need:

<div class="row">
     <div class="col-md-6"></div>
     <div class="col-md-6"></div>
     <div class="col-md-6"></div>
</div>

I have an array of products i am iltrating like this

<div class="row" *ngFor="let p of relatedProperties;let i = index">
    <div class="col-md-6"  *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
    <div class="col-md-6" *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
    <div class="col-md-6" *ngIf="relatedProperties[i].title !== undefined">{{ relatedProperties[i].title }}</div>
  </div>

But the problem is that my every row prints same title on one iltration and second on next iltration

Current output

<div class="row">
     <div class="col-md-6">Title1</div>
     <div class="col-md-6">Title1</div>
     <div class="col-md-6">Title1</div>
</div>

<div class="row">
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title2</div>
</div>

<div class="row">
             <div class="col-md-6">Title3</div>
             <div class="col-md-6">Title3</div>
             <div class="col-md-6">Title3</div>
</div>

Desired Output

<div class="row">
         <div class="col-md-6">Title1</div>
         <div class="col-md-6">Title2</div>
         <div class="col-md-6">Title3</div>
    </div>

    <div class="row">
             <div class="col-md-6">Title4</div>
             <div class="col-md-6">Title5</div>
             <div class="col-md-6">Title6</div>
    </div>

    <div class="row">
                 <div class="col-md-6">Title7</div>
                 <div class="col-md-6">Title8</div>
                 <div class="col-md-6">Title9</div>
    </div>

Upvotes: 1

Views: 2356

Answers (3)

chafank
chafank

Reputation: 389

You can use this to add a row after every 3 columns.

<ng-container *ngFor="let p of relatedProperties; let i = index">
  <div class="row" *ngIf="(i%3)==0"> 
    <div class="col-md-6"  *ngFor="let p of relatedProperties.slice(i, i+3)>
       <span *ngIf="relatedProperties[i].title !== undefined"> {{ relatedProperties[i].title }} </span>
     </div>
   </div>    
</ng-container>

Upvotes: 0

d-h-e
d-h-e

Reputation: 2548

If you split your Array into subarrays with always 3 titel's then you can easy loop through this Array in your template.

https://ng-run.com/edit/zZsztdvTOTpzbUC5Buuj?open=app%2Fapp.component.ts

component html

<div class="row" *ngFor="let row of newTitleArr; let i = index">
    <div class="col" *ngFor="let col of newTitleArr[i]">{{ col.title }}</div>
</div>

component ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  titleArr = [
    { title: 'title1' },
    { title: 'title2' },
    { title: 'title3' },
    { title: 'title4' },
    { title: 'title5' },
    { title: 'title6' },
    { title: 'title7' },
    { title: 'title8' },
    { title: 'title9' },
    { title: 'title10' },
    { title: 'title11' },
    { title: 'title12' },
    { title: 'title13' },
  ];

  newTitleArr:any[];

  ngOnInit() {
     this.newTitleArr = this.splitArr(this.titleArr, 3)
  }

  splitArr(arr, size) {
     let newArr = [];
     for(let i = 0; i< arr.length; i += size) {
       newArr.push(arr.slice(i, i+size));
     }
     return newArr;
  }
}

Upvotes: 3

Francisco Santorelli
Francisco Santorelli

Reputation: 1338

Maybe this works, but Im unsure

<ng-container *ngFor="let p of relatedProperties; let i = index">
   <div class="row" *ngIf="(i + 1) / 3 === 1">
      <div class="col-md-6"  *ngIf="relatedProperties[i - 2].title != null">{{ relatedProperties[i].title }}</div>
      <div class="col-md-6"  *ngIf="relatedProperties[i - 1].title != null">{{ relatedProperties[i].title }}</div>
      <div class="col-md-6"  *ngIf="relatedProperties[i].title != null">{{ relatedProperties[i].title }}</div>
   </div>
</ng-container>

Also, I gotta say this feels pretty hacky, but if this is what you request, this should work

edit:

Note that strict null (a == null) is better than checking for undefined (a === undefined), as it will check for both undefined or null. In your case title != null.

Also, you could build an iterable that holds the structure you want in a cleaner way.

instead of having [title1, title2, title3, title4, title5, title6...] you should try to have [[title1, title2, title3], [title4, title5, title6], ...] which is way cleaner and allows you to simply have two *ngFors inside your template

<element1 *ngFor="let innerArray of myArray; let i = index">
  <element2 *ngFor="let title of innerAray; let j = index">
  </element2>
</element1>

And finally, I suggest you avoid calling a variable 'p', that's bad practice.

Upvotes: 0

Related Questions