Add new row from context menu

Hi,


I would like a Context Menu option to be able to add a new row at a user selectable position. The Context Menu item should appear when a user right clicks on a cell, and the action is to insert a new blank row directly below the currently selected row. Is this possible?


Also, what callback is called after a row drag and drop event?


Thanks,

Andrew


12 Replies

JC Joseph Christ Nithin Issack Syncfusion Team July 5, 2021 04:08 PM UTC

Hi Andrew, 
  
  
   Greetings from Syncfusion support. 
  
Query 1: I would like a Context Menu option to be able to add a new row at a user selectable position. The Context Menu item should appear when a user right clicks on a cell, and the action is to insert a new blank row directly below the currently selected row. Is this possible? 
  
   Based on your requirement you want to add a row using the context menu where the row is inserted below the currently selected row. Before proceeding with your requirement, we need you to provide the following details. 
  
1.       Do you want to add a new row  with data predefined or you want to add a row with the edit form objects. 
2.       By default the edit form objects will be added to the top of the row, Do you want to add the form at the top and then save the row to the desired row index. 
 
 
Query 2:  what callback is called after a row drag and drop event 
 
The `rowDrop` event callback is triggered when the row element is dropped on the target row 
 
  
Regards, 
Joseph I.  



AN Andrew July 6, 2021 12:58 PM UTC

Hi Joseph,


I would like to add a row with the edit form objects, and I would like this to be directly below the currently selected row.

I'm using batch editing, when the user clicks 'save' the row should remain in the desired row index position


Thanks,

Andrew



JC Joseph Christ Nithin Issack Syncfusion Team July 7, 2021 11:16 AM UTC

Hi Andrew, 
  
Thanks for your update. 
  
Based on your requirement you want to add a new row below the currently selected row, and you have also mentioned that you are using batch editing mode.  
 
By default, in EJ2 Grid batch editing, the newly added row element will be added in the DOM virtually (i.e) which will not be reflected to the gridRows. When we save the newly added record then only it will be reflected to the gridRows, so it is not feasible to insert the newly added row element under the selected row. 
  
Regards, 
Joseph I. 



AN Andrew July 7, 2021 11:40 AM UTC

Hi Joseph,


Is there any way to override the default functionality and have control over where in the virtual DOM the newly added row element will appear?

Is there any callback after the batch edit is saved, but before the grid is refreshed? My idea is I could use that to sort the gridRows and get the new row into the desired position. I assume gridRows is an array of the row objects?


Thanks,

Andrew 



RR Rajapandi Ravi Syncfusion Team July 9, 2021 11:03 AM UTC

Hi Andrew, 

Thanks for the update 

Query#: Is there any way to override the default functionality and have control over where in the virtual DOM the newly added row element will appear? 

Before we start providing solution on your query, we need some information for our clarification. So please share the below details that would be helpful for us to provide better solution. 

1)      Please confirm whether you just want to display the added row in virtual DOM or you want to add the row in datasource. 

Query#: Is there any callback after the batch edit is saved, but before the grid is refreshed? 

When the batch is saved and before the grid refresh actionComplete event gets triggered. Please refer the below code example and sample for more information. 


