Freddy Freddy - 4 months ago 27
HTML Question

Angular Material transform table to boxes on small screens

I have an AngularJS website with the Angular Material design. On one screen I have a table and right there is my problem, because tables in Material design aren't really responsive.

My question: Is it possible to show the normal table on big screens and transform the table information from single lines to a box-like layout when the page is displayed on smaller screens? Something like this:

Name | City | Gender
------------------------------
Alice | NY | f
Bob | LA | m


This table on big screens. And the following design on smaller screens.

Name Alice
City NY
Gender f
-------------
Name Bob
City LA
Gender m


I am aware of the layout options with the screen sizes (xs, sm, ...).

I tried to show tables based on this code on smaller screens, but then all the information are in a single line. And not one line for every attribute.

<tr md-row ng-repeat="person in persons">
<th md-cell>Name</th>
<td md-cell>{{person.name}}</td>
<th md-cell>State</th>
<td md-cell>{{person.state}}</td>
<th md-cell>Gender</th>
<td md-cell>{{person.gender}}</td>
</tr>


Result:

Name Alice City NY Gender f
...


Is there any good solution for my problem? Or another approach I am not aware of?

Answer

This is how I would do it - CodePen

This solution is flexible to allow for changes to user information.

Markup

<div ng-controller="AppCtrl" ng-cloak="" ng-app="MyApp" layout-fill>
  <div display="column" ng-if="showColumn">
    <div ng-repeat="user in users">
      <div ng-repeat="(key, value) in user" layout="row">
        <span flex>{{key}}</span>
        <span flex>{{value}}</span>
      </div>
      <md-divider></md-divider>
    </div>
  </div>

  <div ng-if="showRow">
    <div ng-repeat="user in users">
      <div ng-if="$first">
        <div layout="row">
          <span flex ng-repeat="(key, value) in users[0]">
            {{key}}
          </span>
        </div>
        <md-divider></md-divider>
      </div>
      <div layout="row">
        <span flex ng-repeat="(key, value) in user">
          {{value}}
        </span>
      </div>
    </div>
  </div>
</div>

JS

angular.module('MyApp',['ngMaterial', 'ngMessages'])

.controller('AppCtrl', function($scope, $mdMedia, $window) {
  $scope.users = [
    {Name: "Alice", City: "NY", Gender: "f"},
    {Name: "Bob", City: "LA", Gender: "m"}
  ];
  $scope.showColumn = true;
  $scope.showRow = false;

  display();

  angular.element($window).bind("resize", function() {
    display();
    $scope.$apply();
    });

  function display () {
     if ($mdMedia("gt-xs")) {
        $scope.showColumn = true;
        $scope.showRow = false;
      }
      else if ($mdMedia("xs")) {
        $scope.showColumn = false;
        $scope.showRow = true;
      }
  }
});