如何在ag-grid-react cellEditor组件中按“Enter”键按下事件传播?

时间:2016-11-23 22:44:15

标签: reactjs ag-grid ag-grid-react

我的问题主要围绕着文档w.r.t中的this statement。反应成分:

  

cellEditor Params

     

onKeyDown 回调告诉网格按下了某个键 - 对于传递非常有用   控制关键事件(标签,箭头等)回到网格 - 但是你没有   需要调用它,因为网格已经在监听事件了   他们传播。只有在您阻止事件时才需要这样做   传播。

我知道cellEditor params存在,因为道具被传递给组件的反应版本,但我似乎无法找到如何附加到文档中指定的 onKeyDown 。在我的cellEditor的构造函数中,onKeyDown函数存在并匹配我的列定义中onKeyDown中指定的cellEditorParams(如果存在)。

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

但如果它只是存在于组件

中,它永远不会达到
onKeyDown(event) {
  console.log('not reached');
}

如果我将onKeyDown={this.props.onKeyDown}放在我输入的顶级包装div内,但仍然没有按下“Enter”按下,则会调用它。

我试着收听包含自定义单元格编辑器的单元格

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

哪个确实捕获了输入但是在我按下输入之前它似乎卸载了我才能捕获到该字段内的最终输入?我已经看到这种行为不起作用,所以我很困惑。

我目前有一个简单的单元格编辑器 MyCellEditor ,我试图进行聚焦,并在按下输入时选择下一个单元格。我已经能够从rowIndex的rowRenderer中提取我需要的columnthis.props.api.rowRenderer属性,然后使用它们:

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

我的问题是从“Enter”按下默认情况下阻止事件传播的位置。

下面是我的单元格编辑器和用法。

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;

列定义:

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')
    }
  },
  ...
}

阵营:

<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')} />

7 个答案:

答案 0 :(得分:3)

@ buddyp450,有完全相同的问题,并在ag-grid gitgub下创建了一个问题,但是几分钟后找到了解决方法,你可以在我的例子中将关键代码更改为13并且工作完美:)

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();
        }
    }
    :

路易斯

答案 1 :(得分:2)

不幸的是,尽管停止了事件传播,立即传播和防止默认,但所提供的答案实际上都无法阻止本机ag-grid导航事件的传播。

在一个未知区域的某个地方,通过反应ag-grid,导航元素正在劫持一切。我知道这一点,因为我按照此线程中的建议添加了一个侦听器,然后在侦听器的控制台出来之前将renderCell的控制台输出。

我最终采用了简单愚蠢的方法来分析ag-grid和调整onKeyDown:

renderedCell.ts

答案 2 :(得分:1)

将侦听器添加到网格容器以捕获按键。

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

定义监听器。

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

答案 3 :(得分:1)

v13.2.0开始,ag-grid有一个suppressKeyboardEvent回调,可以添加到列定义中以自定义默认键盘导航。您可以找到文档和示例here in the official docs

答案 4 :(得分:0)

我从ag-grid的文档中发现,“grid-api”是由React组件的onGridRead()回调提供的。 以下api函数可以帮助您为keyPress注册事件。

addEventListener(eventType, listener)

尝试类似:

onGridReady = (api)=>{
    api.addEventListener('keyPress', this.keyPressEventHandlerCallback);
}

keyPressEventHandlerCallback=(e)=>{
    ...handler code here
}

答案 5 :(得分:0)

意图是你抓住了'进入&#39;按下你的cellRenderer按下键:

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} />
);

然后你会阻止来自onKeyDownListener的传播。这是如何在javascript中工作的。如果React发生了不同的事情,那我就不知道了:(

答案 6 :(得分:0)

我最后做的是更改afterGuiAttached中的一行(例如LargeTextCellEditor.prototype.afterGuiAttached),以便从超时调用this.textarea.focus。 (我还没有进一步了解问题的根源,但现在这对我有用)

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