Skip to main content

Create table with dynamic rows and configurable row buttons with AngularJS

Hi all,
Today I want to write a short article how to create a table with dynamic configuration for rows. For example, I need to render simple table by data provided from a server and append to each row some extendable buttons, checkboxes etc. for making action on a row. For example, I will use this data:


  app.controller('MainCtrl', ['$scope', function($scope) {
  var vm = this;

  var tableData = [{
      firstName: 'Viktor',
      lastName: 'Dzundza',
      age: 25
    }, {
      firstName: 'Jony',
      lastName: 'Boyko',
      age: 24
    }, {
      firstName: 'John',
      lastName: 'Doe',
      age: 45
    },

    {
      firstName: 'Alisa',
      lastName: 'Doe',
      age: 2
    }
  ];

  var tableMeta = {
    columns: [{
      name: 'firstName',
      title: 'First Name'
    }, {
      name: 'lastName',
      title: 'Last Name'
    }, {
      name: 'age',
      title: 'Age'
    }]
  };
 }]);


After defining actual data and simple meta information for the table, I create a factory which represents Table constructor. I will use it for creating new table instance.

app.factory('Table', [function() {

  function TableConstructor(data, tableMeta) {
    this.rowActions = [];
    this.tableMeta = tableMeta;
    this.rows = [];
  }

  TableConstructor.prototype.getColumns = function() {
      return this.tableMeta.columns;
  };

  TableConstructor.prototype.getRows = function() {
      return this.rows;
  };

  TableConstructor.prototype.getRowActions = function() {
      return this.rowActions;
  };

  TableConstructor.prototype.addRowActions = function(actions) {

  };

  return TableConstructor;
}]);

As you can see the Table has a simple interface for getting rows and retrieving possible row actions.
Next step I create Row factory

app.factory('Row', function() {
    function Row(data, id) {
        this.id = id;
        this.state = {};
        this.data = data;
    }

    Row.prototype.toggleAsDeleted = function() {
        this.state.asDeleted = !this.state.asDeleted;
    };

    Row.prototype.deleteRow = function() {
        this.state.deleted = true;
    };

    Row.prototype.isDeletedMark = function() {
        return this.state.asDeleted;
    };

    Row.prototype.isDeleted = function() {
        return this.state.deleted;
    };

    return Row;
});

I add state object for Row which will keep some boolean properties as "deleted" an "asDeleted". After creating Row, I'll inject it into Table

this.rows = data.map(function(rowData, idx) {
      return new Row(rowData, idx + 1); //actually id should be provided from server
});

For adding buttons to the row, I create a plain object which describes the action. Thia object must have at least one property named 'html' which returns content for compiling. Also, this object could be extended by extra properties: 'handlers' and 'scope', The first contains methods for the element, another can extend the scope. See code below:

var deleteRow = {
      html: function() {
          return '';
      }
  };

  var markAsDeleted = {
      html: function() {
          return '';
      }
  };


Implement `addRowActions` method and simply add these actions to the table.

TableConstructor.prototype.addRowActions = function(actions) {
      actions.forEach((function(a) {
          this.rowActions.push(a)
      }).bind(this));
  };

  vm.table.addRowActions([deleteRow, markAsDeleted]);

At the end, I show html for all this stuff


   
Index
{{row.id}} {{v}}

You can see working example at Plunker: Plunker

Thanks for reading, have a nice day.

Comments

Popular posts from this blog

Some notes about transportation problem

Hello guys. After work I remembered my studying at university. My first thoughts is about solving Monge–Kantorovich transportation problem using a modification of simplex method known as Method of Potentials. Transportation theory investigates methods for optimal allocation resources among consumers and transportation them with minimum cost. For example, suppose we have some factories which provide materials and shops which consume it. (To be continued)

New Personal Website

Hello World, hello my blog again. I have good news, finally, I created my website , I do not know exactly what is the main goal for that and how it will be updated. Now I want to sync my current posts from the blogger platform and personal website, it can be easily done by using the `Blogger API` with some extra requirements which I want to have.   Especially,   - able to show/hide the post separately from blogger (1)   - use custom posts order (2)   - add some extra information besides tags (3)    For instance, technology stack, team size, etc. - add a possibility to use any 3rd party code highlighter instead of post-computed HTML from blogger (4) I think that the 4 the most required and nice feature - able to sync manually, or use cron for syncing with blogger (5)   There is some initial schema of my application   This is a pretty simple solution: two go services, one for fetching data, checking referential integr...