Data Tables

Data tables display raw data sets. They usually appear in desktop enterprise products.

By default, the data tables will be responsive by allowing the user to scroll left/right when there is too much content to be viewed at once.

In react-md, data tables come in two types: plain and selectable where selectable is the default. A plain data table is not part of the material design specs and attempts to just add the base styles for a table and allow any sized content to be displayed. A selectable data table will inject checkboxes as the first column and allow each row to be selected.

If you are working with large data sets and have heavy table edit abilities, it is recommended to use a virtualization library such as react-virtualized instead of my tables. The html <table> is already pretty slow if you don't use fixed layouts and know the exact size of each cell beforehand. When all the event listeners and styles have been applied for the data table, you might start noticing performance issues around a 20x20 table. If a virtualization library isn't your thing, you can always try to paginate the results with the TablePagination component to limit the number of rendered rows/columns at a time

When a table has the plain prop enabled on tables, it will just set the min-height of each cell to the $md-data-table-plain-column-height, allow line wrapping, and centers the content vertically in the cell.

Lorem 1Lorem 2
voluptate nostrud consequat quis nonculpa reprehenderit ad eu enim
mollit culpa sint ipsum cupidatatquis minim et cillum occaecat
eiusmod eu aliquip irure proidentnisi sunt irure laboris id
sint occaecat non incididunt pariaturveniam duis pariatur mollit consequat
pariatur quis exercitation sint quisdolor excepteur dolore minim adipisicing
cillum adipisicing id ex nisicupidatat reprehenderit commodo dolore mollit
nostrud minim ut dolore irureexercitation ex non magna ullamco
officia commodo qui occaecat veniamsit ea incididunt reprehenderit aliquip
et tempor et culpa excepteurofficia occaecat eu labore in
anim aliqua Lorem enim elitcommodo id mollit non et

This example will showcase a selectable table. Checkboxes will be injected as the first cell into each row. To help with accessibility, the baseId prop is now required on the table so that each checkbox is updated with a unique id and a common name. Non-plain data tables have a height set to $md-data-table-column-height and prevent text wrapping.

You can also update the selectable table to be indeterminate which basically updates the "select all" checkbox to be in an "indeterminate" state when not all the rows have been checked.

Lorem 1Lorem 2
adipisicing non est laborum elitfugiat voluptate irure ut deserunt
velit labore incididunt anim elitet tempor quis labore incididunt
velit in tempor laborum ullamcout ex sit ad incididunt
veniam laboris laborum proident noncillum minim ex veniam adipisicing
ad laboris ullamco id aliquipquis id officia fugiat deserunt
non anim adipisicing Lorem exquis nisi do consectetur velit
ullamco ex magna sit consequatsint qui dolore anim excepteur
irure tempor fugiat duis animid ad cupidatat nisi nisi
ipsum pariatur deserunt cillum adipisicingad laboris sint ullamco officia
nisi laboris excepteur ad proidentminim nisi ea proident fugiat

When you have large datasets, you can improve some of your app's performance by paginating your results and limiting the number of rows displayed at a time. This example shows how you can work with the TablePagination component and its API to easily accomplish this.

This component will be displayed at as a <tfoot> and attached to the bottom of the table. It will allow the user to paginate forwards or backwards by a preset number of rows. The default is to start at 10 rows per page and allows for 10, 20, 30, 40, 50, and 100 by default (both of these can be configured).

In addition, this example introduces a new styling prop: selectable. By default non-plain DataTables are selectable which means the checkbox will be automatically injected into the first cell of each row. Sometimes you want the styles of a non-plain DataTable but without the checkboxes. By disabling the selectable prop on each row, the non-plain styles will be applied and checkboxes will not be shown.

