问题描述
我正在构建一个包含几个小的自定义项的时间表输入系统。我的问题是每一天我都需要输入两个十进制值,“小时”和“假日”。我制作了一个可以保存这些数据并通过两个 NumberTextBoxes 输入的自定义小部件,并将这个小部件设置为 dgrid 中该字段的编辑器,它在基本级别上工作。麻烦在于按 Tab 键并将焦点移到“下一个”单元格。
所需的行为是您可以单击一个单元格进行编辑并在“小时”文本框中获得焦点,选项卡应将您带到该编辑器的“假日”文本框,然后选项卡应关闭该编辑器,在下一列,然后重新开始(创建时它会自动聚焦自己的小时文本框)。
这是我为了演示问题而制作的简化版本。
require([
'dojo/_base/declare','dijit/_WidgetBase','dijit/_TemplatedMixin','dijit/_WidgetsInTemplateMixin','dijit/form/NumberTextBox','dgrid/ondemandGrid','dgrid/Editor','dgrid/Selection','dgrid/Keyboard','dgrid/extensions/DijitRegistry','dstore/Memory','dstore/Trackable','dojo/keys','dojo/on','dojo/domready!'
],function(declare,_WidgetBase,_TemplatedMixin,_WidgetsInTemplateMixin,NumberTextBox,ondemandGrid,Editor,Selection,Keyboard,DijitRegistry,Memory,Trackable,keys,on) {
/* The custom widget used as the editor */
var HoursEntry = declare([_WidgetBase,_WidgetsInTemplateMixin],{
templateString: '<div class="hours-entry">' +
' <input class="hours-textBox"' +
' data-dojo-type="dijit/form/NumberTextBox"' +
' data-dojo-props="constraints: { pattern: \'0.##\' },placeHolder: \'Hours\'"' +
' data-dojo-attach-point="hoursTextBox">' +
' <input class="holiday-textBox"' +
' data-dojo-type="dijit/form/NumberTextBox"' +
' data-dojo-props="constraints: { pattern: \'0.##\' },placeHolder: \'Holiday\'"' +
' data-dojo-attach-point="holidayTextBox">' +
'</div>',postCreate: function () {
var self = this;
// We want this HoursEntry widget to emit blur,so Editor kNows to tear us down.
function blurMe(e) {
// self.emit('blur'); doesn't seem to work despite Editor listening for on('blur')
// If the focus has moved to either textBox (e.g. tabbing from hours to holiday) then
// don't emit anything,we want to stay in edit mode for this field.
// We don't seem to be able to tell during blur if the other control being
// focussed is within this widget,so pull a timeout trick
window.setTimeout(function () {
// Are either of our textBoxes focussed still?
if (!self.hoursTextBox.focused &&
!self.holidayTextBox.focused) {
// Neither do,so consider us blurred (tears down the editor)
self._onBlur();
self.emit('focus-right');
}
},250);
}
this.own(
this.hoursTextBox.on('blur',blurMe),this.holidayTextBox.on('blur',this.hoursTextBox.on('change',function (val) {
var curVal = self.get('value');
curVal.hours = val;
self.set('value',curVal);
}),this.holidayTextBox.on('change',function (val) {
var curVal = self.get('value');
curVal.holiday = val;
self.set('value',curVal);
})
);
// Once we have been created (presumably the dgrid field is being edited),// make sure the hours textBox has focus.
this.hoursTextBox.focus();
this.inherited(arguments);
},focus: function () {
this.hoursTextBox.focus();
},_setValueAttr: function (val) {
if (!val) {
// The data object had no value at all for this field. */
this._set('value',{ hours: null,holiday: null });
} else {
this._set('value',val);
this.hoursTextBox.set('value',val.hours,false);
this.holidayTextBox.set('value',val.holiday,false);
}
},_getValueAttr: function () {
return {
hours: this.hoursTextBox.get('value'),holiday: this.holidayTextBox.get('value')
};
}
});
var GridType = declare([ondemandGrid,Editor]);
var StoreType = declare([Memory,Trackable]);
var store = new StoreType({
idProperty: 'admin_id',data: [
{
admin_id: 1,monday: { hours: 1,holiday: 11 },tuesday: { hours: 2,holiday: 22 },wednesday: { hours: 3,holiday: 33 },thursday: { hours: 4,holiday: 44 },friday: { hours: 5,holiday: 55 },saturday: { hours: 6,holiday: 66 },sunday: { hours: 7,holiday: 77 }
}
]
});
function hoursFormatter (val) {
return !val ? 'null' : (
(!val.hours ? '<span class="no-value">No hours</span>' : (val.hours + ' hours')) +
'<br>' +
(!val.holiday ? '<span class="no-value">No holiday</span>' : (val.holiday + ' holiday'))
);
}
// Create identical grid columns for the dummy data fields we have
var columns = [];
[ 'monday','tuesday','wednesday','thursday','friday','saturday','sunday' ].forEach(function (day) {
columns.push({
field: day,formatter: hoursFormatter,editor: HoursEntry,editOn: 'dgrid-cellfocusin',autoSave: true
});
});
var grid = new GridType({
collection: store,columns: columns
});
document.body.appendChild(grid.domNode);
grid.startup();
// Listen for any of the Editors to tell us we need to move our focus right.
on(grid.domNode,'focus-right',function (e) {
console.log('right!');
Keyboard.moveFocusRight.call(grid,e);
});
// This was suggested for older dgrid at https://github.com/SitePen/dgrid/issues/267 back in 2013
// grid.addKeyHandler(keys.TAB,Keyboard.moveFocusRight);
});
.hours-textBox,.holiday-textBox { width: 100%; }
<script>
window.dojoConfig = {
parSEOnLoad: false,async: true,packages: [{
name: 'dstore',location: 'https://cdn.rawgit.com/SitePen/dstore/v1.2.1'
},{
name: 'dgrid',location: '//cdn.rawgit.com/SitePen/dgrid/v0.4.2'
},{
name: 'xstyle',location:'//cdn.rawgit.com/kriszyp/xstyle/v0.3.3'
},{
name: 'put-selector',location: '//cdn.rawgit.com/kriszyp/put-selector/v0.3.6'
}]
};
</script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.12.1/dojo/dojo.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.12.1/dijit/themes/claro/claro.css" />
<style>
.hours-textBox,.holiday-textBox { width: 100%; }
</style>
<body class="claro">
<div id="select"></div>
</body>
我可能在两个方面搞砸了:
-
HoursEntry 小部件尝试管理何时对自身调用 '_onBlur',这似乎是告诉 dgrid 该小部件已模糊并且应该拆除的最佳方式。它在它的两个文本框上设置“模糊”处理程序,并在每个文本框中检测它们中的任何一个是否仍然处于焦点状态(即焦点从一个传递到另一个,因此编辑器应该保持不动)。如果两者都不是,它会调用 _onBlur,并发出一个我稍后处理的自定义事件。
-
在创建 dgrid 的地方,我监听 'focus-right' 事件,并使用 moveFocusRight 函数尝试将焦点向右移动。这似乎获得了所有正确的单元格对象等,但实际上并没有移动它。
自从我打了个结以来,我想我会伸出手来看看是否有更多经验的人可以帮助解决这个问题。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)