Aurelia and DevExtreme DataGrid

Overview

I've been working on an interesting project lately where we wanted to take advantage of some data grids that were already existing. Since the team already had a license for DevExtreme, an HTML5-based cross-platform component suite by the folks at DevExpresss, we decided to use that.

It was a relatively easy process to wrap a re-usable custom element that can be used throughout the application so I wanted to document the process. This post is specific to the DataGrid control in DevExtreme but could be used in most situations to wrap most any similar controls.

Getting Started

It's worth noting that the DevExtreme controls require a license, but if you are reading this you are probably already aware of this.

I am going to be using the standard ESNext Skeleton Navigation starter app as my basis. You can download it here or clone the repo.

First let's install the DevExtreme library -

$ jspm install github:Devexpress/bower-devextreme-web

Next lets go clear our users.html out so there is only a template tag. We'll add a new custom element to be our re-usable grid next.

Creating a re-usable DevExtreme Custom Element

Let's start out by creating a basic empty custom element to use as our re-usable DevExtreme data grid.

Setup

grid-control.js

export class GridControl {  
  control;
}

grid-control.html

<template>  
</template>  

Next we need to import the DevExpress library so it gets loaded.

import * as $ from 'jquery';  
import * as DevExtreme from 'Devexpress/bower-devextreme-web';  

We have to also import jQuery so that devpress gets tacked on to it. The reason we used Devexpress/bower-devextreme-web instead of importing from devextreme is because when we installed it with JSPM it added a map in config.js to devextreme under that name. If you wanted to switch it to import from devextreme you would just rename the map inside your config.js and package.json.

Next we need to import the styles for the grid. We can do this either in the view-model or in the view, but for this walk-thru we'll stick with requiring them in the view -

<require from='Devexpress/bower-devextreme-web/css/dx.common.css'></require>  
<require from='Devexpress/bower-devextreme-web/css/dx.light.css'></require>  

Creating the control

You create a DevExtreme data grid after selecting an element with jQuery like this $('#control').dxDataGrid({}). We can use Aurelia's ref custom attribute to grab a reference to our control's host in our element so we don't have to rely on a selector.

Add a host and ref -

<template>  
  <div ref="control"></div>
</template>  

And then in our attached method we can instantiate the grid -

export class GridControl {  
  attached() {
    $(this.control).dxDataGrid({
      dataSource: [{id: 1, name: 'Test'}]
    });
  }
}

DevExpress will automatically create a column for each of the properties on our object since we didn't specify them in the configuration options.

Making it re-usable

Right now our control displays some static data but we want to make this a control that can be re-used. To do so we can take advantage of the templating engines bindable decorator so that consumers can actually use it. We'll also add a columns property so they can limit the columns that show.

First let's add bindable items and columns properties -

import {bindable} from 'aurelia-framework';  
export class GridControl {  
  @bindable items;
  @bindable columns;
  attached() {
    $(this.control).dxDataGrid({
      dataSource: this.items,
      columns: this.columns
    });
  }
}

Now we can jump back in to our users.html and use it -

<template>  
  <require from="./grid-control"></require>
  <grid-control
    items.bind="users"
    columns.bind="['id', 'login', 'html_url']"
  ></grid-control
</template>  

This will bind to our user objects and show a few columns that are in the data.

Wrap-up

You can see an example of this in action here - https://github.com/PWKad/aurelia-devextreme-sample

If you'd like to see any additional controls or functionality added to this one let me know in the comments or on twitter @pwkad