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)

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

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

Nginx rewrite rules for hosting angular(any) static app on subroute

Hi everyone, I decided to reorganise my personal blog and use it mostly as "Notes" Today, I want to host two websites served by golang application. The simplest solution is to create system service which points to go executable app on the particular port. In a nutshell, there are two separate services which use 9990 and 9991 ports. Next step I added this simple rule to the Nginx location /admin { rewrite /admin/(.*) /$1 break; proxy_pass http://localhost:9991; proxy_redirect off; proxy_set_header Host $host; } location / { proxy_pass http://localhost:9990; } So this simple configuration just rewrites URL properly to the admin service and I do not need to add extra `admin` route prefix. The latest step is set-up base href for the static `index.html` file. We can easily do it with build option `ng build --base-href /admin/` Thank everyone for reading.