zoukankan      html  css  js  c++  java
  • handsontable-developer guide-cell editor

    单元格编辑

    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' } ] });
  • 相关阅读:
    Install JDK In Ubuntu
    js初学—实现checkbox全选功能
    js初学—js全自定义单选框
    poj1679The Unique MST(次小生成树模板)
    hdu3486Interviewe(二分是错的)(ST算法RMQ + 判定上下界枚举)
    poj3974 Palindrome(Manacher最长回文)
    poj1734 Sightseeing trip(Floyd求无向图最小环)
    BZOJ1123 [POI2008]BLO(割点判断 + 点双联通缩点size)
    2.2 logistic回归
    神经网络的火热
  • 原文地址:https://www.cnblogs.com/wang-jing/p/4656314.html
Copyright © 2011-2022 走看看