首页 > 解决方案 > 如何在 ag 网格自定义单元格编辑器中按下箭头键和输入键时做出 event.stopPropagation() 以反应选择输入字段

问题描述

我正在使用 ag-grid 进行记录编辑。

如何制作一个在按下箭头和输入键时不执行任何操作的单元格编辑器。

与此代码类似,但带有 react-select 组件

import React, { Component } from 'react'
import TextField from '@material-ui/core/TextField'
class TextCellEditor extends Component {
    constructor(props) {
        super(props);
        this.textInput = React.createRef();
    }


    onKeyDown(event) {
        if (event.keyCode === 39 || event.keyCode === 37) {
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        if (this.textInput) this.textInput.current.focus();
    }

    getValue() {
        return this.textInput.current.value;
    }

    isPopup(){
        return true
    }

    isCancelAfterEnd(){
        return false

    }

    componentDidMount() {
        this.textInput.current.addEventListener('keydown', this.onKeyDown);
    }

    render() {
        return (
            <TextField
                defaultValue={this.props.value}
                inputProps={{
                    ref:this.textInput
                }}
            />
        );
    }
}

export default TextCellEditor

我试过使用 refsaddeventListener但它不起作用,这是我当前的 react-select 单元格编辑器代码

import React, { Component } from 'react'
import CreatableSelect  from "react-select/lib/Creatable"
import { components } from 'react-select'
import axios from "axios"
import Cookies from 'js-cookie'
import IconButton from '@material-ui/core/IconButton'
import EditIcon from '@material-ui/icons/Edit'
import ReactDOM from 'react-dom'


//redux
import { connect } from 'react-redux'
import {
    setNotification,
    updateFullRecord,
    pushBreadcrumbs,
    pushFullRecord,
    setCFI,
    setFullView,
    pushModalRecord,
    setModalView,
    setCMI,
    toggleModal,
} 
from '../../../actions/ActivityActions'



class ReactSelectCellEditor extends Component {

    constructor(props) {
        super(props);
        this.state = {
            selected : {
                value : "",
                labal : ""
            },
            suggestion :[]
        }
        this.handleChange = this.handleChange.bind(this)
        this.MTORef = React.createRef();
        this.InputRef = React.createRef();
        console.log("cell editor props:",this.props)
    }


    componentDidMount() {
        axios.post(this.props.host+"/api/"+this.props.model+"/options", {
            search  : "",
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        })
        .then(response => {
            var arr     = response.data.records
            var result  = arr.map(record =>({
                label :record[this.props.fieldAsLabel],
                value: record[this.props.fieldAsValue]
            }))
            this.setState({
                suggestion : [
                    ...result
                ]
            })
        })
    }

    getLabel=(id)=>{
        axios.get(this.props.host+"/api/"+this.props.model+"/"+id,{
            headers:{
                Authorization:"Bearer "+Cookies.get("accessToken")
            }
        })
    }

    handleClickEdit = () => {
        axios.post(this.props.host+"/api/"+this.props.model+"/"+this.state.selected.value, {
            search  : this.state.selected.value,
            limit   : 10
        },{
            headers: {
                Authorization: "Bearer "+Cookies.get("accessToken")
            }
        }).then((response)=>{
            this.props.pushModalRecord({
                ...response.data,
                formMode:"edit",
                _modal:true
            })
            this.props.saveFormState()
            this.props.setModalView(this.props.form)
            this.props.setCMI(this.props.Activity.currentModalIndex+1)
            this.props.toggleModal()
        })
    }

    handleCreateOption = (inputValue:any) => {
        this.props.pushModalRecord({
            [this.props.fieldAsLabel]:inputValue,
            formMode:"create",
            _modal:true
        })
        this.props.saveFormState()
        this.props.setModalView(this.props.form)
        this.props.setCMI(this.props.Activity.currentModalIndex+1)
        this.props.toggleModal()
    }

