Components: create a material looking table (withOUT dataTable)

Created on 27 Mar 2017  路  14Comments  路  Source: angular/components

Bug, feature request, or proposal:

request

What is the expected behavior?

be able to use </md-header-row> or <md-cell> tags to do our own material design looking table

What is the current behavior?

those HTML tags are currently in 1e07b30
I expect those HTML tags does not come from the void ?

This merge request is relate to dataTable issue on #581 which is NOT what I'm asking here

current use of this tag will create the following error in console

Unhandled Promise rejection: Template parse errors:
'md-header-cell' is not a known element

What is the use-case or motivation for changing an existing behavior?

To be able to do our own table material looking without having to use/wait for dataTable

Which versions of Angular, Material, OS, browsers are affected?

the linked branch is not yet merge in as far as I know, but again, I expect the html tags name didn't came from the void.

Is there anything else we should know?

this is NOT relate to datatable ! but mention it on #581 could be usefull for some people

Most helpful comment

Solved

Ok, I have a solution to handle html table without data source in official angular material. It's easy to use. Just rebuild the dom generated table of angular material.

<div class="mat-table">
  <div class="mat-header-row">
    <div class="mat-header-cell">One</div>
    <div class="mat-header-cell">Two</div>
    <div class="mat-header-cell">Three</div>
  </div>
  <div class="mat-row">
    <div class="mat-cell">Tick</div>
    <div class="mat-cell">Trick</div>
    <div class="mat-cell">Track</div>
  </div>
</div>

It's fine for me. Meybe better as the html table.
If you want to use your traditional table, just extract the styles from angular material sources and modify it to the tag names of table. Source Path: material2-master\src\lib\table\table.scss.

For me this issue is done / closed. Maybe this example should be added to the official angular material documentation. Just demonstrate a solution without data source.

Update

Currently the solution above only works, if another table - official implementation with data source - was loaded before displaying the handcrafted table (s. above). The mat-table has to be initialized. If not the example above will not work correctly. Weird.

Workaround
Just add the table styling of mat-table to your global style. It looks like the mat-table style will not load until the componente has been used once before using "normal" divs with same classes as mat-table.
You cannot use the mat-table as tag. Because data source is required. It's a dilemma. 馃

.mat-table {
  display: block;
}

.mat-row,
.mat-header-row {
  display: flex;
  border-bottom-width: 1px;
  border-bottom-style: solid;
  align-items: center;
  min-height: 48px;
  padding: 0 24px;
}

.mat-cell,
.mat-header-cell {
  flex: 1;
  overflow: hidden;
  word-wrap: break-word;
}

Feel free to assign this to table, tr, td, th tags. But note: Maybe it does not work with thead and tbody.

Question: How to force material to load the mat-table theme without using the mat-table component?
Clean solution: The mat-table data source (dataSource attr) has to be optionally!

All 14 comments

Because we are working on a data-table, our preference would be to leave out a basic table (i.e., a <table> element with some css) in order to avoid confusion.

Ok, thanks for the quick answer.
Is any CSS source recommand by material for this? somewhere at your knowledge? can't find it in doc.

Material design lite has a cssified table: https://getmdl.io/components/index.html#tables-section

@jelbourn The current implementation of data-table is great for huge data sources. But in my opinion, it should be possible to create a table convertionelly in HTML without data source. Like:

<mat-table>
  <mat-header-row>
    <mat-header-cell>One</mat-header-cell>
    <mat-header-cell>Two</mat-header-cell>
    <mat-header-cell>Three</mat-header-cell>
  </mat-header-row>
  <mat-row *ngFor="let item of items;">
    <mat-cell>{{item.one}}</mat-cell>
    <mat-cell>{{item.two}}</mat-cell>
    <mat-cell>{{item.three}}</mat-cell>
  </mat-row>
</mat-table>

(Or just style the default table of html)
In many cases, you only want to display a short data list. A list with multiple columns.
It would be great if the material team implements a using like that beside the existing implementation with data source.

Should I start a new issue with this request? Or reopen this ticket?
Please do not underestimate this request. Many users ask for it.

Not sure I understand the correlation with the size of the data source and the syntax of the table template. Neither the data source nor table are opinionated on the size of the data.

In short: Nothing. 馃榾 Not much. I just wanted to demonstrate the use of html table without datasource to display a table with a handful data. I just missing a conventionally html table constructed in html and styled in pretty material theme.
Ok, I could download another material framework with css that styles tables or craft my own stylesheets for that. But why? Angular Material already has the style. The only requirement is to use the mat-table without data source.

<mat-table>
  <mat-header-row>
    <mat-header-cell>One</mat-header-cell>
    <mat-header-cell>Two</mat-header-cell>
    <mat-header-cell>Three</mat-header-cell>
  </mat-header-row>
  <mat-row>
    <mat-cell>Tick</mat-cell>
    <mat-cell>Trick</mat-cell>
    <mat-cell>Track</mat-cell>
  </mat-row>
