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

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...

Університет нафти і газу

Всім привіт. Я поступив в національний технічний університет Нафти і Газу. Поступив на 2 курс, хоча мав б бути на третьому. Я дякую, за те, що поступив на другий курс на держ. форму. Але не все так просто. Потрібно перезаразувати години предметів, які вчили в універі на 1 і частково на 2 курсі, для того щоб без проблем перейти на 3 курс. На рахунок програмування, майже нічого нового немає. Хіба що будем вчити Java на на предметі "технологія розробки ПЗ". Ось і все, що я хотів написати. Всім удачі!