一抹阳光。 发表于 2020-5-19 16:34:26

wjimo flexgrid 单元格编辑开始创建自定义编辑器,编辑结束后根据输入的cd去DB拿数据

wj-flex-gird 中单元格编辑开始的事件,创建一个文本编辑器,把输入的code放到编辑器中,
单元格编辑结束后的事件,根据输入code去DB取数据,取到name,并通过itemSource绑到grid表里。
焦点在单元格中(编辑中)时,显示的是编辑器里的code,失去焦点(编辑结束)时,显示的是name。

KevinChen 发表于 2020-5-19 16:34:27

本帖最后由 KevinChen 于 2020-5-20 14:37 编辑

回填判断出了点问题,参考这段:

注意代码中的注释,如果需要替换获取后端数据,请在注释处获取。
<div class="blockcode"><blockquote>import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
import * as wjGrid from '@grapecity/wijmo.grid';
import * as wjInput from '@grapecity/wijmo.input';
import * as wjCore from '@grapecity/wijmo';
//
// *** CustomGridEditor class (transpiled from TypeScript) ***
//

var _toString = function(){
    return this.name;
}
var code_name_source = [
    {code: 1, name: "壹", toString:_toString},{code: 2, name: "贰", toString:_toString},{code: 3, name: "叁", toString:_toString}
    ];

