Home  » Help  » IntegralUI  » Web Components  » Grid

Grid Rows with Custom Toolbar on Mouse Over

In cases when you need to perform some action in the Grid component, you may use a control panel or a toolbar outside of the grid. The IntegralUI Grid comes with built-in functionality that allows you to attach custom toolbar to each row that will appear on mouse over or when item is selected. This toolbar can be the same for all rows or you can set a different one for each row individually.

In this article, you will learn how to create a custom toolbar that will appear when row is hovered in Grid web component for Angular, React and Vue.

Grid component is part of IntegralUI Web
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

As demo shows, when moving the mouse cursor over rows, a toolbar will appear on the right side. The toolbar contains three icons: Delete, Statistics and Favorite. Clicking on them will start a different action accordingly.

How to Show a Toolbar when Row is Hovered

In addition to the default template in use for grid cells, there are two additional templates where you can add custom content. Difference between these templates is in their type:

  • default template - type attribute is set to 'row'
  • hover template - type attribute is set to 'row-hover'
  • select template - type attribute is set to 'row-select

The content from the default template is displayed in cell space of each row. On other hand, the content from hover and select templates are displayed only on demand, and will appear over entire row space in current grid view.

<iui-grid [columns]="columns" [rows]="rows" #grid>
    <ng-template let-column [iuiTemplate]="{ type: 'header' }">
        <!-- Header content -->
    </ng-template>
    <ng-template let-cell [iuiTemplate]="{ type: 'cell' }">
        <!-- Default row cell content -->
    </ng-template>
    <ng-template let-row [iuiTemplate]="{ type: 'row-hover' }">
        <!-- Content when row cell is hovered -->
    </ng-template>
    <ng-template let-row [iuiTemplate]="{ type: 'row-select' }">
        <!-- Content when row cell is selected -->
    </ng-template>
    <ng-template let-column [iuiTemplate]="{ type: 'footer' }">
        <!-- Footer content -->
    </ng-template>
</iui-grid>
                                    

When you want to display a toolbar on mouse over a row, use the hover template. By default, this template is transparent, only when you add content to it, it will appear as docked to the right side within the visible row space. This content will always appear over the default row content.

In this example, the hover template contains a toolbar with three icons, which acts like command buttons with following functionality:

  • Delete - removes the current hover row from the grid
  • Statistics - displays a message
  • Favorite - marks the row as favorite and changes the row icon in first cell
import { IntegralUIGrid } from './integralui/components/integralui.grid';

. . .

