Angular Directive – Table

I have to develop an application where most of the data is displayed in a table. Putting data in a table is pretty straight forward, but when you have multiple pages then you would like to have a table control which can be driven by data and added to pages with one line of HTML. Something like this:

<rmt-table data="data" columns="columns" on-row-clicked="RowClicked(Id)"></rmt-table/>

AngularDirectiveTable

To understand this post, get the full working code for the table directive from this plnkr. This directive takes two arrays of objects, name of columns, and the real data. This table directive has encapsulated paging and sorting functionality. Now dynamically you can supply different data and the page will show you different tables.

Code is straight forward, but I learn few things on the way. My first issue, was to get click on the table back to main controller with the row Id value. Unfortunately, this does not work as straight forward as you may think.

In main controller I have defined a function as follows:

  $scope.RowClicked = function(id) {
    alert(id);
  };

and as you can see in html, this function is defined on on-row-clicked.

<rmt-table data="data" columns="columns" on-row-clicked="RowClicked(Id)"></rmt-table/>

There are many angular courses and documentation where people are advised not to pass the parameter in the function, unfortunately this advice does not hold good anymore. Not only you have to pass the parameter in the function but the parameter name should be exact same as defined in your function definition.

Here is the function in directive:


angular.module('app').directive('rmtTable', function() {
  return {
    restrict: 'E',
    templateUrl: 'myTable.html',
    scope: {
      originalData: '=data',
      columns: '=columns',
      notifyParent: '&onRowClicked',
    },
 snip ....snip 

      $scope.rowClicked = function(row) {
        $scope.notifyParent({
          Id: row.Id
        });

Line 8, wire the external function to the directive. Line 13, calls the external function with the row id value. Here is the rub, you would think you could have called the function as follows:

      $scope.rowClicked = function(row) {
        $scope.notifyParent(row.Id);

But this will not work, this straight and simple way of calling function will not work, no matter what god you believe in :) You may think, that you can do some more javascript jugglery like

      $scope.rowClicked = function(row) {
        $scope.notifyParent()(row.Id);

but still this will not work. It has to be a object. And make sure your object, key must match the parameter you are passing in the function, in my case it is “Id”. Thanks to Dan Wahlin who taught me this trick.

My second issue was to debug the scripts in plnkr. By default, it shows the output in the same window, and if you press F12 you are presented by hundreds of minified JS. Fortunately, in the display IFrame you will find a blue color button which will ‘launch the preview window in a separate window’. In this separate window, it is just you and your code. Much easier to debug the issues.

Go ahead and play with this plnkr. Remember, this is a prototype, there are many things can be improved (for example, max row can also be supplied to directive), this is just to get you started on table directive.

Happy coding!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s