【问题标题】:ag-grid-react editor component not working MoodCellRendererag-grid-react 编辑器组件不工作 MoodCellRenderer
【发布时间】:2019-07-21 18:39:51
【问题描述】:

我正在尝试动态编辑单元格值,但某些组件无法正常工作,例如 MoodCellRendererNumericCellEditor。其他编辑器组件工作正常。
你能帮我完成它吗?

import React, {Component} from "react";
import {render} from "react-dom";
import {AgGridReact} from "ag-grid-react";
import "ag-grid-enterprise";
import 'bootstrap/dist/js/bootstrap.js';

function cloneObject(obj) {
  return JSON.parse(JSON.stringify(obj));
}


class Example8 extends Component {
  constructor(props) {
    super(props);

    this.state = {
      columnDefs: [{
          headerName: "Value",
          field: "value",
          width: 100,
          editable: true,
          cellEditorSelector: function(params) {
            if (params.data.type === 'age') return {
              component: 'numericCellEditor'
            };

            if (params.data.type === 'gender') return {
              component: 'agRichSelectCellEditor',
              params: {
                values: ['Male', 'Female']
              }
            };

            if (params.data.type === 'mood') return {
              component: 'moodEditor'
            };

            return null;
          }
        },
        {
          headerName: "Type",
          field: "type",
          width: 100
        }
      ],

      rowData: [{
          value: 14,
          type: 'age'
        },
        {
          value: 'female',
          type: 'gender'
        },
        {
          value: "Happy",
          type: 'mood'
        },
        {
          value: 21,
          type: 'age'
        },
        {
          value: 'male',
          type: 'gender'
        },
        {
          value: "Sad",
          type: 'mood'
        }
      ],
      gridOptions: {

        onRowEditingStarted: function(event) {
          console.log('never called - not doing row editing');
        },
        onRowEditingStopped: function(event) {
          console.log('never called - not doing row editing');
        },
        onCellEditingStarted: function(event) {
          console.log('cellEditingStarted');
        },
        onCellEditingStopped: function(event) {
          console.log('cellEditingStopped');
        },
        components: {
          genderCellRenderer: GenderCellRenderer,
          numericCellEditor: NumericCellEditor,
          moodCellRenderer: MoodCellRenderer,
          moodEditor: MoodEditor,
          countryCellRenderer: CountryCellRenderer
        }
      }
    };
  }

  onGridReady = params => {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;
    params.api.sizeColumnsToFit();

  };

  render() {
    return (
        <div style={{ width: "100%", height: "100%" }}>
          <div
            id="myGrid"
            style={{
              height: "100%",
              width: "100%"
            }}
            className="ag-theme-balham"
          >
            <AgGridReact
              columnDefs={this.state.columnDefs}
              components={this.state.components}
              rowData={this.state.rowData}
              onGridReady={this.onGridReady}
            />
          </div>
        </div>
    );
  }
}


function getCharCodeFromEvent(event) {
  event = event || window.event;
  return (typeof event.which == "undefined") ? event.keyCode : event.which;
}

function isCharNumeric(charStr) {
  return !!/\d/.test(charStr);
}

function isKeyPressedNumeric(event) {
  var charCode = getCharCodeFromEvent(event);
  var charStr = String.fromCharCode(charCode);
  return isCharNumeric(charStr);
}

// simple function cellRenderer, just returns back the name of the country
function CountryCellRenderer(params) {
  return params.value.name;
}

// function to act as a class
function NumericCellEditor() {}

// gets called once before the renderer is used
NumericCellEditor.prototype.init = function(params) {
  // create the cell
  this.eInput = document.createElement('input');

  if (isCharNumeric(params.charPress)) {
    this.eInput.value = params.charPress;
  } else {
    if (params.value !== undefined && params.value !== null) {
      this.eInput.value = params.value;
    }
  }

  var that = this;
  this.eInput.addEventListener('keypress', function(event) {
    if (!isKeyPressedNumeric(event)) {
      that.eInput.focus();
      if (event.preventDefault) event.preventDefault();
    } else if (that.isKeyPressedNavigation(event)) {
      event.stopPropagation();
    }
  });

  // only start edit if key pressed is a number, not a letter
  var charPressIsNotANumber = params.charPress && ('1234567890'.indexOf(params.charPress) < 0);
  this.cancelBeforeStart = charPressIsNotANumber;
};