</mat-table>

Or in default html tags with directives or classes. <table> <tr> <td> and so on.
That鈥榮 it. The most users of Angular Material expecting that. (to use a html table traditionally without data source collection. Just create a table with fixed values or with variables by handlebar template.

+1

I already have a JSON object in my component; what @Dominik-Andreas-Geng is proposing would allow my to render a table via mat-table using the JSON data I already have in my component.

I think you may be surprised to see that there is actually very little styling to match the material design spec. Essentially you'll want a height of 48px, a bottom border, and some padding between cells. I imagine the styling as a whole would make up about 10-20 lines of CSS (if that).

It'd be a lot of effort to support the layout you described using the table's directives (there's a lot going on under the hood with template refs for creating embedded views).

If it's complexity in building out your columns, I totally agree we can do better here and I am looking into simplifying the column definitions for simple cases like this.

e.g. a simple column such as this

<ng-container matColumnDef="name">
  <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
  <mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
</ng-container>

can be replaced by:

<mat-simple-column id="name"></mat-simple-column>

For the data source side of things, have you tried the new MatTableDataSource? It eliminates the need of trying to set up Observables and connect with your MatSort, MatPaginator, and filters.

In short: We have to write our own css or grab it from another material framework to style our "datasourceless" tables. Styling that never looks exactly like the styling of this Angular Material. Because it's not exactly the same. Material is not always equal Material. Every implementation is different. It's a ugly way to implement multiple UI frameworks in one page.

To DataSource:
I already used the angular material table with datasource. Not MatTableDataSrouce - because I'm currently using the version 2.0.0-beta.12 - but DataSource from cdk collections with more code. It works great.
But I do not want to create a datasource like that for each table. I want to display the received data from REST API - stored in a variable array - directly in html with angular traditional template using.

Look here: The Sort Example shows a table. Not styled. 馃槃 Just style it please and all users are happy.

Solved

Ok, I have a solution to handle html table without data source in official angular material. It's easy to use. Just rebuild the dom generated table of angular material.

<div class="mat-table">
  <div class="mat-header-row">
    <div class="mat-header-cell">One</div>
    <div class="mat-header-cell">Two</div>
    <div class="mat-header-cell">Three</div>
  </div>
  <div class="mat-row">
    <div class="mat-cell">Tick</div>
    <div class="mat-cell">Trick</div>
    <div class="mat-cell">Track</div>
  </div>
</div>

It's fine for me. Meybe better as the html table.
If you want to use your traditional table, just extract the styles from angular material sources and modify it to the tag names of table. Source Path: material2-master\src\lib\table\table.scss.

For me this issue is done / closed. Maybe this example should be added to the official angular material documentation. Just demonstrate a solution without data source.

Update

Currently the solution above only works, if another table - official implementation with data source - was loaded before displaying the handcrafted table (s. above). The mat-table has to be initialized. If not the example above will not work correctly. Weird.

Workaround
Just add the table styling of mat-table to your global style. It looks like the mat-table style will not load until the componente has been used once before using "normal" divs with same classes as mat-table.
You cannot use the mat-table as tag. Because data source is required. It's a dilemma. 馃

.mat-table {
  display: block;
}

.mat-row,
.mat-header-row {
  display: flex;
  border-bottom-width: 1px;
  border-bottom-style: solid;
  align-items: center;
  min-height: 48px;
  padding: 0 24px;
}

.mat-cell,
.mat-header-cell {
  flex: 1;
  overflow: hidden;
  word-wrap: break-word;
}

Feel free to assign this to table, tr, td, th tags. But note: Maybe it does not work with thead and tbody.

Question: How to force material to load the mat-table theme without using the mat-table component?
Clean solution: The mat-table data source (dataSource attr) has to be optionally!

If your goal is just to 'not use DataSource' from a convenience standpoint you can get around this by creating a pipe.

    <mat-table [dataSource]="order?.packages | tableDataSource">

Then add TableDataSourcePipe to your module declarations.

import { Pipe, PipeTransform } from '@angular/core';
import { MatTableDataSource } from '@angular/material';

@Pipe({
    name: 'tableDataSource'
})
export class TableDataSourcePipe implements PipeTransform
{
    transform(data: any[]): any
    {
           return data ? new MatTableDataSource(data) : null;
    }
}

If there are any kind of memory leaks or unsubscription I'm missing please let me know :-)

Is there any specific section available in official material documentation which explaining the use of simple HTML table with Material Styles ?

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

3mp3ri0r picture 3mp3ri0r  路  3Comments

vitaly-t picture vitaly-t  路  3Comments

shlomiassaf picture shlomiassaf  路  3Comments

julianobrasil picture julianobrasil  路  3Comments

jelbourn picture jelbourn  路  3Comments