export class CustomGridEditor {
    /**
   * Initializes a new instance of a CustomGridEditor.
   */
    constructor(flex, binding, edtClass, options) {
      // save references
      this._grid = flex;
      this._col = flex.columns.getColumn(binding);
      // create editor
      this._ctl = new edtClass(document.createElement('div'), options);
      // connect grid events
      flex.beginningEdit.addHandler(this._beginningEdit, this);
      flex.sortingColumn.addHandler(() => {
            this._commitRowEdits();
      });
      flex.scrollPositionChanged.addHandler(() => {
            if (this._ctl.containsFocus()) {
                flex.focus();
            }
      });
      flex.selectionChanging.addHandler((s, e) => {
            if (e.row != s.selection.row) {
                this._commitRowEdits();
            }
      });
      // connect editor events
      this._ctl.addEventListener(this._ctl.hostElement, 'keydown', (e) => {
            switch (e.keyCode) {
                case wjCore.Key.Tab:
                case wjCore.Key.Enter:
                  e.preventDefault(); // TFS 255685
                  this._closeEditor(true);
                  this._grid.focus();
                  // forward event to the grid so it will move the selection
                  var evt = document.createEvent('HTMLEvents');
                  evt.initEvent('keydown', true, true);
                  'altKey,metaKey,ctrlKey,shiftKey,keyCode'.split(',').forEach((prop) => {
                        evt = e;
                  });
                  this._grid.hostElement.dispatchEvent(evt);
                  break;
                case wjCore.Key.Escape:
                  this._closeEditor(false);
                  this._grid.focus();
                  break;
            }
      });
      // close the editor when it loses focus
      this._ctl.lostFocus.addHandler(() => {
            setTimeout(() => {
                if (!this._ctl.containsFocus()) {
                  this._closeEditor(true); // apply edits and close editor
                  this._grid.onLostFocus(); // commit item edits if the grid lost focus
                }
            });
      });
      // commit edits when grid loses focus
      this._grid.lostFocus.addHandler(() => {
            setTimeout(() => {
                if (!this._grid.containsFocus() && !CustomGridEditor._isEditing) {
                  this._commitRowEdits();
                }
            });
      });
      // open drop-down on f4/alt-down
      this._grid.addEventListener(this._grid.hostElement, 'keydown', (e) => {
            // open drop-down on f4/alt-down
            this._openDropDown = false;
            if (e.keyCode == wjCore.Key.F4 ||
                (e.altKey && (e.keyCode == wjCore.Key.Down || e.keyCode == wjCore.Key.Up))) {
                var colIndex = this._grid.selection.col;
                if (colIndex > -1 && this._grid.columns == this._col) {
                  this._openDropDown = true;
                  this._grid.startEditing(true);
                  e.preventDefault();
                }
            }
            // commit edits on Enter (in case we're at the last row, TFS 268944)
            if (e.keyCode == wjCore.Key.Enter) {
                this._commitRowEdits();
            }
      }, true);
      // close editor when user resizes the window
      // REVIEW: hides editor when soft keyboard pops up (TFS 326875)
      window.addEventListener('resize', () => {
            if (this._ctl.containsFocus()) {
                this._closeEditor(true);
                this._grid.focus();
            }
      });
    }
    // gets an instance of the control being hosted by this grid editor
    get control() {
      return this._ctl;
    }
    // handle the grid's beginningEdit event by canceling the built-in editor,
    // initializing the custom editor and giving it the focus.
    _beginningEdit(grid, args) {
      // check that this is our column
      if (grid.columns != this._col) {
            return;
      }
      // check that this is not the Delete key
      // (which is used to clear cells and should not be messed with)
      var evt = args.data;
      if (evt && evt.keyCode == wjCore.Key.Delete) {
            return;
      }
      // cancel built-in editor
      args.cancel = true;
      // save cell being edited
      this._rng = args.range;
      CustomGridEditor._isEditing = true;
      // initialize editor host
      var rcCell = grid.getCellBoundingRect(args.row, args.col), rcBody = document.body.getBoundingClientRect(), ptOffset = new wjCore.Point(-rcBody.left, -rcBody.top), zIndex = (args.row < grid.frozenRows || args.col < grid.frozenColumns) ? '3' : '';
      wjCore.setCss(this._ctl.hostElement, {
            position: 'absolute',
            left: rcCell.left - 1 + ptOffset.x,
            top: rcCell.top - 1 + ptOffset.y,
            width: rcCell.width + 1,
            height: grid.rows.renderHeight + 1,
            borderRadius: '0px',
            zIndex: zIndex,
      });
      // initialize editor content
      if (!wjCore.isUndefined(this._ctl['text'])) {
            var cell_val = grid.getCellData(this._rng.row, this._rng.col, true);
            var edit_val = null;
            code_name_source.forEach(function(item){
                if(item.name == cell_val){
                  edit_val = item.code;
                }
            });
            if(!edit_val){
                edit_val = grid.getCellData(this._rng.row, this._rng.col, true);
            }
            this._ctl['text'] = edit_val;
      }
      else {
            throw 'Can\'t set editor value/text...';
      }
      // start editing item
      var ecv = grid.editableCollectionView, item = grid.rows.dataItem;
      if (ecv && item && item != ecv.currentEditItem) {
            setTimeout(function () {
                grid.onRowEditStarting(args);
                ecv.editItem(item);
                grid.onRowEditStarted(args);
            }, 50); // wait for the grid to commit edits after losing focus
      }
      // activate editor
      document.body.appendChild(this._ctl.hostElement);
      this._ctl.focus();
      setTimeout(() => {
            // get the key that triggered the editor
            var key = (evt && evt.charCode > 32)
                ? String.fromCharCode(evt.charCode)
                : null;
            // get input element in the control
            var input = this._ctl.hostElement.querySelector('input');
            // send key to editor
            if (input) {
                if (key) {
                  input.value = key;
                  wjCore.setSelectionRange(input, key.length, key.length);
                  var evtInput = document.createEvent('HTMLEvents');
                  evtInput.initEvent('input', true, false);
                  input.dispatchEvent(evtInput);
                }
                else {
                  input.select();
                }
            }
            // give the control focus
            if (!input && !this._openDropDown) {
                this._ctl.focus();
            }
            // open drop-down on F4/alt-down
            if (this._openDropDown && this._ctl instanceof wjInput.DropDown) {
                this._ctl.isDroppedDown = true;
                this._ctl.dropDown.focus();
            }
      }, 50);
    }
    // close the custom editor, optionally saving the edits back to the grid
    _closeEditor(saveEdits) {
      if (this._rng) {
            var flexGrid = this._grid, ctl = this._ctl, host = ctl.hostElement;
            // raise grid's cellEditEnding event
            var e = new wjGrid.CellEditEndingEventArgs(flexGrid.cells, this._rng);
            flexGrid.onCellEditEnding(e);
            // save editor value into grid
            if (saveEdits) {
                if (!wjCore.isUndefined(ctl['value'])) {
                  let val = ctl['value'];
                  var setVal = null;
                  // 先从code_name_source里面找
                  code_name_source.forEach(function(item){
                        if(item.code == val){
                            setVal = item;
                        }
                  });
                  if(!setVal){
                        setVal = val;
                  }
                  this._grid.setCellData(this._rng.row, this._rng.col, setVal);
                }
                else if (!wjCore.isUndefined(ctl['text'])) {
                  let val = ctl['text'];
                  var setVal = null;
                  // 先从code_name_source里面找
                  code_name_source.forEach(function(item){
                        if(item.code == val){
                            setVal = item;
                        }
                  });
                  if(!setVal){
                        setVal = val;
                  }
                  this._grid.setCellData(this._rng.row, this._rng.col, setVal);
                }
                else {
                  throw 'Can\'t get editor value/text...';
                }
                this._grid.invalidate();
            }
            // close editor and remove it from the DOM
            if (ctl instanceof wjInput.DropDown) {
                ctl.isDroppedDown = false;
            }
            host.parentElement.removeChild(host);
            this._rng = null;
            CustomGridEditor._isEditing = false;
            // raise grid's cellEditEnded event
            flexGrid.onCellEditEnded(e);
      }
    }
    // commit row edits, fire row edit end events (TFS 339615)
    _commitRowEdits() {
      var flexGrid = this._grid, ecv = flexGrid.editableCollectionView;
      this._closeEditor(true);
      if (ecv && ecv.currentEditItem) {
            var e = new wjGrid.CellEditEndingEventArgs(flexGrid.cells, flexGrid.selection);
            ecv.commitEdit();
            setTimeout(() => {
                flexGrid.onRowEditEnding(e);
                flexGrid.onRowEditEnded(e);
                flexGrid.invalidate();
            });
      }
    }
}
//
document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
    //
    // create some random data
    var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
    var products = [
      { id: 0, name: 'Widget', unitPrice: 23.43 },
      { id: 1, name: 'Gadget', unitPrice: 12.33 },
      { id: 2, name: 'Doohickey', unitPrice: 53.07 }
    ];
    var data = [];
    var dt = new Date();
    for (var i = 0; i < 100; i++) {
      data.push({
            id: i,
            date: new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
            time: new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
            country: countries,
            product: products.name,
            amount: Math.random() * 10000 - 5000,
            discount: Math.random() / 4
      });
    }
    //
    // grid with custom editors
    var theGrid = new wjGrid.FlexGrid('#theGrid', {
      keyActionTab: 'CycleOut',
      autoGenerateColumns: false,
      itemsSource: data,
      columns: [
            { header: 'ID', binding: 'id', width: 40, isReadOnly: true },
            { header: 'Date', binding: 'date', format: 'd' },
            { header: 'Time', binding: 'time', format: 't' },
            { header: 'Country', binding: 'country' },
            { header: 'Product', binding: 'product' },
            { header: 'Amount', binding: 'amount', format: 'n2' }
      ],
    });

    /**
   * 改为AutoComplete
    */
    new CustomGridEditor(theGrid, 'country', wjInput.AutoComplete, {
      itemsSource: [],
      showDropDownButton:false
    });
}
//# sourceMappingURL=CustomGridEditor.js.map


