【自定义编辑器系列】FlexGrid中怎样保存json对象格式数据,并正常显示?
在FlexGrid中,单元格中是可以保存(引用)一个json对象的,比如数据源中,我们给对应字段设置一个json对象,可以成功与FlexGrid执行绑定。但是默认情况下,绑定后的json无法正常显示,如图:
其实这是一个非常“基础”的问题,猜一下如果想让json对象显示出我们想要的内容,
应该怎么办?
对了,重写toString方法即可。
如下图所示:
但是,一旦我们更改了单元格的值,json对象就会被写入成普通的String字符串,怎么破?
OK,既然今天是【自定义编辑器系列】,那么肯定与自定义编辑器有关,如果将下拉菜单替换掉原始的input组件,
那么我们就可以在下拉菜单中回填给表格一个json对象就可以了,参考代码:
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) ***
//
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'])) {
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['selectedItem'])){
this._grid.setCellData(this._rng.row, this._rng.col, ctl['selectedItem']);
}
else if (!wjCore.isUndefined(ctl['value'])) {
this._grid.setCellData(this._rng.row, this._rng.col, ctl['value']);
}
else if (!wjCore.isUndefined(ctl['text'])) {
this._grid.setCellData(this._rng.row, this._rng.col, ctl['text']);
}
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);
console.log(flexGrid.getCellData(this._rng.row, this._rng.col));
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(',');
countries = {country:'US', continent:'North America'};
countries = {country:'Germany', continent:'Europe'};
countries = {country:'UK', continent:'Europe'};
countries = {country:'Japan', continent:'Asia'};
countries = {country:'Italy', continent:'Europe'};
countries = {country:'Greece', continent:'Europe'};
var countryToString = function(){return this.country};
countries.forEach(function(country){country.toString = countryToString;});
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' }
],
});
new CustomGridEditor(theGrid, 'country', wjInput.ComboBox, {
itemsSource: countries
});
}
//# sourceMappingURL=CustomGridEditor.js.map
以上代码在这个示例中可以看到效果(控制台中可以打印出当前修改的单元格json对象):
https://demo.grapecity.com.cn/wijmo/demos/Grid/CustomCells/CustomEditors/purejs
页:
[1]