actionComplete(args) { //actionComplete event of Grid 
    if (args.requestType == 'batchsave') { 
        console.log('Action complete triggers'); 
   
 




Regards,
Rajapandi R 



AN Andrew July 10, 2021 06:51 AM UTC

Hi Rajapandi,


My ultimate goal is to be able to add a new row to the datasource also. I would like to have functionality similar to Excel's 'Insert - Sheet Rows'

 


I need to be able to right click on any cell, and have a context menu appear with an option to insert a new row. Clicking this will insert an empty new row directly below the currently selected row.


The initial response I received syncfusion said, with batch editing the add new row process happens in two steps. First step is to insert a new row with the edit form objects into the virtual DOM. By default this is added at the top of the grid. I would like to be able to change this default functionality, and have the new row edit form objects appear on the grid below the currently selected row, as I described above.

-> can you please provide some information on how I can achieve this?


The second step is for the newly added row to be saved to the datasource after the user clicks the 'update' button. I am using a locally bound datasource.


I tried to solve the second step. Code sample below:

Each row object in my grid has a property 'sort'. I will assign a value for sort in the 'beforeBatchSave' function. In the 'actionComplete' function I sort the row datasource array, and update grid datasource props (using React useState hook - signals/setSignals).

The functionality is ok, the new row appears at the correct position after clicking 'update. However, there is a small time delay between the new row disappearing from the top row, and it reappearing in the required position.

-> is there anything I can change here to prevent the new row disappearing off the screen for a fraction of a second, as you can see in the attached video?

Code sample:

function beforeBatchSave(args: any) {
if (grid && args.batchChanges.addedRecords.length > 0) {
for (let addedRecord of args.batchChanges.addedRecords) {
addedRecord.sort = "xyz" // will use a function to determine this dynamically
}
}
}

function actionComplete(args: any) {
if (grid && args.requestType === "batchsave") {
setSignals((grid?.dataSource as []).sort((a: any, b: any) => a.sort > b.sort ? 1 : -1))
grid.refresh()
}
}

return (
<div className="full-height-grid">
<GridComponent
ref={g => grid = g}
dataSource = {signals}
...


Thanks,

Andrew


Attachment: Screen_Recording_20210710_at_2.48.46_PM_83e56396.zip


AN Andrew July 10, 2021 03:17 PM UTC

Hi,


Clarification for the above message- "Clicking this will insert an empty new row directly below the currently selected row."

I realise now that the 'currently selected row' can be different to the row that the user right-clicks on, as the right-click doesn't actually make the selection (unlike in Excel).

This is fine, I would like the new row to appear below the row that the user right-clicks on, not the currently selected row. I would like to use the 'rowIndex' from the args to determine where in the virtual DOM the new row edit object 

Hope that is clear?


Thanks,

Andrew



AG Ajith Govarthan Syncfusion Team July 14, 2021 03:15 PM UTC

  
Hi Andrew, 
  
Sorry for the convenience caused. 
  
Based on your requirement you need to add empty new row just below the selected row with context menu.  So, we have tried to override our default batch edit behavior and found that your requirement breaks our selection, validation and focus related features. 
  
So, it is not feasible to achieve your requirement. However, we can achieve your requirement with Normal edit mode feature. So, please confirm that you want to achieve the same with Normal edit mode. Based on your confirmation, we will prepare and provide you the sample for your requirement. 
  
  
Regards, 
Ajith G. 



AN Andrew July 15, 2021 01:15 PM UTC

Hi,


Ok I understand. Please send a sample showing how I could achieve this using 'Normal' edit mode.


Thanks,

Andrew



JC Joseph Christ Nithin Issack Syncfusion Team July 16, 2021 09:11 AM UTC

Hi Andrew, 
  
Thanks for the update. 
  
Query: Ok I understand. Please send a sample showing how I could achieve this using 'Normal' edit mode. 
  
Based on your query you want to add records with context menu at the particular position. So, we have prepared sample and in that sample we have used the actionBegin, contextMenuOpen and actionComplete events to achieve your requirement.  
 
For your convenience we have attached the sample, please refer them for your reference. 
  
Code Example: 
Index.js 
  
export class ContextMenuSample extends SampleBase { 
  constructor() { 
    super(...arguments); 
    this.groupOptions = { showGroupedColumn: true }; 
    this.selectedIndex = -1; 
    this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel']; 
    this.contextMenuItems = [ 
      'AutoFit', 
      'AutoFitAll', 
      'SortAscending', 
      'SortDescending', 
      'Copy', 
      'Edit', 
      'Delete', 
      'PdfExport', 
      'ExcelExport', 
      'CsvExport', 
      'FirstPage', 
      'PrevPage', 
      'LastPage', 
      'NextPage', 
      { text: 'Add Record', target: '.e-content', id: 'addrecord' } 
    ]; 
    this.editing = { 
      allowDeleting: true, 
      allowAdding: true, 
      allowEditing: true 
    }; 
  } 
  actionComplete(args) { 
    debugger; 
    if (args.requestType === 'add') { 
      var addedRow = this.gridInstance 
        .getContentTable() 
        .querySelector('.e-addedrow'); 
      var tbody = this.gridInstance.getContentTable().querySelector('tbody'); 
      tbody.insertBefore(addedRow, tbody.children[this.selectedIndex + 2]); 
    } 
    if (args.requestType === 'save' && args.action === 'add') { 
      this.selectedIndex = -1; 
   } 
  } 
  contextMenuClick(args) { 
    if (this.gridInstance && args.item.id === 'addrecord') { 
      this.gridInstance.addRecord(); 
    } 
  } 
  
  actionBegin(args) { 
    if (args.requestType === 'save' && args.action === 'add') { 
      args.index = this.selectedIndex + 1; 
    } 
  } 
  
  contextMenuOpen(args) { 
    if (args.rowInfo.rowIndex) { 
      this.selectedIndex = args.rowInfo.rowIndex; // get the target index here 
    } 
  } 
  render() { 
    return ( 
      <div className="control-pane"> 
        <div className="control-section"> 
          <GridComponent 
            id="gridcomp" 
            dataSource={orderDetails} 
            allowPaging={true} 
            allowSorting={true} 
            allowExcelExport={true} 
            contextMenuClick={this.contextMenuClick.bind(this)} 
            ref={grid => (this.gridInstance = grid)} 
            actionBegin={this.actionBegin.bind(this)} 
            actionComplete={this.actionComplete.bind(this)} 
            allowPdfExport={true} 
            toolbar={this.toolbarOptions} 
            contextMenuItems={this.contextMenuItems} 
            editSettings={this.editing} 
            contextMenuOpen={this.contextMenuOpen.bind(this)} 
          > 
            <ColumnsDirective> 
              <ColumnDirective 
                field="OrderID" 
                headerText="Order ID" 
                width="120" 
                textAlign="Right" 
                isPrimaryKey={true} 
              /> 
              <ColumnDirective 
                field="CustomerName" 
                headerText="Customer Name" 
              /> 
              <ColumnDirective 
                field="Freight" 
                headerText="Freight" 
                format="C2" 
                textAlign="Right" 
                editType="numericedit" 
              /> 
              <ColumnDirective 
                field="ShipName" 
                headerText="Ship Name" 
                width="200" 
              /> 
              <ColumnDirective 
                field="ShipCountry" 
                headerText="Ship Country" 
                width="150" 
                editType="dropdownedit" 
              /> 
              <ColumnDirective 
                field="ShipCity" 
                headerText="Ship City" 
                width="150" 
              /> 
            </ColumnsDirective> 
            <Inject 
              services={[ 
                Resize, 
                Toolbar, 
                Sort, 
                ContextMenu, 
                Filter, 
                Page, 
                ExcelExport, 
                Edit, 
                PdfExport 
              ]} 
            /> 
          </GridComponent> 
        </div> 
      </div> 
    ); 
  } 
  
render(<ContextMenuSample />, document.getElementById('sample')); 
  
  
Please get back to us if you need further assistance. 
  
Regards, 
Joseph I. 



AN Andrew July 16, 2021 01:27 PM UTC

Thanks Joseph, much appreciated 



AG Ajith Govarthan Syncfusion Team July 19, 2021 05:10 AM UTC

Hi Andrew, 
  
Thanks for the update. 
  
We are happy to hear that the provided solution is working fine at your end. 
  
Please get back to us if you need further assistance. 
  
Regards, 
Ajith G. 


Loader.
Up arrow icon