- Home
- Forum
- Angular - EJ 2
- Click and hold on cell for dropdown menu
Click and hold on cell for dropdown menu
Dear Syncfusion team.

I have a grid I created with the GridComponent from Syncfusion. What I am trying to achieve is a "click and hold" functionality for the cells of the grid. My app is fairly complex so I am unable to transfer it to stackblitz. My grid looks like this :

What I would like to implement, is that when I click and hold on a cell for more than 2 seconds, a dropdown menu appears below that cell with different options to select from. Once an option selected, the cell value changes to what has been selected. If the dropdown menu appears and a user clicks somewhere else on the page, I want to dismiss/cancel the dropdown menu and hide it.
Is that possible to implement with the grid component?
I created a very minimal StackBlitz as a playground :
Thank you
SIGN IN To post a reply.
5 Replies
PG
Praveenkumar Gajendiran
Syncfusion Team
December 9, 2020 02:51 PM UTC
Hi Remy,
Thanks for contacting Syncfusion support.
Thanks for contacting Syncfusion support.
Based on your request, we have prepared a Grid sample. In the below sample, we have used setTimeout and clearTimeout functions to achieve “click and hold on a cell to open dropdown menu” requirement.
Please refer the below code example, sample and documentation for more information.
Code Example:
[app.component.ts]
Code Example:
[app.component.ts]
|
export class AppComponent {
@ViewChild("normalgrid")
public grid: GridComponent;
public data: Object[];
public editSettings: Object;
public editparams: Object;
public flag: boolean;
public formatoptions: Object;
public mouseTimer;
public ele;
public gfields = ["OrderID", "CustomerID", "ShipCity", "ShipCountry"];
public rowIndex;
public field;
public ngOnInit(): void {
this.data = orderDataSource.slice(0, 30);
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: "Batch",
showConfirmDialog: false
};
this.editparams = {
params: {
dataBound: this.ddDataBound.bind(this),
change: this.change.bind(this)
}
};
this.formatoptions = { type: "dateTime", format: "M/d/y hh:mm a" };
}
load(args: any): void {
this.grid.element.addEventListener("mousedown", this.mouseDown.bind(this)); // mouseDown event
this.grid.element.addEventListener("mouseup", this.mouseUp.bind(this)); //mouseUp event
}
ddDataBound(args) {
var drop = document.getElementsByClassName("e-dropdownlist")[0]
.ej2_instances[0];
drop.showPopup(); // open dropdown popup initially.
}
change(args) {
//triggered when the dropdown value changed
this.grid.saveCell(); // save the changed value
this.grid.endEdit(); // update the selected value
}
cellEdit(args) {
if (this.flag == true) {
args.cancel = true; // prevent the edit action
this.flag = false; // set the flag as false
}
}
recordDoubleClick() {
// triggered when double click the record
this.flag = true; // set the flag variable as true
}
mouseDown(args) {
debugger;
if (args.target.getAttribute("class") == "e-rowcell") {
this.ele = args.target;
this.mouseUp();
this.rowIndex = parseInt(args.target.getAttribute("index"));
this.field = this.gfields[
parseInt(args.target.getAttribute("aria-colindex"))
];
this.mouseTimer = window.setTimeout(this.menu_toggle.bind(this), 2000); //set timeout to fire in 2 seconds when the user presses mouse button down
}
}
menu_toggle() {
this.grid.editCell(this.rowIndex, this.field); // edit the target cell by passing rowIndex and field values as parameter to editCell method.
}
mouseUp() {
if (this.mouseTimer) window.clearTimeout(this.mouseTimer); //cancel timer when mouse button is released
}
} |
[app.component.html]
|
<ejs-grid #normalgrid id="Normalgrid" [dataSource]="data" allowPaging="true" [editSettings]="editSettings"
(load)="load($event)" (recordDoubleClick)="recordDoubleClick($event)" (cellEdit)="cellEdit($event)">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width="140" textAlign="Right" isPrimaryKey="true">
</e-column>
<e-column field="CustomerID" headerText="Customer ID" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
<e-column field="ShipCity" headerText="Ship City" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
<e-column field="ShipCountry" headerText="Ship Country" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
</e-columns>
</ejs-grid> |
recordDoubleClick: https://ej2.syncfusion.com/angular/documentation/api/grid/#recorddoubleclick
cellEdit: https://ej2.syncfusion.com/angular/documentation/api/grid/#celledit
cellEdit: https://ej2.syncfusion.com/angular/documentation/api/grid/#celledit
Please get back to us if you need further assistance.
Regards,
Praveenkumar G
RE
Remy
December 9, 2020 04:30 PM UTC
Hi Praveenkumar,
Thank you for your prompt response. I'll try to adapt this sample to my app. Is there a way I can hold my click on a cell, have the dropdown appear, hover over the desired option in the dropdown while still holding the click, and have the desired option selected and the dropdown closed only once I release the click over the desired option instead of having to click and hold to show the dropdown and re-clicking again to select an option? Everything would be done in one click press/release.
Thank you,
Remy
PG
Praveenkumar Gajendiran
Syncfusion Team
December 11, 2020 01:14 PM UTC
Hi Remy,
Based on your request, we have prepared a Grid sample. In the below sample, we have used open event of Dropdown and mouseUp event to achieve your requirement.
Based on your request, we have prepared a Grid sample. In the below sample, we have used open event of Dropdown and mouseUp event to achieve your requirement.
Please refer the below code example, sample and documentation for more information.
Code Example:
[app.component.ts]
Code Example:
[app.component.ts]
|
export class AppComponent {
@ViewChild("normalgrid")
public grid: GridComponent;
public data: Object[];
public editSettings: Object;
public editparams: Object;
public flag: boolean;
public formatoptions: Object;
public mouseTimer;
public ele;
public gfields = ["OrderID", "CustomerID", "ShipCity", "ShipCountry"];
public rowIndex;
public field;
public ngOnInit(): void {
this.data = orderDataSource.slice(0, 30);
this.editSettings = {
allowEditing: true,
allowAdding: true,
allowDeleting: true,
mode: "Batch",
showConfirmDialog: false
};
this.editparams = {
params: {
dataBound: this.ddDataBound.bind(this),
change: this.change.bind(this),
open: this.OnOpen.bind(this)
}
};
this.formatoptions = { type: "dateTime", format: "M/d/y hh:mm a" };
}
load(args: any): void {
this.grid.element.addEventListener("mousedown", this.mouseDown.bind(this)); // mouseDown event
this.grid.element.addEventListener("mouseup", this.mouseUp.bind(this)); //mouseUp event
}
ddDataBound(args) {
var drop = document.getElementsByClassName("e-dropdownlist")[0]
.ej2_instances[0];
drop.showPopup(); // open dropdown popup initially.
}
change(args) {
//triggered when the dropdown value changed
this.grid.saveCell(); // save the changed value
this.grid.endEdit(); // update the selected value
}
OnOpen(e, instance) { // dropdown popup open event
var drop = document.getElementsByClassName("e-dropdownlist")[0]
.ej2_instances[0];
e.popup.element
.querySelector("ul")
.addEventListener("mouseup", function(e) {
drop.onMouseClick(e); // here we select the hover dropdown item by mouseUp event
});
}
cellEdit(args) {
if (this.flag == true) {
args.cancel = true; // prevent the edit action
this.flag = false; // set the flag as false
}
}
recordDoubleClick() {
// triggered when double click the record
this.flag = true; // set the flag variable as true
}
mouseDown(args) {
if (args.target.classList.contains("e-rowcell")) {
this.ele = args.target;
this.mouseUp();
this.rowIndex = parseInt(args.target.getAttribute("index"));
this.field = this.gfields[
parseInt(args.target.getAttribute("aria-colindex"))
];
this.mouseTimer = window.setTimeout(this.menu_toggle.bind(this), 2000); //set timeout to fire in 2 seconds when the user presses mouse button down
}
}
menu_toggle() {
this.grid.editCell(this.rowIndex, this.field); // edit the target cell by passing rowIndex and field values as parameter to editCell method.
}
mouseUp() {
if (this.mouseTimer) window.clearTimeout(this.mouseTimer); //cancel timer when mouse button is released
}
} |
[app.component.html]
|
<ejs-grid #normalgrid id="Normalgrid" [dataSource]="data" allowPaging="true" [editSettings]="editSettings"
(load)="load($event)" (recordDoubleClick)="recordDoubleClick($event)" (cellEdit)="cellEdit($event)">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width="140" textAlign="Right" isPrimaryKey="true">
</e-column>
<e-column field="CustomerID" headerText="Customer ID" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
<e-column field="ShipCity" headerText="Ship City" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
<e-column field="ShipCountry" headerText="Ship Country" width="150" editType="dropdownedit"
[edit]="editparams"></e-column>
</e-columns>
</ejs-grid> |
Sample: https://stackblitz.com/edit/angular-spqesu-9fkly4?file=app.component.ts
Please get back to us if you need further assistance.
Regards,
Praveenkumar G
RE
Remy
December 11, 2020 03:49 PM UTC
Hi Praveenkumar,
Thank you for your quick response. I am facing one small issue. My grid is generated dynamically via a service (same service used to generate all of the grids in the app). The code looks something like this :
this._gridService.defineGridColumns(structure as object, this.grid).then(result => {
this.grid = (result as GridComponent);
});
The service itself doesn't include the [edit] parameter for each column since it might differ from one grid to another. Therefore I have to add it manually :
this._enginesGridService.defineGridColumns(engineStructure as object, this.grid).then(result => {
this.grid = (result as GridComponent);
this.grid.columns.forEach(column => {
column.edit = this.editparams;
});
});
However, it seems that this doesn't monitor these events correctly unlike as if the editparams was declared directly in the HTML [edit] tag.
I reproduced the problem in the following Stackblitz sample :
Is there any way around this?
Thank you
PG
Praveenkumar Gajendiran
Syncfusion Team
December 14, 2020 03:25 PM UTC
Hi Remy,
Based on your query, we suspect that you want to set the columns.edit property dynamically to the Grid. For this we suggest you to use the below solution in the load event to achieve your requirement.
Based on your query, we suspect that you want to set the columns.edit property dynamically to the Grid. For this we suggest you to use the below solution in the load event to achieve your requirement.
Please refer the below code example and sample for more information.
Code Example:
[app.component.ts]
Code Example:
[app.component.ts]
|
load(args: any): void {
this.grid.element.addEventListener("mousedown", this.mouseDown.bind(this)); // mouseDown event
this.grid.element.addEventListener("mouseup", this.mouseUp.bind(this)); //mouseUp event
for (var i = 0; i < this.grid.columns.length; i++) {
(this.grid.columns[i] as any).edit = this.editparams;
}
}
|
This is not meet your requirement , could you please explain more details about your requirement. Also, share the information about how to dynamically retrieve the columns and how to assign the dynamic columns into the Grid?
Please get back to us if you need further assistance.
Regards,
Praveenkumar G
Regards,
Praveenkumar G
SIGN IN To post a reply.
- 5 Replies
- 2 Participants
-
RE Remy
- Dec 5, 2020 10:06 PM UTC
- Dec 14, 2020 03:25 PM UTC