16

I am trying to create a grid of three cards per row using ng-repeat. I have a normal array of javascript objects attached to the scope. The code below will create a fresh row for every card.

<div layout="row" ng-repeat='post in posts' layout-fill="" layout-align="">
<md-card>
  <md-card-content>
    <h2 class="md-title">{{post.title}}</h2>
    <p>
      {{post.summary}}
    </p>
  </md-card-content>
  <div class="md-actions" layout="row" layout-align="end center">
    <md-button>View More</md-button>
  </div>
</md-card>
<br>

enter image description here

How can I iterate over my array and display the cards in rows of three? I looked at this post and this post but I do not see how they apply to angular material

Community
  • 1
  • 1
Connor Leech
  • 18,052
  • 30
  • 105
  • 150

4 Answers4

21

I have created something similar to what you may want. The md-card is wrapped within a div having layout-wrap. The divs are dynamically generated after reading.

Here is the code :

<div class='md-padding' layout="row" layout-wrap>
    <md-card style="width: 350px;" ng-repeat="user in users">
      <img src="http://placehold.it/150x150" class="md-card-image" alt="user avatar">
      <md-card-content>
        <h2>{{user}}</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
      </md-card-content>
      <div class="md-actions" layout="row" layout-align="end center">
        <md-button>Save</md-button>
        <md-button>View</md-button>
      </div>
    </md-card>
  </div>

The cards width can be adjusted with inline styling, hope it helps.

isherwood
  • 58,414
  • 16
  • 114
  • 157
  • this is ok, but I think it'd be even better if the wrapper div was defined with `flex` so that each `md-card` could inherit and define a responsive value `flex="33"` instead of binding a fixed width in the card – gru Feb 16 '16 at 19:05
  • @gru Can you give the example? This sounds great but I can't create your solution in practice. – Jenan Mar 14 '16 at 19:32
  • hey @gru thank you for your example, but it is not responsive - in very small witdth is broken. Is it possible to declare some attribute where I set the definition of count of cards in view for different width? – Jenan Mar 15 '16 at 15:02
  • 1
    @Jenan in that case you should just use the normal breakpoint notation as described in [angular material layout docs](https://material.angularjs.org/latest/layout/introduction) e.g. you'd have flex-sm, flex-md, etc. – gru Mar 16 '16 at 16:57
4

I just needed this; here's a more comprehensive solution, only using the layout features, for 3 columns:

<md-content class="md-padding" layout="row" layout-wrap>
    <div flex="33" ng-repeat="i in [1,2,3,4,5,6,7]">
        <md-card>
            // ...
        </md-card>
    </div>
</md-content>

The card must be wrapped inside a correctly-sized div to keep the margins under control and avoid overflow.

Jaime Gómez
  • 6,961
  • 3
  • 40
  • 41
  • `layout-wrap` is what solved my issue, flex wasn't working properly. I still can't understand why it is needed, I'm gonna read a bit more about how this works. Thanks! – Alisson Reinaldo Silva May 08 '17 at 12:08
3

To be compling to material/angular, you must use flex attr to md-card. Flex attr will give you a proportional width about its parent.

<div class='md-padding' layout="row" layout-wrap>
    <md-card flex="40" flex-sm="80" ng-repeat="user in users">
      <img src="http://placehold.it/150x150" class="md-card-image" alt="user avatar">
      <md-card-content>
        <h2>{{user}}</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p>
      </md-card-content>
      <div class="md-actions" layout="row" layout-align="end center">
        <md-button>Save</md-button>
        <md-button>View</md-button>
      </div>
    </md-card>
  </div>

In this example, you will have two cards (40% each) and when the screen resizes to -sm, the cards will be at 80%.

sGambolati
  • 783
  • 8
  • 25
0

You can use class="grid-container" for this. As an example a code snippet like this,

<div class="grid-container">
    <mat-grid-list cols="2" rowHeight="350px">
        <mat-grid-tile [colspan]="1" [rowspan]="1">
            <mat-card class="mat-elevation-z8 card-prop"> CARD 1
            </mat-card>  
        </mat-grid-tile>
        <mat-grid-tile [colspan]="1" [rowspan]="2">
            <mat-card class="mat-elevation-z8 card-prop"> CARD 2
            </mat-card>  
        </mat-grid-tile>
        <mat-grid-tile [colspan]="1" [rowspan]="1">
            <mat-card class="mat-elevation-z8 card-prop"> CARD 3
            </mat-card>  
        </mat-grid-tile>
    </mat-grid-list>
</div>

Will produce an output similar to this.

enter image description here

Nishan
  • 3,644
  • 1
  • 32
  • 41