Column 1Column 2Column 3Column 4Column 5Column 6
non pariatur aute ut eucupidatat fugiat minim pariatur occaecatsit consequat id elit veniamanim non ex ex laborumipsum ullamco sunt dolore minimveniam consequat officia elit dolor
reprehenderit velit qui elit eliteiusmod deserunt sint velit cillumdolore laborum in sint etipsum et ex officia autenon officia mollit fugiat veniamdolore aliquip nulla fugiat minim
excepteur amet aute fugiat exnostrud cillum nostrud sunt veniamqui aliqua duis ullamco consecteturexercitation officia velit deserunt animlaborum incididunt do irure aliquippariatur ea est fugiat occaecat
est enim irure minim doloreirure et nostrud proident cillumaute anim deserunt sit tempornostrud mollit id consequat exercitationreprehenderit excepteur ut ut aliquaeiusmod et pariatur deserunt labore
culpa labore dolor qui temporconsectetur esse fugiat eu euet incididunt officia dolore duisproident et nostrud occaecat sitexercitation esse et enim tempordolor esse aute laborum occaecat
nulla occaecat sunt ea esseminim magna nisi anim nisiea ex id ea deseruntaliquip aute pariatur officia elitirure nulla eu incididunt reprehenderitea fugiat voluptate deserunt in
mollit ut nulla minim reprehenderitmollit duis aute minim doamet velit laboris amet ipsumduis ad aliquip officia nullaquis nostrud consequat laborum adex eiusmod ad culpa nulla
pariatur enim sint laboris cupidatatvelit excepteur ipsum eu nostrudproident tempor et eiusmod quisvelit incididunt adipisicing in pariaturamet laborum in fugiat laborumnulla laborum Lorem anim officia
nostrud sunt do mollit dolorealiquip nisi commodo adipisicing voluptateadipisicing ad non nisi incididuntsit occaecat sunt exercitation fugiatlabore cupidatat eu reprehenderit occaecatenim labore id anim culpa
exercitation deserunt sunt eu elitullamco enim cillum laborum ipsumnostrud ad do do estculpa Lorem esse veniam commodoest elit ullamco est suntdolor ex exercitation qui ullamco
Rows per page1-10 of 350

DataTables can become sortable by applying the sorted prop to one-to-many of the TableColumn that appear in the TableHeader. If the sorted prop is a boolean, it will inject a sort icon before the content in the column. When the sorted prop is true, it will assume that the content is sorted "ascending" while false will assume "descending". This will also update the column with the corresponding aria-sort value. You can then just add a simple onClick handler to your TableColumn to change the sort direction.

arrow_upwardTitle
Year
Commando1985
Conan the Barbarian1982
Conan the Destroyer1984
Eraser1996
Jingle All The Way1986
Raw Deal1986
Red Sonja1985
Terminator 2: Judgement Day1991
Terminator 3: Rise of the Machines2003
Terminator Genisys2015
The 6th Day2000
The Last Stand2013
The Running Man1987
The Terminator1984
Total Recal1990

This example will show how you can create a table with editable content by using the additional table components: EditDialogColumn and SelectFieldColumn. Both of these components will attempt to stay within the viewport and automatically close if they are scrolled out of view while open. In addition, this example showcases another styling prop: grow.

When you have many columns in your DataTable and it is not a plain table, it is recommended to apply grow to one of your column headers. Due to how the html <table> automatically attempts to size each cell, you can end up the "Select All Checkbox" being offset from all the other cells. Enabling grow on one cell will allow it to fill all missing space in the table and only allow cells to be sized based on content and padding.

These two components utilize the baseId to automatically inject unique ids into each field. Each SelectField will gain an id of ${baseId}-${rowIndex}-${columnIndex}-select-field. Each EditDialogColumn will generate an id of ${baseId}-${rowIndex}-${columnIndex}-edit-dialog for the dialog and ${baseId}-${rowIndex}-${columnIndex}-edit-dialog-field for the field in the dialog. If these do not suit your needs, you can still override them manually as props.

The SelectFieldColumn is just a simple wrapper of a TableColumn and a SelectField but it does some work behind the scenes to work with the Layover component. All of the props are basically the same as the SelectField and can be used the same way.

For more information about the EditDialogColumn types, please see the next example.

NameTypeCaloriesFatCarbsProteinSodiumCalciumIron
159624487141
2379374.312981
2621637633767
3053.7674.341338
35616493.9327716
37509405000
3920.29803802
4083.2876.5562045
5225514.9326222
16665754126

Edit dialogs have some built in interactions for handling saves and keyboard support. By default, the value in the dialog is saved automatically whenever the dialog is closed with any interaction except for pressing the escape key or hitting the cancel button in large edit dialogs. So this means that if the user clicks somewhere else on the page, presses enter, or scrolls the page, the value will be saved. The dialog can be updated so that the cancel action happens if a user presses tab, clicks somewhere else on the page, or scrolls the page instead.

