单元格编辑

cell editor

renderer:展示数据;editor:改变数据;renderer用一个函数表示;后者有一系列的操作,需要用class来表示;

EditorManager

handsontable()--init()--EditorManage实例化

1、选择editor
columns中editor的value可以是alias,也可以是class;每个table,有自己的editor instance;
2、prepare
3、display
trigger:enter,双击,F2;会调用beginEditing
4、close
会调用finishEditing

custom editor

enchance existing editor

var PasswordEditor = Handsontable.editors.TextEditor.prototype.extend();
PasswordEditor.prototype.createElements = function(){
Handsontable.editors.TextEditor.prototype.createElements.apply(this, arguments);
this.TEXTAREA = document.createElement('input');
this.TEXTAREA.setAttribute('type', 'password');
this.TEXTAREA.className = 'handsontableInput';
this.textareaStyle = this.TEXTAREA.style;
this.textareaStyle.width = 0;
this.textareaStyle.height = 0; Handsontable.Dom.empty(this.TEXTAREA_PARENT);
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
};

BaseEditor

它是一抽象类

common method

BaseEditor已经实现的方法。如果想创建复杂的编辑器,需要override common method,应该调用原生方法。

Handsontable.editors.BaseEditor.prototype.prepare.apply(this, arguments);
prepare(row, col, prop, td, cellProperties);
beginEditing(initialValue); 内部调用open()
finishEditing(revertToOriginal, ctrlDown, callback); 内部调用saveValue(), discardEditor()
discardEditor(validationResult);
saveValue(val, ctrlDown);
isOpend()
extend()

weditor specific method

这些方法在BaseEditor中没有实现,但在其他编辑器(TextEditor)中实现了。
init() 用法:创建编辑器的html结构
geValue()
setValue(newValue)
open()
close() 隐藏editor:this.editorDiv.style.display = 'none';
focus() 选择另一个cell,但是之前的值没有验证: this.editorInput.focus();

editor常用的属性

row, col, prop(数据源是对象数组时,表示属性名), TD, cellProperties 'object'

extends an existing editor

//passwordEditor(input type='password') extends textEditor(textarea),

var PasswordEditor = Handsontable.editors.TextEditor.prototype.extend();

PasswordEditor.prototype.createElements = function () {
// Call the original createElements method
Handsontable.editors.TextEditor.prototype.createElements.apply(this, arguments); // Create password input and update relevant properties
this.TEXTAREA = document.createElement('input');
this.TEXTAREA.setAttribute('type', 'password');
this.TEXTAREA.className = 'handsontableInput';
this.textareaStyle = this.TEXTAREA.style;
this.textareaStyle.width = 0;
this.textareaStyle.height = 0; // Replace textarea with password input
Handsontable.Dom.empty(this.TEXTAREA_PARENT);
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA);
};

create editor form scratch

1、create new editor

var SelectEditor = Handsontable.editors.BaseEditor.prototype.extend();

2、select

init()在创建editor时,调用(table);prepare()--cell 不展示编辑器--和open()有时间间隔;open()--css

SelectEditor.prototype.init = function() {
// Create detached node, add CSS class and make sure its not visible
this.select = document.createElement('SELECT');
Handsontable.Dom.addClass(this.select, 'htSelectEditor');
this.select.style.display = 'none'; // Attach node to DOM, by appending it to the container holding the table
this.instance.rootElement.appendChild(this.select);
};

3、option

想要这样使用

var hot = new Handsontable(document.getElementById('container'), {
data: someData,
columns: [
{
editor: SelectEditor,
selectOptions: ['option1', 'option2', 'option3']
}
]
});

应该在那个函数中处理option?init():使用selectEditor的column,会有相同的option,肯定不行;open():要尽可能快得打开编辑器,如果option值多得话,会很耗时;所以应该放在prepare()中。

override prepare()时,需要调用BaseEditor的原生方法,因为BaseEditor.prototype.prepare()会设置很多属性,这些属性会被其他方法调用。

4、实现特定的方法

SelectEditor.prototype.getValue = function(){
return this.select.value;
};
SelectEditor.prototype.setValue = function(value){
this.seletct.value = value;
};
SelectEditor.prototype.open = function(){
//如下
};
SelectEditor.prototype.close = function(value){
//如下
};

5、override behavior

监听程序

