How to prevent the event propagation for pressing the Enter key in the cellEditor component of ag-grid reaction?

My question is primarily related to this statement in the wrt docs react component:

CellEditor parameter

onKeyDown The callback for passing the grid pressed a key - useful for transmitting to control key events (tab, arrows, etc.) back to the grid - however you do not need to call this because the grid is already listening to events as they propagate. This is only necessary if you are preventing the Propagation event.

I understand that the cellEditor parameters exist, since the props are passed to the reaction version of the component, but I can not find how to connect to onKeyDown , as indicated in the docs. In my constructor for my cellEditor there is an onKeyDown function and corresponds to onKeyDown specified in cellEditorParams inside the definition of my column (if it exists).

 constructor(props) { super(props); // console.log(typeof props.onKeyDown == 'function') => 'true' } 

But it was never reached if it just exists in the component

 onKeyDown(event) { console.log('not reached'); } 

It onKeyDown={this.props.onKeyDown} called if I put onKeyDown={this.props.onKeyDown} inside the top-level wrapper div around my input, but it still does not catch "Enter".

I tried listening to a cell containing my custom cell editor

 this.props.eGridCell.addEventListener('keyup', (event) => { console.log(event.keyCode === 13) }) 

Which one captures input, click , but it seems to turn off when input is pressed, before I can capture the final click inside the field? I have seen behavior when this does not work, so I am very confused.

Currently, I have a simple MyCellEditor cell editor, which I try to focus and select the next cell when clicking is entered in addition to just a tab. I already have the ability to retrieve the rowIndex and column properties that I need from rowRenderer in this.props.api.rowRenderer , which I then use as:

this.props.api.rowRenderer.moveFocusToNextCell(rowIndex, column, false, false, true);

My problem is to prevent the distribution of the default event from "Enter".

Below is my cell editor and usage.

 import React from 'react'; import _ from 'lodash'; class MyCellEditor extends React.Component { constructor(props) { super(props); this.state = { value: props.value, }; } getValue() { return this.state.value; } isPopup() { return false; } isCancelBeforeStart() { return false; } afterGuiAttached() { const eInput = this.input; eInput.focus(); eInput.select(); } onKeyDown(event) { // Never invoked! } onChangeListener = (e) => { this.setState({ value: e.target.value }); } render() { return ( <input ref={(c) => { this.input = c; }} className="ag-cell-edit-input" type="text" value={this.state.value} onChange={this.onChangeListener} /> ); } } export default MyCellEditor; 

Column Definition:

 columnDefs = [{ headerName: 'CustomColumn', field: 'customField', editable: true, cellClass: 'grid-align ag-grid-shop-order-text', sortable: false, cellEditorFramework: MyCellEditor, // Do I need cellEditorParams? cellEditorParams: { // onKeyDown: (event) => console.log('does not output') } }, ... } 

React:

 <AgGridReact columnDefs={columnDefs} rowData={this.props.rows} enableColResize="false" rowSelection="single" enableSorting="false" singleClickEdit="true" suppressMovableColumns="true" rowHeight="30" // onKeyDown also does nothing here onGridReady={this.onGridReady} onGridResize={() => console.log('grid resized')} onColumnResize={() => console.log('column resized')} /> 
+5
source share
7 answers

@ buddyp450, had exactly the same problem and created a problem in ag-grid gitgub, however after a few minutes I found a workaround, you can change the key code to 13 in my example and work fine :)

https://github.com/ceolter/ag-grid/issues/1300

 export default class PATableCellEditor extends Component { constructor(props) { super(props); : } : afterGuiAttached() { // get ref from React component let eInput = this.refs.textField; : // Add a listener to 'keydown' let self = this; eInput.addEventListener('keydown', function (event) { self.myOnKeyDown(event) }); : } : // Stop propagating 'left'/'right' keys myOnKeyDown(event) { let key = event.which || event.keyCode; if (key === 37 || // left key === 39) { // right event.stopPropagation(); } } : 

Louis

+3
source

Unfortunately, none of the answers provided actually allows you to distribute your own ag-grid navigation events, despite the event ceasing to propagate, immediate distribution, and default prevention.

Somewhere in an area unknown to me with a reactive grid, the navigational elements capture everything. I know this since I added the console to renderedCell.ts in the source after adding listeners, as suggested in this thread, and brought the renderedCell console to the listener console.

In the end, I went for a simple-dumb approach to forking the grid and setting up onKeyDown:

 case Constants.KEY_ENTER: // this.onEnterKeyDown(); // Whatever makes the clients happy amirite? this.onTabKeyDown(); break; 
+2
source

Add receiver to mesh containers to capture keyboard.

 onGridReady: {(event) => event.api.gridPanel.eAllCellContainers.forEach( function (container) { container.addEventListener('keydown', keyDownFunc); }); } ... 

Define a listener.

 function keyDownFunc(e) { var key = event.which || event.keyCode; if (e.keyCode == 13) { // enter = 13 // TODO: Handle event } } 
+1
source

Starting with v13.2.0 , ag-grid has a suppressKeyboardEvent callback that can be added to a column definition to set default navigation by default. You can find documentation and an example here in the official docs

+1
source

I found from ag-grid documentation that "grid-api" is provided by the onGridRead () callback of the React component. The following api function can help you register an event for keyPress.

 addEventListener(eventType, listener) 

Try something like:

 onGridReady = (api)=>{ api.addEventListener('keyPress', this.keyPressEventHandlerCallback); } keyPressEventHandlerCallback=(e)=>{ ...handler code here } 
0
source

the intention is that you commit to 'enter' by clicking on your cellRenderer as follows:

 render() { return ( <input ref={(c) => { this.input = c; }} className="ag-cell-edit-input" type="text" value={this.state.value} onChange={this.onChangeListener} onKeyDown={this.onKeyDownListener} /> ); 

then you will prevent propagation from onKeyDownListener. that it works in javascript. if something happens in React, then I don't know :(

0
source

What I did was change the line in afterGuiAttached (LargeTextCellEditor.prototype.afterGuiAttached example), so this.textarea.focus is called from a timeout. (I have not looked further at the source of the problem, but now it works for me)

 LargeTextCellEditor.prototype.afterGuiAttached = function () { if (this.focusAfterAttached) { // this.textarea.focus(); setTimeout(()=>this.textarea.focus()); } }; 
0
source

Source: https://habr.com/ru/post/1260245/


All Articles