Use ngFor items to display another item before the first element
Asked Answered
R

1

1

I would like to display an array using ngFor but before the first element I want to display a card (the user can click inside to show a modal)

enter image description here

Here the code :

<div fxFlex="25" *ngFor="let product of products; let i = index">
    <div *ngIf="i == 0">                           
        <mat-card (click)="addProduct()" class="mat-card-add-button">
            <div fxLayout="row" fxLayoutAlign="center center" fxFlex="100%">
                <span style="font-size:32px;text-align:center">+<br />Add product</span>
            </div>
        </mat-card>
    </div>

    <div fxLayoutAlign="center stretch">
        <mat-card class="product">
            <img mat-card-image src="{{product.picture.url}}" alt="photo">
            <mat-card-title>{{product.name}}</mat-card-title>
            <mat-card-content>
                <p>
                    {{product.description}}
                </p>
            </mat-card-content>
            <mat-card-actions align="end">
            </mat-card-actions>
        </mat-card>
    </div>
</div>

This code doesn't work. It shows the first element (my card) and the second element like this :

enter image description here

Any idea ? Thank you very much !

EDIT :

ngFor loop products :

first loop => my card "add product"
second loop => product A

EDIT 2 : You'll find the answer to this here : Align mat-cards content (image, text and buttons)

Robledo answered 6/9, 2018 at 12:39 Comment(4)
Is this an angular or a css question?Lucylud
You should add class="product" on your add product card as wellPreemie
@Lucylud I'm using Angular and fxLayout. Maybe there is a css solution. I added the tag to my post the main problem is about resizing. I want my "button" in my ngFor loop with the same cssRobledo
It's not the best solution : I used unshift javascript method to set an element in my array.Robledo
R
4

In order to get the layout you described I had to adjust your code a little bit. Please refer to this stackblitz for a working example. I've tried to use as much @angular/flex-layout and as little CSS as possible.

EDIT: adjusted the stackblitz according to the comment / follow-up question. The changes are explained within my answer to the follow-up question.

Explanation

First of all you don't need to place your button inside the loop of the products. Therefore you can change the structure to this:

<div class="container">

    <mat-card>
      <!-- your button content -->
    </mat-card>
        
    <mat-card>
      <!-- the loop -->
    </mat-card>

</div>

Then you need to apply the proper flex-layout attributes.

Since the button is outside the loop now, you need to define the layout attributes on the container:

<div class="container" fxLayout="row wrap" fxLayoutAlign="center center" fxLayoutGap="25px"> ... </div>

In order to style the mat-card containing the button the same way as the mat-cards containing the products your button and your product loop need to have the same width which can be defined by using the fxFlex attribute, e.g.:

<mat-card fxFlex="180px" ... class="product"> <!-- button content --> </mat-card>
<mat-card fxFlex="180px" ... class="product"> <!-- loop content --> </mat-card>

For all styling which can't be defined by the flex-layout a class called "product" will be used.

To make the mat-card containing the button as high as the products some CSS can be used:

.product{
  min-height: 250px;
  margin-bottom: 25px; /* same as fxLayoutGap for even distribution */
  
  /* additional styling */
}

Keep in mind that if you use the min-height solution your button might be smaller as the products if the height of the product cards exceed 250px.

To always have the button be as high as the products you could use fxLayoutAlign="center stretch" instead of fxLayoutAlign="center center" but all mat-cards will shrink and grow in height depending on the window width. This might not be what you want.

Ruffianism answered 6/9, 2018 at 15:10 Comment(3)
Thank you for your answer. In your working example, you show the same picture (same size) and I have different size for pictures and then it doesn't work. If a picture is smaller, the card is smaller.Robledo
Wait a sec, I just saw your second question and I'm working on an answer to that as well.Ruffianism
Related to #52207088Robledo

© 2022 - 2024 — McMap. All rights reserved.