Edit Dialogs are a mainly desktop interface. Due to the weirdness in how different mobile devices handle keyboards, the dialog versions of the EditDialogColumn do not work on mobile devices. Use the inline mode stated below, or go for a better interface on mobile with a row card edit view.

The default EditDialog will just be a small dialog that displays a text field with minimal padding.

A large EditDialog will require a title prop to display above the text field and then create a footer including a cancel and ok button.

If you want to keep the UI simple, you can create inline edit dialogs which just display a text field in the cell instead of creating a dialog (so the EditDialog is sort of a bad name by this point). By default, a pencil icon will be added to the right side of the text field to indicate that it can be typed into (this can also be removed via props).

When the user tab-focuses the edit dialog column, the dialog will automatically be opened and the text field will be focused for text edits. If the user presses tab in an inline or non-large dialog, the dialog will be closed and the save interaction will be triggered (unless it is switched to do cancel on outside interactions described above). In any case, if the user presses the escape key, the dialog will be closed and the cancel action will be called. Since it is sometimes better to not automatically open the dialog immediately after tab-focus, the auto-open feature can be disabled by disabling visibleOnFocus so the user is required to press space or enter to open the edit dialog.

When the dialog is set to large, the tab interactions will be "trapped" within the dialog until the user selects the ok or cancel button (or presses enter on the text field). The dialog can still be closed by pressing the escape key to cancel any cell edits.

When the dialog is set to inline, tabbing will always save the data and pressing escape will call the cancel action.

The EditDialogColumn uses the TextField behind the scenes and correctly applies all the props to the text field. This means you can integrate help text, error messages, counters, multiline fields, etc for the this component as well.

Some Data
edit

If you want to use menus within the DataTable, it is recommended to use the provided helper components to help out. Since the DataTable is responsive by default and allows for scroll bars, there can be some weird behavior without them since they use the Layover. The helper components automatically attempt to position themselves related to the DataTable as well as injecting unique ids like the other form inputs for the table. Check out the example below to see how to use the MenuButtonColumn and DropdownMenuColumn components.

TitleAuthor
The FlightScott Masterson
Room of PlatesAli Conners
The Sleek BootSandra Adams
Night HuntingJanet Perkins
Rain and CoffeePeter Calsson
Ocean ViewTrevor Hansen
Lovers on the RoofBritta Holt
Lessons from DelhiMary Johnson
MountaineersAbbey Christensen
Plains in the NightDavid Park
Dear OliviaSlyvia Sørensen
Driving LessonsHalimer Carver

There is some very limited support for fixed table headers/footers built into react-md. However, it is advisable to use a third party library such as react-virtualized when dealing with heavy interaction-based tables or using fixed headers. Part of the problem with the implementation that is built into this library is that the vertical scrollbar does not appear until you have scrolled horizontally to the end which is confusing for users on OSes that display scroll bars.

If this still seems fine, there is a mixin built in that will help you create fixed tables at a specific size or to span the entire page. See react-md-make-fixed-table for some more information there.

This example will show how you can use your fixed table headers/footers along with the TablePagination component to dynamically retrieve data from an API and display it in your table.

One of the use cases of tables is to have dynamic content that can be added or removed. There is a component built to help with this named the TableCardHeader which works well with the DataTable's selectable rows. The TableCardHeader was built to display an optional title and any children in a CardTitle component until it is toggled to a "contextual" view where another title and any additional actions can be displayed. A great example of this is when rows in the DataTable are selected and you would like to allow the user to delete them.

This example will show how you can integrate DataTables into Cards (with built in styling changes) and allow the user to add/remove rows from the table.

NOTE: One of the problems with the built-in checkbox support is that it uses React's context to push the changes down to each component. However if you ever use shouldComponentUpdate or a PureComponent, these changes won't be persisted to the child components since they block context updates. It is recommended to take full control instead.

Nutrition

Dessert (100g serving)TypeCaloriesFat (g)Carbs (g)Protein (g)Sodium (mg)Calcium (%)Iron (%)
Frozen yogurtIce cream159624487141
Ice cream sandwhichIce cream2379374.312981
EclairPastry2621637633767
CupcakePastry3053.7674.341338
GingerbreadPastry35616493.9327716
Jelly beanOther37509405000
LollipopOther3920.29803802
HoneycombOther4083.2876.5562045
DonutPastry5225514.9326222
KitKatOther16665754126