a suite of UI Components for development of web apps
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
Advanced User Interface Controls and Components
Created: 21 Oct 2019
Usually the angular grid displays data in its rows and cells based on provided data while actions are handled outside of the grid by other controls. Instead of adding custom actions outside the grid, you can make them as part of the grid component. For example, if you need to show custom buttons that will handle specific action in the Grid, and you want them to appear only when row is hovered.
Like using cell editors to change the grid data, in IntegralUI Grid and TreeGrid components for Angular, you can also show a custom button bar on row hover. In this article, you will learn how to add custom buttons that will appear whenever a grid row is hovered.
If you have any questions, don't hesitate to contact us at support@lidorsystems.com
As you move the mouse cursor over some row in angular grid, a button bar will appear on right side of the row showing three buttons: Delete, Statistics and Favorite. A tooltip will appear on each button, with a small delay, showing the button title. By clicking on these buttons, a different action will happen: a row deletion, prompt message and marking a row as favorite.
To add data in IntegralUI TreeGrid component, you need to use a template for grid cells. Each cell can have the same or a separate template. In case of adding buttons on row hover, you also need to use a template with its identifier set to 'row-hover'. This identifier specifies that the content in the template will be displayed only on row hovering.
Note To set a different template for specific hover row, you can use ngSwitch inside the template and row id to determine the row object. To simplify the example, all rows use the same template.
<div class="app-block" #application>
<iui-treegrid [appRef]="applicationRef" [controlStyle]="treegridStyle" [columns]="columns" [rows]="rows" [rowHeight]="30" [showFooter]="false" [expandColumnID]="1" [gridLines]="gridLines" [showHoverRow]="isHoverRowAllowed" #treegrid>
<ng-template let-column [iuiTemplate]="{ type: 'header' }">
{{column.headerText}}
</ng-template>
<ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
<span [ngSwitch]="cell.cid">
<span *ngSwitchCase="2">
<span class="treegrid-rwhov-cell-favorite" [ngClass]="{ 'treegrid-rwhov-cell-favorite-selected': isFavorite(cell) }" [ngStyle]="{ opacity: isRowHovered(cell) ? 1 : 0.5 }"></span>
</span>
<span *ngSwitchDefault style="display:inline-block">
<span class="treegrid-rwhov-cell-label">{{cell.text}}</span>
</span>
</span>
</ng-template>
<ng-template let-row [iuiTemplate]="{ type: 'row-hover' }">
<div class="treegrid-rwhov-button" *ngFor="let button of row.buttons" [iuiTooltip]="button.tooltip" [tooltipRef]="tooltipReference">
<span class="treegrid-rwhov-button-icons {{button.icon}}" (click)="rowButtonClicked(row, button)"></span>
</div>
</ng-template>
</iui-treegrid>
</div>
Once you have the template set up, you can add any custom content, which can be HTML elements or other Angular components. In this case, the template has three buttons with a tooltip.
Note Because this content is shown on row hover, the content height is based on average row height. Although you can add custom elements, you need to keep in mind that hovering template will appear on top of grid row within its size.
In TreeGrid component, not all rows will have data in all cells. For example, parent rows may only have one cell with a title. For this purpose, there is no reason to show the button bar for these rows.
To exclude the button bar from row, you can filter the grid rows by checking whether they have a parent or not. In that way only the rows that are children will have the template applied. For example:
ngAfterViewInit(){
let self = this;
// Add command buttons to each child row
let initTimeout = setTimeout(function(){
let list = self.treegrid.getFullList();
list.filter(row => self.treegrid.getRowParent(row))
.map(row => row.buttons = [
{ key: 'DELETE', icon: 'trash', tooltip: { title: "Delete", initialDelay: 1000 } },
{ key: 'CHARTS', icon: 'statistics', tooltip: { title: "Statistics", initialDelay: 1000 } },
{ key: 'MARK', icon: 'favorite', tooltip: { title: "Favorite", initialDelay: 1000 } }
]
);
self.tooltipReference = self.applicationRef;
clearTimeout(initTimeout);
}, 100);
}
You may notice that this code is placed under ngAfterViewInit method, this allows us to also apply the application reference to the tooltips. This is required, so that tooltips appear on top of other elements using the reference to the top application component as an element under which tooltip is created in the DOM.
Like any other button in Angular, you can use the click event and add a specific event handler for each button separately. Based on provided button object from teh template settings, you can distinguish which button is clicked and proceed accordingly.
isFavorite(cell: any){
let row = this.treegrid.findRowById(cell.rid);
return row ? row.favorite == true : false;
}
isRowHovered(cell: any){
let row = this.treegrid.findRowById(cell.rid);
return row == this.treegrid.getHoverRow();
}
rowButtonClicked(row: any, button: any){
switch (button.key){
case 'DELETE':
this.treegrid.removeRow(row);
this.treegrid.updateLayout();
break;
case 'CHARTS':
alert("Statistics button is clicked for row: " + row.text);
break;
case 'MARK':
row.favorite = row.favorite != undefined ? !row.favorite : true;
button.icon = row.favorite ? 'favorite-selected' : 'favorite';
break;
}
}
<div class="treegrid-rwhov-button" *ngFor="let button of row.buttons" [iuiTooltip]="button.tooltip" [tooltipRef]="tooltipReference">
<span class="treegrid-rwhov-button-icons {{button.icon}}" (click)="rowButtonClicked(row, button)"></span>
</div>
</ng-template>
.treegrid-rwhov-button {
background: transparent;
border: 0;
border-radius: 3px;
cursor: pointer;
display: inline-block;
margin: 1px 3px 0 3px;
padding: 5px;
white-space: no-wrap;
}
.treegrid-rwhov-button:hover {
animation-name: treegrid-rwhov-button-animate-enter;
animation-delay: 0s;
animation-direction: normal;
animation-duration: 0.25s;
animation-fill-mode: forwards;
animation-iteration-count: 1;
animation-play-state: running;
animation-timing-function: linear;
}
@keyframes treegrid-rwhov-button-animate-enter {
0% { background: transparent; }
100% { background: #d5d5d5; }
}
.treegrid-rwhov-button-icons {
background-image: url(src/app/resources/icons-x24.png);
background-repeat: no-repeat;
display: inline-block;
overflow: hidden;
padding: 0 !important;
margin: 0;
width: 24px;
height: 24px;
vertical-align: top;
}
.trash {
background-position: -72px -48px;
}
.favorite {
background-position: -216px -72px;
}
.favorite-selected {
background-position: -144px -72px;
}
.statistics {
background-position: -216px -168px;
}
In this example, the button bar has three buttons:
In similar way, you can add other buttons or different elements to the button bar like a label showing data related to the row. To keep this example simple, all rows when hovered show three buttons.
In case when you need to add some custom action to the Grid, you can use a template and create custom button bar that will include buttons for each action. This content can appear only on row hover, so that the user can take actions based on grid row that is currently hovered.
The IntegralUI TreeGrid component for Angular comes with a built-in option that allows you to add custom content to each row and set it to appear only when row is hovered. You can share the sample templates for all rows, or create a different one for each row separately. This feature greatly enhances the Grid UI, by providing custom UI elements on demand, in this case on row hovering.
The TreeGrid component is part of IntegralUI Web.