diff --git a/src/lib/table/table.md b/src/lib/table/table.md index 8fbb3601ee11..1f14951d4ed7 100644 --- a/src/lib/table/table.md +++ b/src/lib/table/table.md @@ -1,50 +1,185 @@ -The `mat-table` provides a Material Design styled data-table that can be used to display rows of -data. +The `mat-table` provides a Material Design styled data-table that can be used to display rows of +data. + +The table's template is made up of column definitions where each definition provides the content for +that column's header and row cells. It also includes a `` and `` where each +takes an ordered list of the columns they should render. + +Passing data to the table must be done through a `DataSource`, which connects to the table by +providing an Observable that emits an array of data. The table picks up this data array and writes +a `mat-row` for each data object in the array. It is the responsibility of the `DataSource` to send +exactly what data should be rendered by the table, so any data manipulation features such as +sorting or filtering should be implemented here. This table builds on the foundation of the CDK data-table and uses a similar interface for its data source input and template, except that its element and attribute selectors will be prefixed -with `mat-` instead of `cdk-`. - -For more information on the interface and how it works, see the +with `mat-` instead of `cdk-`. For detailed information on the interface and how it works, see the [guide covering the CDK data-table](https://material.angular.io/guide/cdk-table). +### Getting Started + -### Features +Start by writing your table's column definitions. Each column definition should be given a unique +name and contain the content definitions for its header and row cells. + +Here's a simple column definition with the name `'userName'`. The header cell contains the text +"Name" and each row cell will render the `name` property of each row's data. + +```html + + Name + {{user.name}} + +``` + +After you define all your columns, you'll need to provide the header and data row templates that +will be rendered out by the table. Each template should be given an ordered list of columns that +will let the table know what columns each row should render. + +```html + + +``` + +Once your template is set up, the final step is to provide data to the table. This must be done +through a `DataSource`, which uses an Observable stream that emits an array of data that the table +should render. + +To get started, you can use the pre-built `MatTableDataSource` to handle the stream for you. +Just create a new instance and set its `data` property to whatever data you want the table to +render. -The `` itself only deals with the rendering of a table structure (rows and cells). -Additional features can be built on top of the table by adding behavior inside cell templates -(e.g., sort headers) or next to the table (e.g. a paginator). Interactions that affect the -rendered data (such as sorting and pagination) should be propagated through the table's data source. +```ts +this.myDataSource = new MatTableDataSource(); +this.myDataSource.data = dataToRender; +``` +```html + + ... + +``` + +### Features #### Pagination -The `` adds a pagination UI that can be used in conjunction with the ``. The -paginator emits events that can be used to trigger an update via the table's data source. +To paginate the table's data, add a `` after the `` and provide the +`MatPaginator` to the `MatTableDataSource`. The data source will automatically listen for page +changes made by the user and send the right paged data to the table. + +For more information on using and configuring the ``, check out the +[mat-paginator docs](https://material.angular.io/components/paginator/overview). #### Sorting -Use the `matSort` directive and `` adds a sorting UI the table's column headers. The -sort headers emit events that can be used to trigger an update via the table's data source. +To add sorting behavior to the table, add the `matSort` directive to the `` and add +`mat-sort-header` to each column header cell that should trigger sorting. Provide the `MatSort` +directive to the `MatTableDataSource` and it will automatically listen for sorting changes and +change the order of data rendered by the table. + +By default, the `MatTableDataSource` sorts with the assumption that the sorted column's name +matches the data property name that the column displays. For example, the following column +definition is named `position`, which matches the name of the property displayed in the row cell. + +```html + + + Name + {{element.position}} + +``` + +If the data properties do not match the column names, or if a more complex data property accessor +is required, then a custom `sortingDataAccessor` function can be set to override the default data +accessor on the `MatTableDataSource`. +For more information on using and configuring the sorting behavior, check out the +[matSort docs](https://material.angular.io/components/sort/overview). + #### Filtering -While Angular Material does not offer a specific component for filtering tabular data, the table's -data source can be updated based on any custom filter UI. Any filtering pattern need only trigger -an update via the table's data source. +To remove filtered rows from the table's data, simply provide the filter string to the +`MatTableDataSource`. The data source will reduce each row data to a serialized form and will +filter out the row if it does not contain the filter string. By default, the row data reducing +function will concatenate all the object values and convert them to lowercase. - +For example, the data object `{id: 123, name: 'Mr. Smith', favoriteColor: 'blue'}` will be +reduced to `123mr. smithblue`. If your filter string was `blue` then it would be considered a match +because it is contained in the reduced string, and the row would be displayed in the table. -### Simple Table +To override the default filtering behavior, a custom `filterPredicate` function can be set +which takes a data object and filter string and returns true if the data object is considered a +match. + + -In the near future, we will provide a simplified version of the data-table with an easy-to-use -interface, material styling, array input, and more out-of-the-box features (sorting, pagination, -and selection). +#### Selection + +To add row selection to the table, first set up a `SelectionModel` from `@angular/cdk/collections` +that will maintain the selection state. + +```js +const initialSelection = []; +const allowMultiSelect = true; +this.selection = new SelectionModel(allowMultiSelect, initialSelection); +``` + +Add a column definition for displaying the row checkboxes, including a master toggle checkbox for +the header. The column name should be added to the list of displayed columns provided to the +`` and ``. + +```html + + + + + + + + + + +``` + +Implement the behavior in your component's logic to handle the header's master toggle and checking +if all rows are selected. + +```js +/** Whether the number of selected elements matches the total number of rows. */ +isAllSelected() { + const numSelected = this.selection.selected.length; + const numRows = this.dataSource.data.length; + return numSelected == numRows; +} + +/** Selects all rows if they are not all selected; otherwise clear selection. */ +masterToggle() { + this.isAllSelected() ? + this.selection.clear() : + this.dataSource.data.forEach(row => this.selection.select(row)); +} +``` + +Finally, adjust the styling for the select column so that its overflow is not hidden. This allows +the ripple effect to extend beyond the cell. + +```css +.mat-column-select { + overflow: initial; +} +``` + + ### Accessibility Tables without text or labels should be given a meaningful label via `aria-label` or