NumericCellEditor.prototype.isKeyPressedNavigation = function(event) {
  return event.keyCode === 39 ||
    event.keyCode === 37;
};


// gets called once when grid ready to insert the element
NumericCellEditor.prototype.getGui = function() {
  return this.eInput;
};

// focus and select can be done after the gui is attached
NumericCellEditor.prototype.afterGuiAttached = function() {
  this.eInput.focus();
};

// returns the new value after editing
NumericCellEditor.prototype.isCancelBeforeStart = function() {
  return this.cancelBeforeStart;
};

// example - will reject the number if it contains the value 007
// - not very practical, but demonstrates the method.
NumericCellEditor.prototype.isCancelAfterEnd = function() {
  var value = this.getValue();
  return value.indexOf('007') >= 0;
};

// returns the new value after editing
NumericCellEditor.prototype.getValue = function() {
  return this.eInput.value;
};

// any cleanup we need to be done here
NumericCellEditor.prototype.destroy = function() {
  // but this example is simple, no cleanup, we could  even leave this method out as it's optional
};

// if true, then this editor will appear in a popup
NumericCellEditor.prototype.isPopup = function() {
  // and we could leave this method out also, false is the default
  return false;
};


function GenderCellRenderer() {}

GenderCellRenderer.prototype.init = function(params) {
  this.eGui = document.createElement('span');
  if (params.value !== "" || params.value !== undefined || params.value !== null) {
    var gender = '<img border="0" width="15" height="10" src="https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/' + params.value.toLowerCase() + '.png">';
    this.eGui.innerHTML = gender + ' ' + params.value;
  }
};

GenderCellRenderer.prototype.getGui = function() {
  return this.eGui;
};

function MoodCellRenderer() {}

MoodCellRenderer.prototype.init = function(params) {
  this.eGui = document.createElement('span');
  if (params.value !== "" || params.value !== undefined || params.value !== null) {
    var imgForMood = params.value === 'Happy' ? 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley.png' : 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley-sad.png';
    this.eGui.innerHTML = '<img width="20px" src="' + imgForMood + '" />';
  }
};

MoodCellRenderer.prototype.getGui = function() {
  return this.eGui;
};

function MoodEditor() {
  this.defaultImgStyle = 'padding-left:10px; padding-right:10px;  border: 1px solid transparent; padding: 4px;';
  this.selectedImgStyle = 'padding-left:10px; padding-right:10px; border: 1px solid lightgreen; padding: 4px;';
}

MoodEditor.prototype.onKeyDown = function(event) {
  var key = event.which || event.keyCode;
  if (key == 37 || // left
    key == 39) { // right
    this.toggleMood();
    event.stopPropagation();
  }
};

MoodEditor.prototype.toggleMood = function() {
  this.selectMood(this.mood === 'Happy' ? 'Sad' : 'Happy');
};

MoodEditor.prototype.init = function(params) {
  this.container = document.createElement('div');
  this.container.style = "border-radius: 15px; border: 1px solid grey;background: #e6e6e6;padding: 15px; text-align:center;display:inline-block;outline:none";
  this.container.tabIndex = "0"; // to allow the div to capture keypresses

  this.happyImg = document.createElement('img');
  this.happyImg.src = 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley.png';
  this.happyImg.style = this.defaultImgStyle;

  this.sadImg = document.createElement('img');
  this.sadImg.src = 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/packages/ag-grid-docs/src/images/smiley-sad.png';
  this.sadImg.style = this.defaultImgStyle;

  this.container.appendChild(this.happyImg);
  this.container.appendChild(this.sadImg);

  var that = this;
  this.happyImg.addEventListener('click', function(event) {
    that.selectMood('Happy');
    params.stopEditing();
  });
  this.sadImg.addEventListener('click', function(event) {
    that.selectMood('Sad');
    params.stopEditing();
  });
  this.container.addEventListener('keydown', function(event) {
    that.onKeyDown(event)
  });

  this.selectMood(params.value);
};

MoodEditor.prototype.selectMood = function(mood) {
  this.mood = mood;
  this.happyImg.style = (mood === 'Happy') ? this.selectedImgStyle : this.defaultImgStyle;
  this.sadImg.style = (mood === 'Sad') ? this.selectedImgStyle : this.defaultImgStyle;
};

// gets called once when grid ready to insert the element
MoodEditor.prototype.getGui = function() {
  return this.container;
};

MoodEditor.prototype.afterGuiAttached = function() {
  this.container.focus();
};

