From 42f40dadb31b22918e52942692f7b81906e81074 Mon Sep 17 00:00:00 2001 From: Denperidge Date: Mon, 23 Jan 2023 18:34:35 +0100 Subject: [PATCH 1/3] Adapted README to divio --- README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index d8b9cf9..b5d9566 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ Data table for Ember based on a JSONAPI compliant backend. Have a look at [ember-paper-data-table](https://github.com/mu-semtech/emper-paper-data-table) to get a data table styled with [ember-paper](https://github.com/miguelcobain/ember-paper). -## Installation +## Getting started +### Installation If you're using Ember > v3.8 ```bash ember install ember-data-table @@ -17,7 +18,7 @@ For Ember < v3.8, use version 1.x of the addon ember install ember-data-table@1.2.2 ``` -## Getting started +### Usage Include the `DataTableRouteMixin` in the route which model you want to show in the data table. Configure the model name. ```javascript @@ -31,7 +32,7 @@ export default Ember.Route.extend(DataTableRouteMixin, { Next, include the data table in your template: -```htmlbars +```hbs {{data-table content=model fields="firstName lastName age created modified" @@ -47,9 +48,11 @@ Note: the filtering, sorting and pagination isn't done at the frontend. By inclu Have a look at [Customizing the data table](https://github.com/erikap/ember-data-table#customizing-the-data-table) to learn how you can customize the data table's header and body. -## Data table component -### Specification +## Reference +### Data table component + +#### Specification The following parameters can be passed to the data-table component: @@ -73,7 +76,7 @@ The following parameters can be passed to the data-table component: By default the data table will make each column sortable. The search text box is only shown if the `filter` parameter is bound. Pagination is only shown if the pagination metadata is set on the model (see the [Ember Data Table Serializer mixin](https://github.com/mu-semtech/ember-data-table#serializer)). -### Customizing the data table +#### Customizing the data table The way the data is shown in the table can be customized by defining a `content` block instead of a `fields` parameter. ```htmlbars @@ -98,7 +101,7 @@ The way the data is shown in the table can be customized by defining a `content` ``` Have a look at the [helper components](https://github.com/mu-semtech/ember-data-table#helper-components). -### Adding actions to the data table +#### Adding actions to the data table The user can add actions on top of the data table by providing a `menu` block. ```htmlbars {{#data-table content=model filter=filter sort=sort page=page size=size isLoading=isLoadingModel as |t|}} @@ -128,11 +131,11 @@ actions: } ``` -## Helper components +### Helper components The following components may be helpful when customizing the data table: * [Sortable header](https://github.com/mu-semtech/ember-data-table#sortable-header) -### Sortable header +#### Sortable header The `th-sortable` component makes a column in the data table sortable. It displays a table header `` element including an ascending/descending sorting icon in case the table is currently sorted by the given column. ```htmlbars @@ -149,13 +152,13 @@ The following parameters are passed to the `th-sortable` component: Note: the data table will update the `currentSorting` variable, but the user needs to handle the reloading of the data. The [Ember Data Table Route mixin](https://github.com/mu-semtech/ember-data-table#route) may be of use. -## Mixins +### Mixins The following mixins may be helpful to use with the data table: * [Serializer mixin](https://github.com/mu-semtech/ember-data-table#serializer) * [Route mixin](https://github.com/mu-semtech/ember-data-table#route) * [Default Query Params mixin](https://github.com/mu-semtech/ember-data-table#default-query-params) -### Serializer +#### Serializer Upon installation, the `DataTableSerializerMixin` is automatically included in your application serializer to add parsing of the filter, sortig and pagination meta data from the links in the [JSONAPI](http://jsonapi.org) responses. The data is stored in [Ember's model metadata](https://guides.emberjs.com/v2.9.0/models/handling-metadata/). To include the `DataTableSerializerMixin` in your application, add the mixin to your application serializer: @@ -189,7 +192,7 @@ meta: { } ``` -### Route +#### Route The route providing data for the `data-table` component often looks similar. The model hook needs to query a list of resources of a specific model from the server. This list needs to be reloaded when the sorting, page or page size changes. The `DataTableRouteMixin` provides a default implementation of this behaviour. Just include the mixin in your route and specify the model to be queried as `modelName`. ```javascript @@ -229,7 +232,7 @@ mergeQueryOptions(params) { The `DataTableRouteMixin` also sets the `isLoadingModel` flag on the controller while the route's model is being loaded. Passing this flag to the data table's `isLoading` property will show a spinner while data is loaded. -### Default Query Params +#### Default Query Params The `DefaultQueryParams` mixin provides sensible defaults for the `page` (default: 0), `size` (default: 25) and `filter` (default: '') query parameters. The mixin can be mixed in a controller that uses the `page` and `filter` query params. ```javascript From 0894278ff3238975c220696b02a0cf113d799ef5 Mon Sep 17 00:00:00 2001 From: Denperidge Date: Mon, 23 Jan 2023 18:41:28 +0100 Subject: [PATCH 2/3] Added Visualizing your Ember Data tutorial --- README.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/README.md b/README.md index b5d9566..01453ef 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,105 @@ Note: the filtering, sorting and pagination isn't done at the frontend. By inclu Have a look at [Customizing the data table](https://github.com/erikap/ember-data-table#customizing-the-data-table) to learn how you can customize the data table's header and body. +### Visualizing your Ember Data with ember-data-table +In this tutorial we show you how to easily render a data table with search, sort and pagination. The [ember-data-table addon](https://www.npmjs.com/package/ember-data-table) provides a component to visualize your Ember Data in a data table according to [Google’s  Material Design specification](https://material.io/guidelines/components/data-tables.html). Have a look at the [demo](https://ember-data-table.semte.ch) to get an idea of its capabilites. The addon assumes a [JSON:API](http://jsonapi.org/) compliant backend, like mu.semte.ch. It has support for sorting, search and pagination. However, the actual sorting, search and pagination is done by the backend. + +In this tutorial we will build the data table on [an extension of the books-service from the Getting Started guide](https://github.com/erikap/books-service/tree/ember-data-table-example). We start with a simple data table using a lot of defaults. We we will first create a new Ember app and install `ember-data-table` and its dependencies. Next, we will generate a model and configure the data table. In the next tutorials we will gradually convert this simple data table into a fully customized data table to display our books. If you already want to try on your own, an extensive overview of all the options, components and helpers of the data table can be found [in the reference](#reference). + +#### Creating your app + +Let’s get started! First, create a new Ember app and install the `ember-data-table` addon and its prerequisites. + +```bash +ember new my-ember-app +cd my-ember-app +ember install ember-cli-sass +ember install ember-cli-materialize +ember install ember-data-table +``` + +The installation process will first install the `ember-data-table` package. Next, it will overwrite `app.scss` and the `ApplicationSerializer`. The `app.scss` imports the data table styling, while the changes in the `ApplicationSerializer` will automatically parse the pagination metadata from the JSONAPI responses. You don’t have to know the technical details of the serializer to use the addon, but if you’re interested, have a look at the [DataTableSerializerMixin](https://github.com/mu-semtech/ember-data-table/blob/master/addon/mixins/serializer.js) which is included in the `ApplicationSerializer`. + +#### Generating a model and a route + +Now the addon is installed, we can include our first data table. We will first generate a model for a book and an author: + +```bash +ember generate model book title isbn publicationDate:date genre language numberOfPages:number authors:hasMany +ember generate model author name books:hasMany +``` + +Next, generate a new route `/books` to show our table. + +```bash +ember generate route books +``` + + +#### Configuring the data table +Include the [DataTableRouteMixin](https://github.com/mu-semtech/ember-data-table/blob/master/addon/mixins/route.js) in `app/routes/books.js` and set the model name: + +```js +import Ember from 'ember'; +import DataTableRouteMixin from 'ember-data-table/mixins/route'; + +export default Ember.Route.extend(DataTableRouteMixin, { + modelName: 'book' +}); +``` + +Finally, add the data-table in your template `app/templates/book.hbs`: +```hbs +

My books

+{{data-table content=model fields="title isbn"}} +``` + +#### Adding sorting and pagination + +By including the `DataTableRouteMixin` in the `/books` route, we get sorting and pagination for free (if your back-end supports it of course). Just pass the ‘page’ and ‘sort’ parameters to the data table. The `DataTableRouteMixin` will make sure the model gets refreshed when one of the parameters is updated. + +```hbs +

My books

+{{data-table content=model + fields="title isbn genre publicationDate language numberOfPages" + page=page sort=sort}} +``` + +#### Adding free-text search +Finally, we will include a free-text search field. The only thing we need to do to enable this is passing the filter parameter to the data-table and initializing it on an empty string in the controller. + +Generate a controller for the `/books` route. + +```bash +ember generate controller books +``` + +Initialize the filter query param by including the [DefaultParamsMixin](https://github.com/mu-semtech/ember-data-table/blob/master/addon/mixins/default-query-params.js). + +```js +import Ember from 'ember'; +import DefaultQueryParamsMixin from 'ember-data-table/mixins/default-query-params'; + +export default Ember.Controller.extend(DefaultQueryParamsMixin, { +}); +``` + +Update the `books.hbs` template with the filter paramater. + +```hbs +

My books

+{{data-table content=model + fields="title isbn genre publicationDate language numberOfPages" + page=page sort=sort filter=filter}} +``` + +That’s it. We now have a simple data table including sorting, pagination and free-text search with minimal effort. In the [following part of the tutorial below](#tailoring-ember-data-table-to-your-app) we will customize the formatting of the columns and add some custom action buttons in the table header. + + +### Tailoring ember-data-table to your app + + + ## Reference ### Data table component From 3915fe7c3bb7d48a1e34b6c223cf24867a942fac Mon Sep 17 00:00:00 2001 From: Denperidge Date: Mon, 23 Jan 2023 18:55:14 +0100 Subject: [PATCH 3/3] Added visualising tutorial link & tailor tutorials --- README.md | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/README.md b/README.md index 01453ef..c4958a4 100644 --- a/README.md +++ b/README.md @@ -143,10 +143,198 @@ Update the `books.hbs` template with the filter paramater. That’s it. We now have a simple data table including sorting, pagination and free-text search with minimal effort. In the [following part of the tutorial below](#tailoring-ember-data-table-to-your-app) we will customize the formatting of the columns and add some custom action buttons in the table header. +*This tutorial has been adapted from Erika Pauwels' mu.semte.ch article. You can view it [here](https://mu.semte.ch/2017/03/02/visualizing-your-ember-data-with-ember-data-table/).* + ### Tailoring ember-data-table to your app +This tutorial is a follow-up [on how to visualize your Ember Data with the ember-data-table](#visualizing-your-ember-data-with-ember-data-table). Have a look at the first tutorial if you want to get started with the ember-data-table addon. This article explains how to customize the data table by defining custom table headers and column formatting. We will continue on [the books example](https://github.com/erikap/ember-data-table-demo) of the previous post. A live demo is available on [https://ember-data-table.semte.ch](https://ember-data-table.semte.ch). + +![](http://mu.semte.ch/wp-content/uploads/2017/03/ember-data-table-screenshot-1024x332.png) + + + +In the previous tutorial we created a simple data table to list the books in our library. We used the default header and column rendering resulting in table headers  like ‘publicationDate’ and ‘nbOfPages’ and non-formatted data in the columns such as ‘Wed Jan 01 1913 01:00:00 GMT+0100 (CET)’. In this tutorial we will first customize the column header. Next, we will format the data and enrich it by showing the author(s) of the books. + +#### Customizing the table headers + +To customize the data table we will update the template containing the data table component. First, remove the `fields` parameter. Next, convert the component to the [block form](https://guides.emberjs.com/v2.12.0/components/wrapping-content-in-a-component/) so that we can provide custom HTML content. + +```hbs +{{#data-table content=model page=page sort=sort filter=filter}} + +{{/data-table}} +``` + +We can now define our custom headers using [contextual components](https://guides.emberjs.com/v2.12.0/components/wrapping-content-in-a-component/#toc_sharing-component-data-with-its-wrapped-content) wrapping inner components within the context of outer components. Add the table context as variable ‘t’ and define a ‘content’ block component. Next to the content block, the data table can also have a menu block containing custom action buttons. We will elaborate on this [below](#adding-actions-to-the-data-table). + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.content}} + + {{/t.content}} +{{/data-table}} +``` + +The content component wraps two components itself: a header component and a body component. The names are self-explanatory. The header component contains the column headers. The body component contains the actual data – the body – of the data table. + +Let’s start with the header. Add the content as a context variable on the content component and wrap the header component in it. + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.content as |c|}} + {{#c.header}} + + {{/c.header}} + {{/t.content}} +{{/data-table}} +``` + +Define your custom HTML content to display the table headers in the data table. In its simplest form the headers could just be `` table headers containing a custom label: + +```hbs +{{#c.header}} + Title + Author + ISBN + Genre + Published + Language + # pages +{{/c.header}} +``` + +If you want the column to be sortable, you can use the `th-sortable` component provided by the addon. This component will automatically display the table header with the appropriate sort icons depending on the current sorting. Just pass the field (model attribute), label and current sorting to the component. + +```hbs +{{th-sortable field='title' currentSorting=sort label='Title'}} +``` + +The header may consist of a mix of sortable and non-sortable table headers, for example resulting in: + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.content as |c|}} + {{#c.header}} + {{th-sortable field='title' currentSorting=sort label='Title'}} + Author + {{th-sortable field='isbn' currentSorting=sort label='ISBN'}} + {{th-sortable field='genre' currentSorting=sort label='Genre'}} + {{th-sortable field='publicationDate' currentSorting=sort label='Published'}} + {{th-sortable field='language' currentSorting=sort label='Language'}} + # pages + {{/c.header}} + {{/t.content}} +{{/data-table}} +``` + +#### Formatting the table columns +Similar to the header component, we can include a body component in the table’s content block.  The row context is passed as a variable ‘row’. + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.content as |c|}} + {{#c.header}} + ... + {{/c.header}} + {{#c.body as |row|}} + + {{/c.body}} + {{/t.content}} +{{/data-table}} +``` + +The ‘row’ variable contains the Ember Data record to be displayed. Displaying an attribute or relationship works as you would expect: +```hbs +{{row.title}} +{{row.authors}} +``` + +The custom HTML content defined in the body component are wrapped in a `` tag. We just need to define the `` tags, one per column. The content of the `` tags may include any valid HTML, including other components like for example ‘[moment-format](https://github.com/stefanpenner/ember-moment)‘ to format a date or the [join composable helper](https://github.com/DockYard/ember-composable-helpers#join) to display an array of values. +```hbs +{{#c.body as |row|}} + {{row.title}} + {{join ", " (map-by "name" row.authors)}} + {{row.isbn}} + {{row.genre}} + {{moment-format row.publicationDate 'MM/DD/YYYY'}} + {{row.language}} + {{row.numberOfPages}} +{{/c.body}} +``` + +#### Adding custom actions on top of the data table +![](http://mu.semte.ch/wp-content/uploads/2017/05/ember-data-table-custom-actions.png) + +The addition of actions on top of the data table works similar to the customisation of the data table contents using [contextual components](https://guides.emberjs.com/v2.12.0/components/wrapping-content-in-a-component/#toc_sharing-component-data-with-its-wrapped-content). We will start from a data table component in block form containing a custom ‘content’ block: +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.content}} + + {{/t.content}} +{{/data-table}} +``` + +Add a ‘menu’ block next to the ‘content block’ inside the data table component. The menu block on its turn consists of two blocks:  a ‘general’ and a ‘selected’ block. The ‘general’ block is shown by default. The ‘selected’ block is shown when one or more rows in the data table are selected. It typically contains actions that will be executed only on the selected items. + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.menu as |menu|}} + {{#menu.general}} + + {{/menu.general}} + {{#menu.selected as |selection datatable|}} +   + {{/menu.selected}} + {{/t.menu}} + {{#t.content}} + + {{/t.content}} +{{/data-table}} +``` +Next, add the menu items as anchor elements to the ‘general’ and ‘selected’ blocks. Each anchor element contains an [Ember action helper](https://guides.emberjs.com/v2.13.0/templates/actions/) that will execute the appropriate action. The actions in the ‘selected’ menu block receive the selected rows and the data table as parameters. + +```hbs +{{#data-table content=model page=page sort=sort filter=filter as |t|}} + {{#t.menu as |menu|}} + {{#menu.general}} + Export + Print + {{/menu.general}} + {{#menu.selected as |selection datatable|}} + Delete + {{/menu.selected}} + {{/t.menu}} + {{#t.content}} + + {{/t.content}} +{{/data-table}} +``` +If you would render the data table now, you will see the ‘general’ menu on top of the data table. As soon as you start selecting rows, the ‘selected’ menu will be shown. This menu automatically contains a ‘Cancel’ button to clear the selection without executing an action. + +Finally, we need to implement the menu actions in the controller. In the example above we defined three actions: ‘export’  and ‘print’ in the general menu and ‘delete’ in the selected menu. Since the ‘delete’ action receives the selected rows and the data table as parameters, the action method signatures in the controller will look as follows: +```js +actions: { + export() { + // implement export action here + }, + print() { + // implement print action here + }, + delete(selection, datatable) { + // implement delete action here + // e.g. selection.forEach(function(item) { item.destroyRecord(); }); + + // clear the selection at the end + datatable.clearSelection(); + } +} +``` + +You can now implement the actions in any way you want. Just note that in the actions of the ‘selected’ menu you need to clear the selection by yourself in the end by calling `datatable.clearSelection()` as shown in the example above. +This concludes this tutorial. Have look at the [reference](#reference) to get an extensive overview of all the options, components and helpers of the data table. We hope you’re convinced on the easy-of-use of this addon by following the tutorials. Feel free to make a [contribution](https://github.com/mu-semtech/ember-data-table) or log an [issue](https://github.com/mu-semtech/ember-data-table) if you have a problem using the ember-data-table. +*This tutorial has been adapted from Erika Pauwels' mu.semte.ch articles. You can view them [here](https://mu.semte.ch/2017/03/30/tailoring-ember-data-table-to-your-app/) and [here](https://mu.semte.ch/2017/05/18/tailoring-ember-data-table-to-your-app-part-2/).* ## Reference ### Data table component