angulargridangular-material2angular-flex-layout

Change the layout or cols value of md-grid-list based on screen size


I am using Grid List of angular material 2.

Here is the plunker https://plnkr.co/edit/0v9R3e4x3tThh85147x7?p=preview

Here I have defined a grid list of three columns and there are three tiles (showing in a row as defined as three columns).

I want to change the layout direction of tiles like if the screen size gets shrunk at a certain point then all the tiles should be in column one below the other that is somehow value of cols parameter changed to 1. How is it possible? Is it possible with flex-layout ?


Solution

  • Only for a div:

    To apply column change only to a div, add an elementRef to the div for example, #gridView. Use this ref to get the width of the div containing the grid-list. Then we can use [fxShow] from flex-layout when div width changes and set the col number based on the size of the div.

    html:

    <div style="background: skyblue" #gridView [ngStyle]="{ 'width.px': divSize }"
        [fxShow]="setColNum(gridView.style.width)">
        <md-grid-list [cols]="columnNum" rowHeight="100px">
            <md-grid-tile>
                A
            </md-grid-tile>
    
            <md-grid-tile>
                B
            </md-grid-tile>
    
            <md-grid-tile>
                C
            </md-grid-tile>
        </md-grid-list>
    </div>
    

    ts:

    @ViewChild('gridView') gridView;
          
    columnNum = 3;
    
    divSize = 900;
    
    setColNum(div){
      // console.log(div);
      if(this.gridView.nativeElement.offsetWidth < 400){
        this.columnNum = 1;
      }
      if(this.gridView.nativeElement.offsetWidth >= 400 
          && this.gridView.nativeElement.offsetWidth < 800){
        this.columnNum = 2;
      }
      if(this.gridView.nativeElement.offsetWidth >= 800){
        this.columnNum = 3;
      }
    }
    

    demo

    Full Viewport:

    Yes, it's possible with flex-layout. In my testing I found that the fxLayout api doesn't play well with md-grid-list, so as an alternative, I used it's MediaChange, ObservableMedia features to detect screen size and set column number based on that.

    Edited Plunker, col size changes to 2 and 1 for screen size sm and xs.

    html:

    <md-grid-list [cols]="columnNum" 
                  rowHeight="100px">
      <md-grid-tile>
        A
      </md-grid-tile>
      
      <md-grid-tile>
        B
      </md-grid-tile>
      
      <md-grid-tile>
        C
      </md-grid-tile>
    </md-grid-list>
    

    component.ts:

    columnNum = 0;
    
    constructor(media: ObservableMedia) {
      media.asObservable()
        .subscribe((change: MediaChange) => {
          // alert(change.mqAlias);  
          console.log(change.mqAlias);
          if(change.mqAlias == 'xs'){
            this.columnNum = 1;
          }
          else if(change.mqAlias == 'sm'){
            this.columnNum = 2;
          }
          else{
            this.columnNum = 3;
          }
        });
    }