//通过上下箭头,选择值,enter确认选择值,enter保存选择值,最后EditorManager决定什么时候关闭editor
//EditorManager有一beforeKeyDown函数,可以调用stopImmediatePropagation(),来取消默认行为。
//覆盖默认行为的操作,只是针对指定的editor,所以在open中注册监听器,在close中移除监听器,以免影响其他editor的行为
var onBeforeKeyDown = function(event){
//this 是Handsontable.Core,而不是当前的editor
var instance = this;
//获取当前editor,需要使用getActiveEditor()。返回的是最近调用prepare()的编辑器
var editor = instance.getActiveEditor();
var selectedIndex = editor.select.selectedIndex; Handsontable.Dom.enableImmediatePropagation(event);
switch(event.keyCode){
case Handsontable.helper.keyCode.ARROW_UP:
var previousOption = editor.select.options[selectedIndex-1];
if(previousOption){
editor.select.value = previousOption.value;
}
event.stopImmediatePropagation();
event.preventDefault();
break;
case Handsontable.helper.keyCode.ARROW_DOWN:
var nextOption = editor.select.options[selectedIndex+1];
if(nextOption){
editor.select.value = nextOption.value;
}
event.stopImmediatePropagation();
event.preventDefault();
break;
}
};

注册监听器:包含css变换

//open的实现基于的假设是:option的处理函数是放在prepare()中的
//展示列表之前,设定了高和最小宽,以便匹配相应的单元格,这一步可选,但是不这样做的话,editor会根据浏览器来设定大小,不太容易
//把select放在cell上面
SelectEditor.prototype.open = function(){
var width = Handsontable.Dom.outerWidth(this.TD);
var height = Handsontable.Dom.outerHeight(this.TD);
var rootOffset = Handsontable.Dom.offset(this.instance.rootElement);
var tdOffset = Handsontable.Dom.offset(this.TD);
var editorSection = this.checkEditorSection();
var cssTransformOffset; //open editor后,需要进行css调整
//cssTransformOffset和resetCssTransform
switch(editorSection){
case 'top': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.vertical.clone.wtTable.holder.parentNode);
break;
case 'left': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.horizontal.clone.wtTable.holder.parentNode);
break;
case 'corner': cssTransformOffset = Handsontable.Dom.getCssTransform(this.instance.view.wt.wtScrollbars.corner.clone.wtTable.holder.parentNode);
break;
} var selectStyle = this.select.style;
if(cssTransformOffset && cssTransformOffset !== -1){
selectStyle[cssTransformOffset[0]] = cssTransformOffset[1];
}else{
Handsontable.Dom.resetCssTransform(this.select);
} this.select.style.height = height + 'px';
this.select.style.minWidth = width + 'px';
this.select.style.top = tdOffset.top - rootOffset.top + 'px';
this.select.style.margin = '0'; this.select.style.display = ''; //register listener
this.instance.addHook('beforeKeyDown', onBeforeKeyDown); };
SelectEditor.prototype.close = function(){
this.select.style.display = 'none'; //remove listener
this.instance.removeHook('beforeKeyDown', onBeforeKeyDown);
};

检查监听器

SelectEditor.protoype.checkEditorSection = function(){
if(this.row < this.instance.getSetting().fixedRowsTop){
if(this.row < this.instance.getSetting().fixedColumnsLet){
return 'corner';
}else{
return 'top';
}
}else{
if(this.row < this.instance.getSetting().fixedColumnsLeft){
return 'left';
}
}
};

6、注册editor

//如果把别名设为select,之前已经有select的话,就会重写,如果想重写的话,可以这样做;否则,还是用一个其他别名,比如,前缀为github的账号,这样就不容易冲突了。
Handsontable.editors.registerEditor('sfp12.selcet', SelectEditor);

默认的别名和类

editor alias editor class
text Handsontable.editors.TextEditor
numeric Handsontable.editors.NumericEditor
date Handsontable.editors.DateEditor
autocomplete Handsontable.eitors.AutocompleteEditor
checkbox Handsontable.editors.CheckboxEditors
hansontable Handsontable.editors.HandsontableEditor

自定义编辑器的封装:

//放在立即执行的匿名函数中
(function(Handsontable){
var CustomEditor = Handsontable.editors.BaseEditor.prototype.extend(); // ...rest of the editor code // Put editor in dedicated namespace
//作为全局变量的一个属性(变量)
Handsontable.editors.CustomEditor = CustomEditor; // Register alias
 //别名
Handsontable.editors.registerEditor('theBestEditor', CustomEditor); })(Handsontable);

使用

//扩展自定义编辑器
var AnotherEditor = Handsontable.editors.CustomEditor.prototype.extend()
//常规使用
var hot = new Handsontable(document.getElementById('container'), {
data: someData,
columns: [
   //两种方式
{
editor: Handsontable.editors.CustomEditor
},
{
type: 'my.select'
}
]
});

