- Home
- Forum
- Angular - EJ 2
- onhover need to get an icon at the end of a row
onhover need to get an icon at the end of a row
Hi Team,


I have couple of queries as mentioned in below images,
1. onhover i need to get an icon at the end of a row,please check below image
2. onclick of the corner icon, need to get an dropdown kind and that should have action items like add edit etc
3. I need an icon before the expand icon
4. How can I add complex data binding like example
ex: name: {firstname:"",last:{name:"}} -> if I want to add last.name as a fieldname then how can i do it?
ex: employee[{},{}] -> if I want to display length of an employee array length then how I need to give that in field name?
Regards,
Bhavya
SIGN IN To post a reply.
16 Replies
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 8, 2020 11:50 AM UTC
Hi Bhavya,
Greetings from Syncfusion support.
Query – 1: “On hover i need to get an icon at the end of a row, please check below image”
Query – 2: “On click of the corner icon, need to get an dropdown kind and that should have action items like add edit etc”
You can achieve these requirements by rendering the EJ2 Menu control with sub-menu items in the last grid column using its template property and on clicking the sub-menu items you can perform the required operations like add, edit using grid methods – addRecord, startEdit respectively. This is explained below,
Initially render the EJ2 Menu control in the last grid column(And disable edit to this column using its allowEditing property) using template with the required sub-menu items(Add, Edit) on clicking which the corresponding actions can be performed. Then bind select event to the menu.
app.component.html
|
<ejs-grid #grid id='grid' (created)='onCreated($event)' allowPaging='true' [dataSource]='data' [editSettings]='editSettings' [toolbar]='toolbar'>
<e-columns>
.
.
<e-column headerText='Actions' width=150 [allowEditing]='false'>
<ng-template #template>
<div class='custom-menu'>
<ejs-menu #menu [items]='menuItems' (select)='onSelect($event)'></ejs-menu>
</div>
</ng-template>
</e-column>
</e-columns>
</ejs-grid> |
app.component.ts
|
ngOnInit() {
.
.
// Menu items
this.menuItems = [
{
iconCss: 'e-icons MT_Menu',
items: [
{ text: 'Add', iconCss: 'e-icons Add' },
{ text: 'Edit', iconCss: 'e-icons Edit' }
]
}
];
} |
In the menu’s select event, if the selected item is ‘Add’, then invoke the Grid’s addRecord method to add a new record to the Grid. If the selected item is ‘Edit’, get the grid’s row index, select the row using selectRow method and enable edit using startEdit method.
|
// Menu’s select event function
onSelect(args) {
if (args.item.text === Add) {
// Adds a new record
this.grid.addRecord();
} else if (args.item.text === 'Edit') {
// Gets the grid row index based on the selected menu item
var gridRowIndex = parseInt(args.item.controlParent.lItem.closest('.e-row').getAttribute('aria-rowindex'));
// Selects the grid row
this.grid.selectRow(gridRowIndex);
// Enables edit for the selected row
this.grid.startEdit();
}
} |
Icon styles for the menu items,
|
// Icon for the parent menu item
.MT_Menu::before {
content: '\e984';
}
// Icon for add sub menu item
.Add::before {
content: '\e7f9';
}
// Icon for edit sub menu item
.Edit::before {
content: '\e81e';
}
// Removes the default caret icon displayed in the menu
.e-menu-wrapper ul .e-menu-item .e-caret::before {
content: '' !important;
}
// Adjusting position of the menu element
.e-menu-wrapper {
margin-left: 11px;
}
// Modifying the width of the parent menu item
.e-menu-wrapper ul.e-menu {
width: 20px;
}
// Adjusting the position of the parent menu icon
.e-menu-wrapper ul.e-menu .e-menu-item {
padding-left: 3px;
padding-right: 3px;
width: 20px;
} |
If you only want this menu icon to be displayed while hovering the row, then you can achieve this by setting visibility as ‘hidden’ to this menu’s parent element in the rowDataBound event and modifying this visibility property on ‘mouseenter’ and ‘mouseleave’ events on the row elements. This is demonstrated in the below code snippet,
|
// Grid’s rowDataBound event function
rowDataBound(args) {
// The menu is hidden initially using its parent element rendered in the column template
args.row.querySelector('.custom-menu').style.visibility = "hidden";
// Mouse enter and leave events are bound to the row elements
args.row.addEventListener('mouseenter', function (args) {
// Menu is shown
args.target.querySelector('.e-menu-wrapper').style.visibility = "visible";
})
args.row.addEventListener('mouseleave', function (args) {
// Menu is hidden
args.target.querySelector('.e-menu-wrapper').style.visibility = "hidden";
})
} |
For more details on the EJ2 Menu control you can check the below help documentation site,
EJ2 Menu documentation: https://ej2.syncfusion.com/angular/documentation/menu/getting-started/
Query – 3: “I need an icon before the expand icon”
This requirement can be achieved by dynamically creating and appending a div element with the icon class to each row in the Grid’s rowDataBound event(Triggers each time a row element is appended to the Grid element). To avoid header and content misalignment due to the new element added in the content, an empty element is added to the header row in the Grid’s dataBound event. This is demonstrated in the below code snippet,
|
// Grid’s rowDataBound event function
rowDataBound(args) {
// A new element is created and appended as first child to the row element
var tdEle = document.createElement('td');
tdEle.innerHTML = '<div class="e-icons Custom-icon"></div>';
args.row.insertBefore(tdEle, args.row.firstElementChild);
}
dataBound(args) {
var headertable = this.grid.element.querySelector('.e-columnheader');
// A new element is created and appended as first child to the header element
var tdEle = document.createElement('td');
tdEle.innerHTML = '<div></div>';
headertable.insertBefore(tdEle, headertable.firstElementChild);
} |
Icon styles added based on its class name.
|
<style>
.Custom-icon:before {
content: '\e7f9';
}
</style> |
We have prepared a sample based on the above three queries for your reference which you can find below,
Query – 4: “How can I add complex data binding”
You can achieve complex data binding using the dot(.) operator in the field name. This is demonstrated in the below code snippet based on your field values,
|
<e-column field='last.name' headerText='Name'></e-column> |
You can refer the below help documentation site for more details on this,
Complex data binding documentation: https://ej2.syncfusion.com/angular/documentation/grid/columns/#complex-data-binding
Note: If the data is an array of objects then you need to access them like, “last.0.name”. You can refer the below help documentation for more details on this,
Complex data binding with array of objects documentation: https://ej2.syncfusion.com/angular/documentation/grid/how-to/list-of-array-of-objects/
For displaying the array length in the column field you can specify its length like demonstrated in the below code snippet,
|
<e-column field='employee.length' headerText='Length'></e-column> |
Please get back to us if you require any further assistance.
Regards,
Sujith R
BH
Bhavya Harini
April 9, 2020 09:12 AM UTC
Hi Team,
Query – 3: “I need an icon before the expand icon”
Regarding above query, i have added the given below code its fine but i need to manuplate the icon based on my api response
if my employee is inactive i need to show icon-x and if active i need to show icon-y, so i need to check my api response and then based on that i need to add the icon in front of each row. Please reply soon
BH
Bhavya Harini
April 9, 2020 09:51 AM UTC
Hi Team,
onhover im able to get icon but i should get below scenario, onclick of the icon i should get the dropdown as exact as below the icon should be exist. Please check below image as i need same UI for onclick action dropdown

Regards,
Bhavya
BH
Bhavya Harini
April 9, 2020 10:28 AM UTC
Hi Team,
Please check the below code i have added action icons as last column and also icon on front of each row as you have suggested but we are getting spacing between each row and also while scrolling the table headers are moving to right.please check my sample code
html:
<ejs-grid #grid id='Grid' [dataSource]='rowData' (rowDataBound)='rowDataBound($event)' (dataBound)="dataBound($event)">
<e-columns>
<ng-container *ngFor="let column of def; index as i">
<e-column *ngIf=" i == 0;else Show" [field]="column.tagName" [headerText]="column.tagLabel" [width]="column.tagWidth" [textAlign]="column.tagTextAlign">
<ng-template #template let-data>
<div>
<a rel='nofollow' rel='nofollow' rel='nofollow' href="">{{data[column.tagName]}}</a>
</div>
</ng-template>
</e-column>
<ng-template #Show>
<e-column [field]="column.tagName" [headerText]="column.tagLabel" [width]="column.tagWidth" [textAlign]="column.tagTextAlign">
</e-column>
</ng-template>
</ng-container>
<e-column width=150 [allowEditing]='false'>
<ng-template #template>
<div class='custom-menu'>
<ejs-menu #menu [items]='menuItems' (select)='onSelect($event)'></ejs-menu>
</div>
</ng-template>
</e-column>
</e-columns>
</ejs-grid>
App.ts
ngOnInit() {
this.rowData= this.items.items;
const td = new TableDefinition(this.tableDefinition);
this.def = td.tags.map(item => {
return item;
});
this.filterOptions = {
type: 'Menu'
};
this.menuItems = [
{
items: [
{ text: 'Add' },
{ text: 'Edit' }
]
}
];
}
// Grid’s rowDataBound event function
rowDataBound(args) {
// The menu is hidden initially using its parent element rendered in the column template
args.row.querySelector('.custom-menu').style.visibility = "hidden";
// Mouse enter and leave events are bound to the row elements
args.row.addEventListener('mouseenter', function (args) {
// Menu is shown
args.target.querySelector('.e-menu-wrapper').style.visibility = "visible";
})
args.row.addEventListener('mouseleave', function (args) {
// Menu is hidden
args.target.querySelector('.e-menu-wrapper').style.visibility = "hidden";
})
var tdEle = document.createElement('td');
tdEle.innerHTML = '<span class="icon icon-Bell"></span>';
args.row.insertBefore(tdEle, args.row.firstElementChild);
}
dataBound(args) {
var headertable = this.grid.element.querySelector('.e-columnheader');
// A new element is created and appended as first child to the header element
var tdEle = document.createElement('td');
tdEle.innerHTML = '<div></div>';
headertable.insertBefore(tdEle, headertable.firstElementChild);
}
Thanks,
Bhavya
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 10, 2020 07:30 AM UTC
Hi Bhavya,
Query – 1: “Manipulate the icon based on my API response”
You can achieve this requirement by adding icon content for different classes and based on the API response remove the previous class and add the new icon class to update the icon. This is demonstrated in the below code snippet on button click function,
app.component.ts
|
// Button click event function
iconChange(args) {
// Different icon classes that can be added to the Grid are retrieved
var customIconElements = this.grid.element.querySelectorAll('.Custom-icon');
var updatedIconElements = this.grid.element.querySelectorAll('.Updated-icon');
// Icon class is added and removed alternatively
// Here you can update based on your API response
if (customIconElements.length !== 0) {
customIconElements.forEach(x => x.classList.remove('Custom-icon'));
customIconElements.forEach(x => x.classList.add('Updated-icon'));
} else {
updatedIconElements.forEach(x => x.classList.remove('Updated-icon'));
updatedIconElements.forEach(x => x.classList.add('Custom-icon'));
}
} |
app.component.css
|
.Custom-icon:before {
content: '\e7f9';
}
.Updated-icon:before {
content: '\e934';
} |
Query – 2: “Change sub-menu position”
From your query and attached image we could see that you wish to modify the sub-menu element’s display position. You can achieve this by binding beforeOpen event to the menu and in that event you can change the menu position by modifying the arguments top and left values. We have demonstrated this in the below code snippet by modifying the sub-menu position based on the menu wrapper’s position,
|
// Menu’s beforeOpen event function
beforeOpen(args) {
var top = args.event.target.closest('.e-menu-wrapper').getBoundingClientRect().top;
var left = args.event.target.closest('.e-menu-wrapper').getBoundingClientRect().left;
args.top = top;
args.left = left;
} |
This requirement is documented in our help documentation site in the below mentioned link which you can check for your reference,
Documentation: https://ej2.syncfusion.com/angular/documentation/menu/how-to/change-sub-menu-position/
Query – 3: “We are getting spacing between each row and also while scrolling the table headers are moving to right”
Sorry for the inconvenience. This problem was occurring due to the code in the dataBound event, as a ‘div’ element was getting inserted in the header row each time the dataBound was getting triggered. You can resolve this problem by executing this code only on initial render by using a flag variable. This is demonstrated in the below code snippet,
|
export class AppComponent implements OnInit {
.
.
public initialRender = true;
dataBound(args) {
if (this.initialRender) {
var headertable = this.grid.element.querySelector('.e-columnheader');
var tdEle = document.createElement('td');
tdEle.innerHTML = '<div></div>';
headertable.insertBefore(tdEle, headertable.firstElementChild);
this.initialRender = false;
}
}
.
.
} |
We have modified the previously provided sample based on the above queries for your reference which you can find below,
Let us know if you have any concerns.
Regards,
Sujith R
BH
Bhavya Harini
April 13, 2020 10:23 AM UTC
HI Team,
While scrolling as the menu is hidden at the below line im getting below error
args.target.querySelector('.e-menu-wrapper').style.visibility = "hidden";
core.js:14597 ERROR TypeError: Cannot read property 'style' of null
Regards,
Bhavya
BH
Bhavya Harini
April 13, 2020 10:29 AM UTC
H Team,


I have my icon, onhover i'm placing the icon for each row.
Onclick of icon i need below behaviour, please provide proper solution
Note: icon should be on window n menu items and the window should be open left
Regards,
Bhavya
BH
Bhavya Harini
April 14, 2020 12:43 PM UTC
HI Team,
Can someone reply on it
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 14, 2020 01:02 PM UTC
Hi Bhavya,
Query – 1: “While scrolling as the menu is hidden error is occurring”
You can resolve this by checking if the target has the menu control and if so change its visibility style.
|
args.row.addEventListener('mouseenter', function (args) {
if (args.target.querySelector('.e-menu-wrapper')) {
args.target.querySelector('.e-menu-wrapper').style.visibility = "visible";
}
})
args.row.addEventListener('mouseleave', function (args) {
if (args.target.querySelector('.e-menu-wrapper')) {
args.target.querySelector('.e-menu-wrapper').style.visibility = "hidden";
}
}) |
Query – 2: “Menu dropdown position”
We are currently validating this query from our end. We will update the further details on 16th April 2020. Until then your patience is appreciated.
Regards,
Sujith R
BH
Bhavya Harini
April 14, 2020 01:33 PM UTC
No Worries, i will use same menuitem what you have given above, but please make changes just onhover just move the dropdown on the hovered row and icon should be on it.just make these changes.It help me alot.
Note: how can i chnage the drop down down arrow icon?
Regards,
Bhavya
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 15, 2020 09:23 AM UTC
Hi Bhavya,
As informed in our previous update, our team is currently working on your query – “Changing menu dropdown position” and we will update the further details by 16th April 2020.
For your other query – “how can i change the drop down arrow icon?”, we suspect you mean the below menu icon,
The icon class for this is set in the following line,
|
this.menuItems = [
{
iconCss: 'e-icons MT_Menu'
}
]; |
And the corresponding icon content is set in the following CSS code,
|
.MT_Menu::before {
content: '\e984';
} |
So if you are using an icon from the e-icons library you can just modify the icon content above. If you wish to render you own icon then you can set the required CSS class in the menu item’s iconCss property and set the corresponding icon content for that class in the CSS styles.
e-icons library documentation: https://ej2.syncfusion.com/angular/documentation/appearance/icons/#material
Let us know if you have any concerns.
Regards,
Sujith R
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 16, 2020 11:06 AM UTC
Hi Bhavya,
Thanks for your patience.
You can achieve the requirement – “Changing menu dropdown position with icon displayed on right side in the sub-menu” by modifying the menu’s left position in the beforeOpen event and setting float style to the icon property as demonstrated in the below code snippet,
app.component.ts
|
ngOnInit() {
.
.
this.menuItems = [
{
iconCss: 'e-icons MT_Menu',
items: [
{ text: 'Add', iconCss: 'e-icons MT_Menu' },
{ text: 'Edit', iconCss: 'e-icons Edit1' }
]
}
];
}
// Menu’s beforeOpen event
beforeOpen(args) {
var top = args.event.target.closest('.e-menu-wrapper').getBoundingClientRect().top;
var left = args.event.target.closest('.e-menu-wrapper').getBoundingClientRect().left;
args.top = top;
args.left = left - 120;
} |
app.component.css
|
.MT_Menu::before {
content: '\e984';
}
.e-menu-icon {
float: right;
} |
Updated sample for your reference,
Let us know if you have any concerns.
Regards,
Sujith R
BH
Bhavya Harini
April 17, 2020 05:12 AM UTC
HI,
It is not helping,the menu is at same place it is not moving top and left
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 20, 2020 09:38 AM UTC
Hi Bhavya,
With the code snippet we had provided in the last update, the dropdown menu was moved to the position you had requested for. Please check below video demo for your reference,
Video demo: https://www.syncfusion.com/downloads/support/forum/153087/ze/SyncfusionAngularApp-1498259456
We suspect the problem might be occurring due to cached memory in the browser causing old settings to be restored. So we suggest you to clear the local cache and then run your application to see if this resolves the problem. If you are using older Syncfusion packages we suggest you to update to the latest version.
If your problem still persists please share us the following information to validate further,
- Video demo of the problem.
- Grid code file.
- If possible provide us a sample replicating the problem or try reproducing it in the sample we had provided.
Let us know if you have any concerns.
Regards,
Sujith R
BH
Bhavya Harini
April 21, 2020 04:58 AM UTC
Hi Team,

Thanks a lot for your support. Its working fine now. But only last only one issue, if I release the onhover effect from row and move to Menu dropdown then onhover effect is disappeared as we used mouseenter and mouseleave(check below code). Onhover of row should be appear still we move to dropdown. Please make this changes by EOD we have milestone
args.row.addEventListener('mouseenter', function (args) {
if (args.target.querySelector('.e-menu-wrapper')) {
args.target.querySelector('.e-menu-wrapper').style.visibility = "visible";
}
})
args.row.addEventListener('mouseleave', function (args) {
if (args.target.querySelector('.e-menu-wrapper')) {
args.target.querySelector('.e-menu-wrapper').style.visibility = "hidden";
}
})
QN2:
.e-grid .e-icon-grightarrow::before,
.e-grid-menu .e-icon-grightarrow::before {
content: '\e734';
}
.e-grid .e-icon-gdownarrow::before,
.e-grid-menu .e-icon-gdownarrow::before {
content: '\e705';
}
I have used above code but still im not getting below icons, instead of that getting ChevronUp icon n ChevronDown icon
SK
Sujith Kumar Rajkumar
Syncfusion Team
April 22, 2020 11:40 AM UTC
Hi Bhavya,
We are glad to hear that the provided solution worked for you.
Query – 1: “Onhover of row should be appear still we move to dropdown.”
Since the Menu is a custom component rendered in the Grid columns, focusing on the menu items will not maintain hover on the Grid rows. However you can achieve this requirement by adding custom class to the row in the Menu’s beforeOpen and beforeClose event and then add the hover styles to this custom class. This is demonstrated in the below code snippet,
app.component.html
|
<ejs-menu #menu [items]='menuItems' (beforeClose)='beforeClose($event)' (beforeOpen)='beforeOpen($event)' (select)='onSelect($event)'></ejs-menu> |
app.component.ts
|
beforeOpen(args) {
args.parentItem.parentObj.element.closest('.e-row').classList.add('custom-hover');
}
beforeClose(args) {
args.parentItem.parentObj.element.closest('.e-row').classList.remove('custom-hover');
} |
app.component.css
|
.custom-hover {
background-color: #eee;
color: #000;
} |
Query – 2: “I have used above code but still I’m not getting below icons, instead of that getting ChevronUp icon n ChevronDown icon”
We checked this problem from our end but the icons were properly rendered on using your code snippet in the application. Please check below image for your reference,
We suspect the icon styles may not be reflected due to ViewEncapsulation enabled in your application causing the style to be scoped for particular components. So we suggest you to set the ViewEncapsulation to None to resolve this problem.
|
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ToolbarService, DetailRowService],
encapsulation: ViewEncapsulation.None
}) |
We have modified the previously provided sample based on the above queries. You can download it from the below link,
Let us know if you have any concerns.
Regards,
Sujith R
SIGN IN To post a reply.
- 16 Replies
- 2 Participants
-
BH Bhavya Harini
- Apr 7, 2020 05:34 AM UTC
- Apr 22, 2020 11:40 AM UTC