KevinChen 发表于 2020-5-19 16:43:01

你好,您的描述很详细,这个问题需要时间来制作Demo,明天中午前给你答复。

一抹阳光。 发表于 2020-5-19 16:48:11

KevinChen 发表于 2020-5-19 16:43
你好,您的描述很详细,这个问题需要时间来制作Demo,明天中午前给你答复。

好的,谢谢

KevinChen 发表于 2020-5-20 09:17:47

不客气,中午之前给你回复。

KevinChen 发表于 2020-5-20 12:32:47

参考以下代码:

import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
import * as wjGrid from '@grapecity/wijmo.grid';
import * as wjInput from '@grapecity/wijmo.input';
import * as wjCore from '@grapecity/wijmo';
//
// *** CustomGridEditor class (transpiled from TypeScript) ***
//

var _toString = function(){
    return this.name;
}
var code_name_source = [
    {code: 1, name: "壹", toString:_toString},{code: 2, name: "贰", toString:_toString},{code: 3, name: "叁", toString:_toString}
    ];

export class CustomGridEditor {
    /**
   * Initializes a new instance of a CustomGridEditor.
   */
    constructor(flex, binding, edtClass, options) {
      // save references
      this._grid = flex;
      this._col = flex.columns.getColumn(binding);
      // create editor
      this._ctl = new edtClass(document.createElement('div'), options);
      // connect grid events
      flex.beginningEdit.addHandler(this._beginningEdit, this);
      flex.sortingColumn.addHandler(() => {
            this._commitRowEdits();
      });
      flex.scrollPositionChanged.addHandler(() => {
            if (this._ctl.containsFocus()) {
                flex.focus();
            }
      });
      flex.selectionChanging.addHandler((s, e) => {
            if (e.row != s.selection.row) {
                this._commitRowEdits();
            }
      });
      // connect editor events
      this._ctl.addEventListener(this._ctl.hostElement, 'keydown', (e) => {
            switch (e.keyCode) {
                case wjCore.Key.Tab:
                case wjCore.Key.Enter:
                  e.preventDefault(); // TFS 255685
                  this._closeEditor(true);
                  this._grid.focus();
                  // forward event to the grid so it will move the selection
                  var evt = document.createEvent('HTMLEvents');
                  evt.initEvent('keydown', true, true);
                  'altKey,metaKey,ctrlKey,shiftKey,keyCode'.split(',').forEach((prop) => {
                        evt = e;
                  });
                  this._grid.hostElement.dispatchEvent(evt);
                  break;
                case wjCore.Key.Escape:
                  this._closeEditor(false);
                  this._grid.focus();
                  break;
            }
      });
      // close the editor when it loses focus
      this._ctl.lostFocus.addHandler(() => {
            setTimeout(() => {
                if (!this._ctl.containsFocus()) {
                  this._closeEditor(true); // apply edits and close editor
                  this._grid.onLostFocus(); // commit item edits if the grid lost focus
                }
            });
      });
      // commit edits when grid loses focus
      this._grid.lostFocus.addHandler(() => {
            setTimeout(() => {
                if (!this._grid.containsFocus() && !CustomGridEditor._isEditing) {
                  this._commitRowEdits();
                }
            });
      });
      // open drop-down on f4/alt-down
      this._grid.addEventListener(this._grid.hostElement, 'keydown', (e) => {
            // open drop-down on f4/alt-down
            this._openDropDown = false;
            if (e.keyCode == wjCore.Key.F4 ||
                (e.altKey && (e.keyCode == wjCore.Key.Down || e.keyCode == wjCore.Key.Up))) {
                var colIndex = this._grid.selection.col;
                if (colIndex > -1 && this._grid.columns == this._col) {
                  this._openDropDown = true;
                  this._grid.startEditing(true);
                  e.preventDefault();
                }
            }
            // commit edits on Enter (in case we're at the last row, TFS 268944)
            if (e.keyCode == wjCore.Key.Enter) {
                this._commitRowEdits();
            }
      }, true);
      // close editor when user resizes the window
      // REVIEW: hides editor when soft keyboard pops up (TFS 326875)
      window.addEventListener('resize', () => {
            if (this._ctl.containsFocus()) {
                this._closeEditor(true);
                this._grid.focus();
            }
      });
    }
    // gets an instance of the control being hosted by this grid editor
    get control() {
      return this._ctl;
    }
    // handle the grid's beginningEdit event by canceling the built-in editor,
    // initializing the custom editor and giving it the focus.
    _beginningEdit(grid, args) {
      // check that this is our column
      if (grid.columns != this._col) {
            return;
      }
      // check that this is not the Delete key
      // (which is used to clear cells and should not be messed with)
      var evt = args.data;
      if (evt && evt.keyCode == wjCore.Key.Delete) {
            return;
      }
      // cancel built-in editor
      args.cancel = true;
      // save cell being edited
      this._rng = args.range;
      CustomGridEditor._isEditing = true;
      // initialize editor host
      var rcCell = grid.getCellBoundingRect(args.row, args.col), rcBody = document.body.getBoundingClientRect(), ptOffset = new wjCore.Point(-rcBody.left, -rcBody.top), zIndex = (args.row < grid.frozenRows || args.col < grid.frozenColumns) ? '3' : '';
      wjCore.setCss(this._ctl.hostElement, {
            position: 'absolute',
            left: rcCell.left - 1 + ptOffset.x,
            top: rcCell.top - 1 + ptOffset.y,
            width: rcCell.width + 1,
            height: grid.rows.renderHeight + 1,
            borderRadius: '0px',
            zIndex: zIndex,
      });
      // initialize editor content
      if (!wjCore.isUndefined(this._ctl['text'])) {
            var cell_val = grid.getCellData(this._rng.row, this._rng.col, true);
            if(cell_val && cell_val.code){
                // 先从code_name_source里面找
                code_name_source.forEach(function(item){
                  if(item.code == cell_val.code){
                        this._ctl['text'] = item.name;
                  }
                });
            }else{
                this._ctl['text'] = grid.getCellData(this._rng.row, this._rng.col, true);
            }
      }
      else {
            throw 'Can\'t set editor value/text...';
      }
      // start editing item
      var ecv = grid.editableCollectionView, item = grid.rows.dataItem;
      if (ecv && item && item != ecv.currentEditItem) {
            setTimeout(function () {
                grid.onRowEditStarting(args);
                ecv.editItem(item);
                grid.onRowEditStarted(args);
            }, 50); // wait for the grid to commit edits after losing focus
      }
      // activate editor
      document.body.appendChild(this._ctl.hostElement);
      this._ctl.focus();
      setTimeout(() => {
            // get the key that triggered the editor
            var key = (evt && evt.charCode > 32)
                ? String.fromCharCode(evt.charCode)
                : null;
            // get input element in the control
            var input = this._ctl.hostElement.querySelector('input');
            // send key to editor
            if (input) {
                if (key) {
                  input.value = key;
                  wjCore.setSelectionRange(input, key.length, key.length);
                  var evtInput = document.createEvent('HTMLEvents');
                  evtInput.initEvent('input', true, false);
                  input.dispatchEvent(evtInput);
                }
                else {
                  input.select();
                }
            }
            // give the control focus
            if (!input && !this._openDropDown) {
                this._ctl.focus();
            }
            // open drop-down on F4/alt-down
            if (this._openDropDown && this._ctl instanceof wjInput.DropDown) {
                this._ctl.isDroppedDown = true;
                this._ctl.dropDown.focus();
            }
      }, 50);
    }
    // close the custom editor, optionally saving the edits back to the grid
    _closeEditor(saveEdits) {
      if (this._rng) {
            var flexGrid = this._grid, ctl = this._ctl, host = ctl.hostElement;
            // raise grid's cellEditEnding event
            var e = new wjGrid.CellEditEndingEventArgs(flexGrid.cells, this._rng);
            flexGrid.onCellEditEnding(e);
            // save editor value into grid
            if (saveEdits) {
                if (!wjCore.isUndefined(ctl['value'])) {
                  let val = ctl['value'];
                  var setVal = null;
                  // 先从code_name_source里面找
                  code_name_source.forEach(function(item){
                        if(item.code == val){
                            setVal = item;
                        }
                  });
                  if(!setVal){
                        setVal = val;
                  }
                  this._grid.setCellData(this._rng.row, this._rng.col, setVal);
                }
                else if (!wjCore.isUndefined(ctl['text'])) {
                  let val = ctl['text'];
                  var setVal = null;
                  // 先从code_name_source里面找
                  code_name_source.forEach(function(item){
                        if(item.code == val){
                            setVal = item;
                        }
                  });
                  if(!setVal){
                        setVal = val;
                  }
                  this._grid.setCellData(this._rng.row, this._rng.col, setVal);
                }
                else {
                  throw 'Can\'t get editor value/text...';
                }
                this._grid.invalidate();
            }
            // close editor and remove it from the DOM
            if (ctl instanceof wjInput.DropDown) {
                ctl.isDroppedDown = false;
            }
            host.parentElement.removeChild(host);
            this._rng = null;
            CustomGridEditor._isEditing = false;
            // raise grid's cellEditEnded event
            flexGrid.onCellEditEnded(e);
      }
    }
    // commit row edits, fire row edit end events (TFS 339615)
    _commitRowEdits() {
      var flexGrid = this._grid, ecv = flexGrid.editableCollectionView;
      this._closeEditor(true);
      if (ecv && ecv.currentEditItem) {
            var e = new wjGrid.CellEditEndingEventArgs(flexGrid.cells, flexGrid.selection);
            ecv.commitEdit();
            setTimeout(() => {
                flexGrid.onRowEditEnding(e);
                flexGrid.onRowEditEnded(e);
                flexGrid.invalidate();
            });
      }
    }
}
//
document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
    //
    // create some random data
    var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
    var products = [
      { id: 0, name: 'Widget', unitPrice: 23.43 },
      { id: 1, name: 'Gadget', unitPrice: 12.33 },
      { id: 2, name: 'Doohickey', unitPrice: 53.07 }
    ];
    var data = [];
    var dt = new Date();
    for (var i = 0; i < 100; i++) {
      data.push({
            id: i,
            date: new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
            time: new Date(dt.getFullYear(), i % 12, 25, i % 24, i % 60, i % 60),
            country: countries,
            product: products.name,
            amount: Math.random() * 10000 - 5000,
            discount: Math.random() / 4
      });
    }
    //
    // grid with custom editors
    var theGrid = new wjGrid.FlexGrid('#theGrid', {
      keyActionTab: 'CycleOut',
      autoGenerateColumns: false,
      itemsSource: data,
      columns: [
            { header: 'ID', binding: 'id', width: 40, isReadOnly: true },
            { header: 'Date', binding: 'date', format: 'd' },
            { header: 'Time', binding: 'time', format: 't' },
            { header: 'Country', binding: 'country' },
            { header: 'Product', binding: 'product' },
            { header: 'Amount', binding: 'amount', format: 'n2' }
      ],
    });

    /**
   * 改为AutoComplete
    */
    new CustomGridEditor(theGrid, 'country', wjInput.AutoComplete, {
      itemsSource: [],
      showDropDownButton:false
    });
}
//# sourceMappingURL=CustomGridEditor.js.map


把在线示例的app.js替换为以上代码,在country列中输入,1、2、3可以看到效果:

https://demo.grapecity.com.cn/wijmo/demos/Grid/CustomCells/CustomEditors/purejs

一抹阳光。 发表于 2020-5-20 14:05:38

KevinChen 发表于 2020-5-20 12:32
参考以下代码:




编辑中的时候怎么显示code不显示name,编辑结束后才显示name

一抹阳光。 发表于 2020-5-20 17:49:16

KevinChen 发表于 2020-5-20 14:32
回填判断出了点问题,参考这段:

注意代码中的注释,如果需要替换获取后端数据,请在注释处获取。

已收到,谢谢

KevinChen 发表于 2020-5-20 18:13:03

不客气~
页: [1]
查看完整版本: wjimo flexgrid 单元格编辑开始创建自定义编辑器,编辑结束后根据输入的cd去DB拿数据