handsontable-developer guide-cell editor的更多相关文章

  1. Microsoft Visual Studio 2008 未能正确加载包“Visual Web Developer HTML Source Editor Package” | “Visual Studio HTM Editor Package”

    在安装Microsoft Visual Studio 2008 后,如果Visual Studio 2008的语言版本与系统不一致时,比如:在Windows 7 English System 安装Vi ...

  2. Ehcache(2.9.x) - API Developer Guide, Key Classes and Methods

    About the Key Classes Ehcache consists of a CacheManager, which manages logical data sets represente ...

  3. Ehcache(2.9.x) - API Developer Guide, Cache Usage Patterns

    There are several common access patterns when using a cache. Ehcache supports the following patterns ...

  4. Ehcache(2.9.x) - API Developer Guide, Write-Through and Write-Behind Caches

    About Write-Through and Write-Behind Caches Write-through caching is a caching pattern where writes ...

  5. Ehcache(2.9.x) - API Developer Guide, Cache Eviction Algorithms

    About Cache Eviction Algorithms A cache eviction algorithm is a way of deciding which element to evi ...

  6. 移动端目标识别(2)——使用TENSORFLOW LITE将TENSORFLOW模型部署到移动端(SSD)之TF Lite Developer Guide

    TF Lite开发人员指南 目录: 1 选择一个模型 使用一个预训练模型 使用自己的数据集重新训练inception-V3,MovileNet 训练自己的模型 2 转换模型格式 转换tf.GraphD ...

  7. Intel® Threading Building Blocks (Intel® TBB) Developer Guide 中文 Parallelizing Data Flow and Dependence Graphs并行化data flow和依赖图

    https://www.threadingbuildingblocks.org/docs/help/index.htm Parallelizing Data Flow and Dependency G ...

  8. Ehcache(2.9.x) - API Developer Guide, Basic Caching

    Creating a CacheManager All usages of the Ehcache API start with the creation of a CacheManager. The ...

  9. Ehcache(2.9.x) - API Developer Guide, Searching a Cache

    About Searching The Search API allows you to execute arbitrarily complex queries against caches. The ...

  10. Ehcache(2.9.x) - API Developer Guide, Using Explicit Locking

    About Explicit Locking Ehcache contains an implementation which provides for explicit locking, using ...

随机推荐

  1. 遍历树节点(多层)的方法(java)

    前序遍历,后序遍历,广度遍历,深度遍历,遍历一级节点.以及按钮如何响应点击事件. import java.awt.*; import java.awt.event.*; import java.uti ...

  2. X.509证书的编码及解析:程序解析以及winhex模板解析

    一.证书的整体结构:证书内容.签名算法.签名结果. 用ASN.1语法描述如下: Certificate::=SEQUENCE{ tbsCertificate TBSCertificate, signa ...

  3. emacs之配置2,UI基本设置

    在-下建立目录emacsConfig,里面建立一些自己写的el脚本,下面是名字随便,我的 emacsConfig/ui-setting.el ;关闭Emacs的默认启动界面 (setq inhibit ...

  4. 关于 android 环信无法正确获取昵称的问题

    本案例中 username 记录成 userId了, nick 始终为空...,这是 getNick() 取得的就是 username..... 如果想自己取得自己系统的nickname则 做以下调整 ...

  5. logger5步走

    https://www.cnblogs.com/GGGGGGZX/p/9114378.html'''打印日志11/26/2017 10:44:21 PM bug 24 并写入文件example.log ...

  6. 使用word设置标题级别, 自动生成和大纲对应的多级列表, 自动生成索引目录

    作为程序员,只会开发是不够的, 在日常工作中还需要掌握一些办公软件的的操作方法,word excel ppt精通不敢, 暂且入个门吧, 在前后台开发配合过程中,能写的一手好文档将会达到事半功倍的效果, ...

  7. Java遍历一个目录下的所有文件

    Java遍历一个目录下的所有文件   Java工具中为我们提供了一个用于管理文件系统的类,这个类就是File类,File类与其他流类不同的是,流类关心的是文件的内容,而File类关心的是磁盘上文件的存 ...

  8. wampserver中php版本的升级

    以php5.3.10到5.4.31版本为例: 1.  停止WAMP服务器. 2.  去网站windows.php.net 下载php-5.4.31-Win32-VC9-x86.zip. 不要下载THE ...

  9. selenium webdriver——JS滚动到最底部

    JS控制滚动条的位置: window.scrollTo(x,y); 竖向滚动条置顶 window.scrollTo(0,0); 竖向滚动条置底 window.scrollTo(0,document.b ...

  10. ADO Connection failure

    使用ado连接,频繁报错.为何?是网络的问题吗?太灵敏了.Connection failure. 跟大文本又关系??