The longest project in which I was ever involved in took a year. Thanks to this, I learned a lot. I remember how much of a beginner I was when I joined the team compared to now. For example, I couldn’t imagine how could I make a nice and clear table from lot of data, because I only knew the ng-repeat method. I didn’t know that there are user-friendly tools that I can modify according to my own needs.
Then I got this project, where all pages had at least one table. First, I searched nice ng-repeat words in the HTML files with all my strength, but it was in vain. They weren’t there, instead there was everything else that I haven’t known. In this project, grid components were used everywhere, which was a bit complex at first, but later became easy to use.
The project has already been finished, but maybe we will need a similar component later in another project. Because of that, I researched some components from which I can choose a good one. An important factor was for it to work in Angular 2. I can modify it easily and it can do tasks like filtering and sorting.
In this post I’m going to compare three grid components. Let’s look at what Handsontable, ag-Grid and Flexgrid can do.
I think that this component is similar to Excel. There are numbered lines and we can copy the cells in vertical and horizontal directions, besides the cells have borders by default.
The appearance of this component is a bit different. The cells aren’t bordered by default, but every row has different background, the numbered column is missing from the left side, and the head of the table is different. We can’t copy the cells here like at Handsontable.
The Flexgrid is similar to Handsontable, it doesn’t have a numbered column and we can’t copy the cells when we click on them.
Nothing is free. I think it’s true for the Flexgrid. Fortunatelly it’s half true for Handsontable and ag-Grid. In the latter two cases we can use lot of the functionality without paying, but some functions are still paid. Some extras go together, for example support, maintenance, etc. are paid. The free version of ag-Grid and Handsontable are licensed by MIT, so it is available to anyone, but with Handsontable it was a sore point for me that some important functions (filtering) are in the PRO version.
There is a so-called EditorManager class which has more tasks: selecting the editor for the active cell, displaying the editor, then closing it. We can invoke the editor inseveral ways. The keyboard is working on the grid, so we can use the enter and F2 or click on the selected cell twice. We can close the editor with keys for example with enter, arrows, tab or page buttons. In this case the modification will be saved. If we click on another cell, the result will be the same.
We can’t edit the cells by default, we need to enable it in column definition. We can edit a cell if we press an enter, click in the cell twice or start to write text into the active cell. The editing can happen inside the coll or in a little popup window. In the last case the content will only be changed when we finished the editing in the popup window.
We can edit the cells by default. If we need some cells to be readable, we have to use the isReadOnly property. The editing starts with double clicking, F2 pressing and writing in the selected cell.
It’s sad, but at this component we can only use filtering in the PRO version.
There is a dropdown menu in the column head of the grid, we can find the filtering here. We need to enable the filters and the dropDownMenu for the table. There are other options in the dropdown menu for example: delete content of the column and positioning. If we only want to display the filtering, we can set it with dropDownMenu.
Filtering is a free function, we don’t need to pay for it. (Yay! :))
We have a lot of possibilities at this component. There are different types of filters, such as number, date, string, etc. Besides we can access them from different places. One option when the filter is in the head of the table, similar to the Handsontable. Secondly, we can filter the data with API and use buttons outside of the grid. Furthermore, there are floating filters, where the filters are under the head of table and here we can access them easier than in the tablehead.
The filter is a simple input field, it’s separated from the table. We can add in TypeScript, what we want to filter.
We can turn on the column sorting plugin with the columnSorting property. It has two types: boolean and object. In the first case the value is true or false. If it’s on, we can sort the whole table. We have more possibilities at the object type, for example we can select the column what we want to sort, set the sorting rule (decreasing or increasing), or set how it handles the empty cells.
If the plugin is on, we can sort the table by clicking on the tablehead (it worked when I clicked on the text) or the sort() method.
We can enable the sorting with enableSorting property inside the grid options, moreover we can specify it in the column definition, where we can set the possible sortings for the given column. For example it could be growing or decreasing and it shouldn’t be able to do another sorting. It’s very useful, because we can create own comparators.
We can sort the table with clicking on the tablehead (the whole area is sensitive, not just the text) and via the API.
We don’t need to enable the sorting, because it works by default. We can click everywhere inside the head of column.
First, I found this function at ag-Grid as pinning, then I started to search for it at Handsontable and I found it by another name: fixing. The fixedColumnsLeft sets how many columns should be fixed on the left side, the fixedRowsTop does the same thing at the top of the grid.
As I said, we can find it as pinning here. We can set the positions of columns on the left and right sides. We can set the pinned property in the columns’ definition. The value of property can be left or right.
The function is called as freezing. We can set it in HTML with frozenRows and frozenColumns properties and with TypeScript.
I saw that the name of this function is nested rows, but according to the hansondtable website, the function hasn’t been perfected like it is in Flexgrid or ag-Grid. It belongs to the PRO functions.
We can goup data by one or more values easily. We can set it in column definition. If we want to group the data by countries, we set the next property at column: rowgroupIndex: 0
Then we want to group the data by years as well: we have to set this property again on the next (year) column like this: rowGroupIndex: 1
Just like ag-Grid, it can group by one or more values. You can see on the picture, I grouped the data by countries first. In the revenue column, values are all added for each country by date. And for each date we can see all revenue for that group. Overall values automatically change if we modify any of the sub-values.
There is a so-called handsontable cell type. If we use it, a bit arrow will be displayed in the right side of the cell. When we click on it, a new table will be opened above the previous table. Personally, I don’t like this solution very much, I prefer a solution that I will show you at ag-Grid soon. If you know or find a better solution for Master-detail at Handsontable, please share with me!
Function of the grid differs from Handsontable. Plus signs will be displayed in front of the texts. We can put tables, pictures, buttons here and we can use the ag-Grid functions, for example filtering and sorting. The tables are independent, if we select something on one of tables, it won’t effect the other tables.
We don’t have to display all information in the table, we can access them outside of the table. The data won’t be displayed inside the table when we click on a row.
Fortunatelly, in all cases we can modify the style of the table according to our own ideas. Mainly, we can find lot of information about that at ag-Grid and Handsontable. ag-Grid created some theme for their grid earlier, what we can use free, or we can use them when we would like to create our own themes.
At Handsontable we can set the type of a column, so we can validate the content with that. I searched a lot for this function at ag-Grid and Flexgrid, but I didn’t find it. Of course it doesn’t mean we can’t validate the texts, but Handsontable has a lot of cell types (string, numeric, date, time, etc.), and because of that we can validate easily. It’s not a PRO function. When we are trying to write the wrong value into the cell, we can’t save it nor can we edit other cells or the cell will have other background color.
The method with which we can set the labels on the head of the grid at Handsontable was weird to me. This method at ag-Grid was much cleaner. At ag-Grid we can add them in column definition with the headerName property. At Handsontable we have to use an array in the colHeaders and outside of the column definition. So when I would like to remove a column, I need to pay attention to remove the label from the right place in the array. It’s not a big deal with three columns, but if we have lot of columns, it can cause some problems.
The filtering is in the PRO version at Handsontable, wasn’t that a surprise! I think it’s not a rare function. The solution at ag-Grid was better, because it has a lot of possibilities for filtering. I can set the filter under the header and it’s a good thing. Honestly I can access the filter easier like this, and I don’t have to click on the header every time.
I didn’t write about it in the earlier part of the post, but there are so-called groups at ag-Grid. They make the table cleaner, mainly when we have lot of of columns. In this case, more headers can be under each other. Under the top level there can be lot of levels. I didn’t find this function in Flexgrid, but I did at Handsontable as nested headers among the PRO functions. At ag-Grid we can open and close these groups and it’s very spectacular and definitely useful.
It’s big advantage at Handsontable that we can copy the cells in Excel style. There is a little square at the bottom right corner of the active cell and you can drag it in horizontal and vertical directions.
I mentioned Flexgrid only a few times, but it’s not a free component, so it’s hard to write a detailed review. I had a few different reasons to choose this component as the third subject in this comparsion: First of all, you can check it, but there aren’t lot of grids that we can use in Angular 2 at present. Most of the grids are made for jquery or Angular 1, and I didn’t find a solution similar to Handsontable (it has directive for Angular 2), but I would have tried other free grids too. Besides since Flexgrid is paid, I got curious about its advantages over its free counterparts. It has a lot of good functions, but if you don’t need the support and other stuffs, I think it makes sense for you to choose from the free solutions.
I haven’t found a lot of information about browser versions at ag-Grid. According to their site, ag-Grid is compatible with IE 9+, Firefox, Chrome and Safari.
At first, I liked Handsontable the most. I liked some of its functions, cell types and that I could use validation. It was sad though, that some important functions are in the PRO version. It was surprising to me, how much ag-Grid could provide. I checked this component right after Handsontable, so I thought I couldn’t access some functions here for free, but I was wrong. I worked with a lot of grids in Angular 1 a long time ago, and I couldn’t think of any tasks that I couldn’t have solved with ag-Grid.
We can create good tables with all three components. We should choose the one we need in the given situation. Why should we suffer with adding a filter row under the header or validating, if the another component can do it by default? Fortunately, these components don’t differ too much from each other. If you know one, you can understand others quickly and easily.
In this post I didn’t write about all of their functions. If anybody checks the ag-Grid website, they can see that I could write even five part post about this component. And it’s just ag-Grid. With this post I wanted to show you solutions of the spreedsheet components, so developers can see how the tables are able to implement the more popular functions.
Feel free to add your thoughts in the comment section, I’d love to hear about your experiences with these components.
And if you want to learn more about Angular, there are some useful posts written by my colleague, Csenge about creating a cross-browser Angular pull-to-refresh for example.