ngAfterViewInit(){
    let self = this;

    // Add command buttons to each child row
    let initTimeout = setTimeout(function(){
        let list = self.grid.getFullList();
        list.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);

}

isFavorite(cell: any){
    let row  = this.grid.findRowById(cell.rid);
    return row ? row.favorite == true : false;
}

isRowHovered(cell: any){
    let row  = this.grid.findRowById(cell.rid);
    return row == this.grid.getHoverRow();
}

rowButtonClicked(row: any, button: any){
    switch (button.key){
        case 'DELETE':
            this.grid.removeRow(row);
            this.grid.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;
    }
}
                                    
<iui-grid [columns]="columns" [rows]="rows" [rowHeight]="30" [showFooter]="false"#grid>
    <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="grid-rwhov-cell-favorite" [ngClass]="{ 'grid-rwhov-cell-favorite-selected': isFavorite(cell) }" [ngStyle]="{ opacity: isRowHovered(cell) ? 1 : 0.5 }"></span>
            </span>
            <span *ngSwitchDefault style="display:inline-block">
                <span class="grid-rwhov-cell-label">{{cell.text}}</span>
            </span>
        </span>
    </ng-template>
    <ng-template let-row [iuiTemplate]="{ type: 'row-hover' }">
        <div class="grid-rwhov-button" *ngFor="let button of row.buttons" [iuiTooltip]="button.tooltip" [tooltipRef]="tooltipReference">
            <span class="grid-rwhov-button-icons {{button.icon}}" (click)="rowButtonClicked(row, button)"></span>
        </div>
    </ng-template>
</iui-grid>
                                    
.grid-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;
}
.grid-rwhov-button:hover {
    animation-name: grid-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 grid-rwhov-button-animate-enter {
    0% { background: transparent; }
    100% { background: #d5d5d5; }
}
.grid-rwhov-button-icons {
    background-image: url(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;
}
                                    

You can also set the hover content to appear on left side, only change the CSS settings for the hover template.

In some cases, you may need to change the content of the toolbar depending on the row that is hovered. For example, if you don't want to delete some rows using the toolbar, you may need to exclude the delete button. To solve this, when buttons are added to rows, skip adding the delete button to specific rows.

let list = self.grid.getFullList();
list.map(row => {
    row.buttons = [];

    for (let i = 0; i < 3; i++){
        switch(i){
            case 0:
                if (row.id !== 12 && row.id !== 23)
                    row.buttons.push({ key: 'DELETE', icon: 'trash', tooltip: { title: "Delete", initialDelay: 1000 } });
                break;

            case 1:
                row.buttons.push({ key: 'CHARTS', icon: 'statistics', tooltip: { title: "Statistics", initialDelay: 1000 } });
                break;

            case 2:
                row.buttons.push({ key: 'MARK', icon: 'favorite', tooltip: { title: "Favorite", initialDelay: 1000 } });
                break;
        }
    }
});
                                    

In this example, the toolbar for rows with id 12 and 23 don't have a delete button.

Different Ways to Show Toolbar in Grid Rows

The contentVisibility property of the Grid component, determines when then content from row templates will appear. This property accepts values from IntegralUIContentVisibility enumeration, which can have one of the following values:

  • None - content is hidden
  • Hover - content is shown on mouse over row
  • Select - content is shown for selected row
  • Both - content is shown when row is hovered or selected

This property allows you to set the visibility of content from templates on general level, which is it affects all grid rows. If this property is not set explicitly, it has the Both as default value, which means that content from hover and select templates will appear in both cases, when row is hovered or selected, correspondingly.

This property doesn't have effect on the default row template.

You can also choose when the content will appear on individual level, for each row separately. The row object has a contentVisibility field, which accepts the same values from the IntegralUIContentVisibility enumeration. To hide the content for specific row, just set this field value to None.

This allows you to create custom conditions on how and when the content form hover and select templates will appear. For example, you can a have a toolbar to appear on hover for all rows except when there are multiple rows selected. To set this:

  • Set the contentVisibility property to Hover
  • Set the contentVisibility property to Select when there are more than one row selected
import { IntegralUIContentVisibility } from './integralui/components/integralui.core';

. . .

public gridContentVisibility: IntegralUIContentVisibility = IntegralUIContentVisibility.Hover;

onSelectionChanged(e: any){
    let selList = this.grid.getList('selected');

    this.gridContentVisibility = selList.length > 1 ? IntegralUIContentVisibility.Select : IntegralUIContentVisibility.Hover;
}
                                    
<iui-grid [columns]="columns" [rows]="rows" [contentVisibility]="gridContentVisibility"  (selectionChanged)="onSelectionChanged($event)"#grid>

. . .
                                    

Toolbar for Selected Items

In similar way, you can display a custom toolbar when row is selected. This toolbar may be the same as the one from hover template, or you can create entirely different content.

<iui-grid [columns]="columns" [rows]="rows" [rowHeight]="30" [showFooter]="false"#grid>

    . . .

    <ng-template let-row [iuiTemplate]="{ type: 'row-select' }">
        <div class="grid-rwhov-button" *ngFor="let button of row.buttons" [iuiTooltip]="button.tooltip" [tooltipRef]="tooltipReference">
            <span class="grid-rwhov-button-icons {{button.icon}}" (click)="rowButtonClicked(row, button)"></span>
        </div>
    </ng-template>
</iui-grid>
                                    

In this example, there is no hover content, the toolbar will appear only when row is selected.

If multi-selection is enabled, the toolbar will appear for all selected rows. As an example, the toolbar will change based on number of selected rows. If there is more than one row selected, the Statistics button is excluded from the toolbar. This condition is set in selectionChanged event where you can check how many rows are selected:

public numSelRows: number = 0;

onSelectionChanged(e: any){
    this.numSelRows = this.grid.getList('selected').length;
}
                                    
<iui-grid [columns]="columns" [rows]="rows" (selectionChanged)="onSelectionChanged($event)"#grid>

    . . .

    <div *ngFor="let button of row.buttons; let i = index" style="display:inline-block">
        <div *ngIf="i !== 1 || (i === 1 && numSelRows === 1)" class="grid-rwhov-button" [iuiTooltip]="button.tooltip" [tooltipRef]="tooltipReference">
            <span class="grid-rwhov-button-icons {{button.icon}}" (click)="rowButtonClicked(row, button)"></span>
        </div>
    </div>
</iui-grid>
                                    

Conclusion

In this article you have learned how to show a toolbar when row is hovered or selected for Grid as a web component. You can find the sample code in plain JavaScript and for Angular, React and Vue frameworks.

The default template determines the content displayed in grid cells. When you need to show an additional content, for example a toolbar, you can use hover or select templates that will display the toolbar on demand, when row is hovered and/or selected.

Using custom conditions you can determine when and how the content will appear, on hover, select or in both cases. You can also choose to hide the content for specific rows.

The Grid component is part of IntegralUI Web.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.