MoodEditor.prototype.getValue = function() {
  return this.mood;
};

// any cleanup we need to be done here
MoodEditor.prototype.destroy = function() {};

MoodEditor.prototype.isPopup = function() {
  return true;
};

// setup the grid after the page has finished loading


export default Example8;

【问题讨论】:

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


    【解决方案1】:
    import React, { Component } from 'react'
        import { render } from 'react-dom'
      //  import { AgGridReact } from 'ag-grid-react'
        import 'ag-grid-enterprise'
        import 'bootstrap/dist/js/bootstrap.js'
    
        import 'ag-grid/dist/styles/ag-grid.css'
        import 'ag-grid/dist/styles/ag-theme-balham.css'
        import {DataGrid} from '@cib-jpm-ui-toolkit/data-grid'
        import $ from 'jquery'
    
        function cloneObject (obj) {
            return JSON.parse(JSON.stringify(obj))
        }
    
    
        class InvoiceTextFields extends Component {
          constructor (props) {
            super(props)
    
            this.state = {
              columnDefs: [
    
                           {headerName: 'Field Name', field: 'fieldName', width: 70},
                           {headerName: 'Extracted Taxonomy', field: 'extractedTaxonomy', width: 70},
                           {headerName: 'Taxonomy Data Field', field: 'taxonomyDataField', width: 70},
            {
                headerName: 'Corrected Texonomy',
                field: 'value',
                width: 70,
                editable: true,
                cellEditorSelector:function (params) {
                    if (params.data.type === 'age') {
     return {
                        component: 'numericCellEditor'
                    }
    }
    
                    if (params.data.type === 'examination') {
    return {
                        component: 'agSelectCellEditor',
                        params: { values: extractValues(carMappings) },
                        valueFormatter: function (params) {
                            return lookupValue(carMappings, params.value)
                          },
                          valueParser: function (params) {
                            return lookupKey(carMappings, params.newValue)
                          }
                    }
    }
                    if (params.data.type === 'tenor') {
                        return {
                                            component: 'agSelectCellEditor',
                                            params: { values: extractValues(tenorMappings) },
                                            valueFormatter: function (params) {
                                                return lookupValue(carMappings, params.value)
                                              },
                                              valueParser: function (params) {
                                                return lookupKey(carMappings, params.newValue)
                                              }
                                        }
                        }
    
                    if (params.data.type === 'dateVal') {
     return {
                 cellEditor: 'datePicker'
                    }
    }
    
                    return null
                }
            }
        ],
     //   components: { datePicker: getDatePicker() },
              rowData: [
            {value: '28/02/2019', type: 'dateVal', fieldName:'Expiry Date'},
            {value: 'YES', type: 'tenor', fieldName:'Tenor Type'},
            {value: 'Vessel 1', type: 'text', fieldName:'Vessel Name'},
            {value: 'Examine Document', type: 'examination', fieldName:'Examination Type'},
    
        ],
              gridOptions:{
    
                  onRowEditingStarted: function (event) {
                      console.log('never called - not doing row editing')
                  },
                  onRowEditingStopped: function (event) {
                      console.log('never called - not doing row editing')
                  },
                  onCellEditingStarted: function (event) {
                      console.log('cellEditingStarted')
                  },
                  onCellEditingStopped: function (event) {
                      console.log('cellEditingStopped')
                  }
    
              }
            }
          }
    
          onGridReady = params => {
            this.gridApi = params.api
            this.gridColumnApi = params.columnApi
        params.api.sizeColumnsToFit()
          };
    
          onCellClicked = (event) => {
              console.log('hi: ' + event.colDef.field)
               console.log('hi type: ' + event.colDef.type)
               if (this.props.correctedTaxonomy === null) {
                   console.log('null')
               }
              if (this.props.correctedTaxonomy === '') {
                  console.log('empty')
              }
             if (event.colDef.field === 'value' && this.props.correctedTaxonomy !== null) {
                 var rowModel = this.gridApi.getModel()
                  var rowNode = rowModel.rowsToDisplay[event.rowIndex]
                 event.data.correctedText = this.props.correctedTaxonomy
                 rowNode.setDataValue('value', event.data.correctedText)
         }
         };
    
    
          render () {
            return (
                    <div style={{ width: '100%', height: '100%' }}>
    
                <div
                  id='myGrid'
                  style={{
                    height: '100%',
                    width: '103%'
                  }}
                  className='ag-theme-balham'
                >
                  <DataGrid
                    columnDefs={this.state.columnDefs}
       //             components={this.state.components}
                    rowData={this.state.rowData}
                  gridOptions={this.state.gridOptions}
                    onGridReady={this.onGridReady}
                  onCellClicked={this.onCellClicked.bind(this)}
                  />
                </div>
              </div>
            )
          }
        }
    
    
        var carMappings = {
                'Examine Document': 'Examine Document',
                'Do not Examine': 'Do not Examine',
                'Send on approval with Doc Exam': 'Send on approval with Doc Exam',
                'Send on Approval Without Doc' : 'Send on Approval Without Doc ',
                'Exam' : 'Exam'
        }
        var tenorMappings = {
          'YES': 'YES',
          'NO': 'NO'
    
        }
        function extractValues (mappings) {
          return Object.keys(mappings)
        }
        function lookupValue (mappings, key) {
          return mappings[key]
        }
        function lookupKey (mappings, name) {
          for (var key in mappings) {
            if (mappings.hasOwnProperty(key)) {
              if (name === mappings[key]) {
                return key
              }
            }
          }
        }
    
        function getCharCodeFromEvent (event) {
            event = event || window.event
            return (typeof event.which === 'undefined') ? event.keyCode : event.which
        }
    
        function isCharNumeric (charStr) {
            return !!/\d/.test(charStr)
        }
    
        function isKeyPressedNumeric (event) {
            var charCode = getCharCodeFromEvent(event)
            var charStr = String.fromCharCode(charCode)
            return isCharNumeric(charStr)
        }
    
    
        function getDatePicker () {
            console.log('in gerDatePicker...')
              function Datepicker () {}
              Datepicker.prototype.init = function (params) {
                this.eInput = document.createElement('input')
                this.eInput.value = params.value
                $(this.eInput).datepicker({ dateFormat: 'dd/mm/yy' })
              }
              Datepicker.prototype.getGui = function () {
                return this.eInput
              }
              Datepicker.prototype.afterGuiAttached = function () {
                this.eInput.focus()
                this.eInput.select()
              }
              Datepicker.prototype.getValue = function () {
                return this.eInput.value
              }
              Datepicker.prototype.destroy = function () {}
              Datepicker.prototype.isPopup = function () {
                return false
              }
              return Datepicker
            }
    
    
    
        export default InvoiceTextFields
    

    【讨论】:

      【解决方案2】:
      import React, { Component } from "react";
      import { render } from "react-dom";
      import { AgGridReact } from "ag-grid-react";
      import "ag-grid-enterprise";
      import 'bootstrap/dist/js/bootstrap.js';
          import $ from 'jquery'
      
          function cloneObject (obj) {
              return JSON.parse(JSON.stringify(obj))
          }
      
      
          class InvoiceTextFields extends Component {
            constructor (props) {
              super(props)
      
              this.state = {
                columnDefs: [
      
                             {headerName: 'Field Name', field: 'fieldName', width: 70},
                             {headerName: 'Extracted Taxonomy', field: 'extractedTaxonomy', width: 70},
                             {headerName: 'Taxonomy Data Field', field: 'taxonomyDataField', width: 70},
              {
                  headerName: 'Corrected Texonomy',
                  field: 'value',
                  width: 70,
                  editable: true,
                  cellEditorSelector:function (params) {
                      if (params.data.type === 'age') {
       return {
                          component: 'numericCellEditor'
                      }
      }
      
                      if (params.data.type === 'examination') {
      return {
                          component: 'agRichSelectCellEditor',
                          params: { values: extractValues(carMappings) },
                          valueFormatter: function (params) {
                              return lookupValue(carMappings, params.value)
                            },
                            valueParser: function (params) {
                              return lookupKey(carMappings, params.newValue)
                            }
                      }
      }
                      if (params.data.type === 'tenor') {
                          return {
                                              component: 'agSelectCellEditor',
                                              params: { values: extractValues(tenorMappings) },
                                              valueFormatter: function (params) {
                                                  return lookupValue(carMappings, params.value)
                                                },
                                                valueParser: function (params) {
                                                  return lookupKey(carMappings, params.newValue)
                                                }
                                          }
                          }
      
                      if (params.data.type === 'dateVal') {
       return {
                   cellEditor: 'datePicker'
                      }
      }
      
                      return null
                  }
              }
          ],
       //   components: { datePicker: getDatePicker() },
                rowData: [
              {value: '28/02/2019', type: 'dateVal', fieldName:'Expiry Date'},
              {value: 'YES', type: 'tenor', fieldName:'Tenor Type'},
              {value: 'Vessel 1', type: 'text', fieldName:'Vessel Name'},
              {value: 'Examine Document', type: 'examination', fieldName:'Examination Type'},
      
          ],
                gridOptions:{
      
                    onRowEditingStarted: function (event) {
                        console.log('never called - not doing row editing')
                    },
                    onRowEditingStopped: function (event) {
                        console.log('never called - not doing row editing')
                    },
                    onCellEditingStarted: function (event) {
                        console.log('cellEditingStarted')
                    },
                    onCellEditingStopped: function (event) {
                        console.log('cellEditingStopped')
                    }
      
                }
              }
            }
      
            onGridReady = params => {
              this.gridApi = params.api
              this.gridColumnApi = params.columnApi
          params.api.sizeColumnsToFit()
            };
      
            onCellClicked = (event) => {
                console.log('hi: ' + event.colDef.field)
                 console.log('hi type: ' + event.colDef.type)
                 if (this.props.correctedTaxonomy === null) {
                     console.log('null')
                 }
                if (this.props.correctedTaxonomy === '') {
                    console.log('empty')
                }
               if (event.colDef.field === 'value' && this.props.correctedTaxonomy !== null) {
                   var rowModel = this.gridApi.getModel()
                    var rowNode = rowModel.rowsToDisplay[event.rowIndex]
                   event.data.correctedText = this.props.correctedTaxonomy
                   rowNode.setDataValue('value', event.data.correctedText)
           }
           };
      
      
            render () {
              return (
                      <div style={{ width: '100%', height: '100%' }}>
      
                  <div
                    id='myGrid'
                    style={{
                      height: '100%',
                      width: '103%'
                    }}
                    className='ag-theme-balham'
                  >
                    <AgGridReact
                      columnDefs={this.state.columnDefs}
         //             components={this.state.components}
                      rowData={this.state.rowData}
                    gridOptions={this.state.gridOptions}
                      onGridReady={this.onGridReady}
              //      onCellClicked={this.onCellClicked.bind(this)}
                    />
                  </div>
                </div>
              )
            }
          }
      
      
          var carMappings = {
                  'Examine Document': 'Examine Document',
                  'Do not Examine': 'Do not Examine',
                  'Send on approval with Doc Exam': 'Send on approval with Doc Exam',
                  'Send on Approval Without Doc' : 'Send on Approval Without Doc ',
                  'Exam' : 'Exam'
          }
          var tenorMappings = {
            'YES': 'YES',
            'NO': 'NO'
      
          }
          function extractValues (mappings) {
            return Object.keys(mappings)
          }
          function lookupValue (mappings, key) {
            return mappings[key]
          }
          function lookupKey (mappings, name) {
            for (var key in mappings) {
              if (mappings.hasOwnProperty(key)) {
                if (name === mappings[key]) {
                  return key
                }
              }
            }
          }
      
          function getCharCodeFromEvent (event) {
              event = event || window.event
              return (typeof event.which === 'undefined') ? event.keyCode : event.which
          }
      
          function isCharNumeric (charStr) {
              return !!/\d/.test(charStr)
          }
      
          function isKeyPressedNumeric (event) {
              var charCode = getCharCodeFromEvent(event)
              var charStr = String.fromCharCode(charCode)
              return isCharNumeric(charStr)
          }
      
      
          function getDatePicker () {
              console.log('in gerDatePicker...')
                function Datepicker () {}
                Datepicker.prototype.init = function (params) {
                  this.eInput = document.createElement('input')
                  this.eInput.value = params.value
                  $(this.eInput).datepicker({ dateFormat: 'dd/mm/yy' })
                }
                Datepicker.prototype.getGui = function () {
                  return this.eInput
                }
                Datepicker.prototype.afterGuiAttached = function () {
                  this.eInput.focus()
                  this.eInput.select()
                }
                Datepicker.prototype.getValue = function () {
                  return this.eInput.value
                }
                Datepicker.prototype.destroy = function () {}
                Datepicker.prototype.isPopup = function () {
                  return false
                }
                return Datepicker
              }
      
      
      
          export default InvoiceTextFields
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-18
        • 2019-05-24
        • 1970-01-01
        • 2018-09-29
        • 2017-07-18
        • 1970-01-01
        • 2016-10-31
        • 2020-06-21
        相关资源
        最近更新 更多