    handleChange(selected){
        selected = selected === null?"":selected
        this.setState({
            selected : {
                label : selected.label,
                value : selected.value
            }
        })
    }


    onKeyDown(event) {
        let key = event.which || event.keyCode;
        if (key === 37 ||  // left
            key === 39) {  // right
            event.stopPropagation();
        }
    }

    afterGuiAttached(param) {
        this.SelectRef.focus()
    }

    getValue() {
        return this.state.selected.value
    }

    isPopup() {
        return true
    }


    render() {
        return (
            <div>
            <div style={{minWidth:"200px",display:"flex"}}>
                <div style={{width:"160px"}}>
                <CreatableSelect 
                    isLoading       = {false}
                    options         = {this.state.suggestion}
                    defaultValue    = {this.props.value !== undefined?{
                        label:this.props.label,
                        value:this.props.value
                    }:null}
                    onChange        = {this.handleChange}
                    onKeyDown       = {event=>this.onKeyDown(event)}
                    onCreateOption  = {this.handleCreateOption}
                    ref             = { ref => { this.MTORef = ref }}
                    isClearable

                />
                </div>
                {this.props.editable?<IconButton onClick={()=>this.handleClickEdit()}>
                    <EditIcon/>
                </IconButton>:""}
            </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        Global      :state.GlobalReducer,
        Activity    :state.ActivityReducer
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        setNotification: (isOpen,message,color)=>{
            dispatch(setNotification(isOpen,message,color))
        },
        updateFullRecord: (data,index) => {
            dispatch(updateFullRecord(data,index))
        },
        setCFI: (index) => {
            dispatch(setCFI(index))
        },
        pushFullRecord: (record) => {
            dispatch(pushFullRecord(record))
        },
        setFullView: (path) => {
            dispatch(setFullView(path))
        },
        pushBreadcrumbs: (data) => {
            dispatch(pushBreadcrumbs(data))
        },
        toggleModal : () => {
            dispatch(toggleModal())
        },
        pushModalRecord : (data) => {
            dispatch(pushModalRecord(data))
        },
        setModalView : (path) => {
            dispatch(setModalView(path))
        },
        setCMI : (data) => {
            dispatch(setCMI(data))
        },
    }
}

export default connect(mapStateToProps,mapDispatchToProps,null,{ forwardRef: true })(ReactSelectCellEditor)

标签: reactjsag-gridreact-selectag-grid-react

解决方案


您可以使用suppressKeyboardEvent回调忽略箭头并为整个网格或特定单元格输入键。如果网格应该抑制事件,回调应该返回 true,或者返回 false 以正常继续。

回调具有以下签名:

导出接口 SuppressKeyboardEventParams 扩展 IsColumnFuncParams {

   // the keyboard event the grid received. inspect this to see what key was pressed
   event: KeyboardEvent;

   // whether the cell is editing or not. sometimes you might want to suppress event
   // only when cell is editing.
   editing: boolean;

   node: RowNode; // row node
   data: any; // row data
   column: Column; // column
   colDef: ColDef; // column definition
   context: any; // context object
   api: GridApi | null | undefined; // grid API
   columnApi: ColumnApi | null | undefined; // column API

}

回调函数可能如下所示 -

function suppressEnterArrow(params) {
      let KEY_LEFT = 37;
      let KEY_UP = 38;
      let KEY_RIGHT = 39;
      let KEY_DOWN = 40;
      let KEY_ENTER = 13;
      let ignoredKeys = [KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_ENTER, KEY_DOWN];
      var event = params.event;
      var key = event.which;
      var suppress = ignoredKeys.include(key) && params.editing && 
         params.colDef.cellEditor === <Your Text Cell Editor>;
      return suppress;
   }

您可以在此处阅读更多相关信息 - https://www.ag-grid.com/javascript-grid-keyboard-navigation/#suppressKeyboardEvents


推荐阅读