Skip to content
Sreenath Somarajapuram edited this page Dec 21, 2015 · 1 revision

Installation

npm install --save em-table

Basic usage

In the controller

  • import Column Definition import ColumnDefinition from 'em-table/utils/column-definition';
  • Create columns & rows.
    • Columns must be an Ember.Array of column definitions
    • Rows must be an Ember.Array of Ember.Objects (That includes ember-data records).
columns: ColumnDefinition.make([
  {
    id: 'id',
    headerTitle: 'Id',
    contentPath: 'id'
  }, {
    id: 'name',
    headerTitle: 'Name',
    contentPath: 'name'
  }
]),
rows: Ember.A([
  Ember.Object.create({
    id: 1,
    name: "Gopi"
  }), Ember.Object.create({
    id: 2,
    name: "Jaya"
  })
])
  • Path can be a dot separated string to the value.
  • ColumnDefinition.make creates an array of column definitions from an array of Javascript objects.

In the template

Basic:

{{em-table columns=columns rows=rows}}

And that would create a table of the format

Id Name
1 Gopi
2 Jaya

Without Search

{{em-table columns=columns rows=rows enableSearch=false}}

Without Sort

{{em-table columns=columns rows=rows enableSort=false}}

Without Pagination

{{em-table columns=columns rows=rows enablePagination=false}}

Setting number of rows displayed in a page

{{em-table columns=columns rows=rows rowCount=5}}

Bounded values in cell

By default cell values are not bounded. But we can do that by adding observePath: true to the respective column definition. The cell will observe change at the contentPath, and update when required.

{
  id: 'status',
  headerTitle: 'Status',
  contentPath: 'status',
  observePath: true
}

Cell as component

Each column can be defined to use a specific component as the cell. It's done via the cellComponentName property.

  • em-table comes with some predefined components, also you can create your own.

While creating a component just keep in mind that the value at the contentPath would be passed into the component through a property named content.

{
  id: 'status',
  headerTitle: 'Status',
  contentPath: 'status',
  cellComponentName: 'em-table-status',
  observePath: true
}

Complex cell content

What to do when you have a cell component that expects multiple values or when you need to do some processing on the value at the path. getCellContent in the column definition comes for rescue.

  • Using getCellContent you can set a callback that would be called when ever the cell need to be updated.
  • The value returned will be available as content property in the component.

getCellContent gets called for each displayed row, with row object as the argument.

For instance assume we are using the em-table-linked-cell component to display a links to profile. Following is how it would look.

{
  id: 'profile',
  headerTitle: 'Profile',
  cellComponentName: 'em-table-linked-cell',
  getCellContent: function (row) {
    return {
      routeName: 'profile',
      id: row.get('id'),
      displayText: row.get('name') + "'s profile"
    };
  }
}
  • routeName - is the ember rout to which we would be redirecting
  • id - the dynamic segment in the link
  • displayText - the link content

Sorting and searching while using getCellContent

When the data displayed is computed, search and sort values would also have to be computed. That's when getSearchValue & getSortValue comes handy.

Like getCellContent, these callbacks also would be called with row as argument.

  • Value returned would be respectively used on searching and sorting.
  • getSearchValue expects you to return a string value
  • getSortValue expects a value that works with Javascript's > & < operators.
  • All these processing (Searching/Sorting) happens inside the Data Processor class
{
  id: 'profile',
  headerTitle: 'Profile',
  cellComponentName: 'em-table-linked-cell',
  getCellContent: function (row) {
    return {
      routeName: 'profile',
      id: row.get('id'),
      displayText: row.get('name') + "'s profile"
    };
  },
  getSearchValue: function (row) {
    return row.get('name') + "'s profile";
  },
  getSortValue: function (row) {
    return row.get('name');
  }
}

Cell level loading

getCellContent serves more functionalities. You can return a promise in the getCellContent callback, and the cell will wait till the promise is fulfilled.

  • While waiting it displays a waiting message

Value returned on fulfillment will be available as the content in the component.

  • getSearchValue & getSortValue doesn't supports promises as of now.
{
  id: 'city',
  headerTitle: 'City',
  getCellContent: function (row) {
    return thisController.store.find('address', row.get('id')).then(function (address) {
      return address.get('city');
    });
  }
}

Before sort callback

  • beforeSort callback on the column definition will be called before sorting a column.
  • Column definition will be passed as the argument.
  • Return a true value to continue, and false value to abort sorting.
{
  id: 'age',
  headerTitle: 'Age',
  contentPath: 'age',
  beforeSort: function () {
    if(thisController.isReady) {
      return true;
    }
    alert("Controller is not ready, cannot sort this field!");
  }
}

Search, Sort & Pagination properties

Following properties in the table definition can be used to control the respective functionalities. You can observe the same values to know change in values. Check Table Definition to know what they mean.

  • Search - searchText
  • Sort - sortColumnId, sortOrder
  • Pagination - pageNum, rowCount, rowCountOptions

In the controller create a TableDefinition instance with these properties, and use that instance in the template. Check the demo app to see it in action. Setting Values In Controller

// Your custom instance of table definition
tableDefinition: TableDefinition.create(),
...
// Search text alias, any change in controller's searchText would affect the table's searchText, and vice-versa.
searchText: Ember.computed.alias('tableDefinition.searchText'),

In the template

{{em-table definition=tableDefinition columns=columns rows=rows}}

Customizing Header & Footer

headerComponentNames & footerComponentNames array properties are available over em-table to set the header and footer components. By default header uses the in-build em-table-search-ui & em-table-pagination-ui components. Footer uses em-table-pagination-ui component. You can create your own components and replace headerComponentNames & footerComponentNames properties.

All table components will be passed two parameters, tableDefinition & dataProcessor. Components can observe property change in them and act accordingly.