2017-07-19 54 views
0

我一直在閱讀關於Handsontable for Cell Editors的文檔,但我似乎無法正確創建自定義單元格編輯器。Handsontable Angular - 細胞編輯器

我在引用Select2 for Handsontable並將此腳本添加到angular-cli中,但沒有運氣。任何人有任何線索如何使這項工作?

爲的jsfiddle的代碼是:

(function (Handsontable) { 
    "use strict"; 

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

    Select2Editor.prototype.prepare = function (row, col, prop, td, originalValue, cellProperties) { 

     Handsontable.editors.TextEditor.prototype.prepare.apply(this, arguments); 

     this.options = {}; 

     if (this.cellProperties.select2Options) { 
      this.options = $.extend(this.options, cellProperties.select2Options); 
     } 
    }; 

    Select2Editor.prototype.createElements = function() { 
     this.$body = $(document.body); 

     this.TEXTAREA = document.createElement('input'); 
     this.TEXTAREA.setAttribute('type', 'text'); 
     this.$textarea = $(this.TEXTAREA); 

     Handsontable.Dom.addClass(this.TEXTAREA, 'handsontableInput'); 

     this.textareaStyle = this.TEXTAREA.style; 
     this.textareaStyle.width = 0; 
     this.textareaStyle.height = 0; 

     this.TEXTAREA_PARENT = document.createElement('DIV'); 
     Handsontable.Dom.addClass(this.TEXTAREA_PARENT, 'handsontableInputHolder'); 

     this.textareaParentStyle = this.TEXTAREA_PARENT.style; 
     this.textareaParentStyle.top = 0; 
     this.textareaParentStyle.left = 0; 
     this.textareaParentStyle.display = 'none'; 

     this.TEXTAREA_PARENT.appendChild(this.TEXTAREA); 

     this.instance.rootElement.appendChild(this.TEXTAREA_PARENT); 

     var that = this; 
     this.instance._registerTimeout(setTimeout(function() { 
      that.refreshDimensions(); 
     }, 0)); 
    }; 

    var onSelect2Changed = function() { 
     this.close(); 
     this.finishEditing(); 
    }; 
    var onSelect2Closed = function() { 
     this.close(); 
     this.finishEditing(); 
    }; 
    var onBeforeKeyDown = function (event) { 
     var instance = this; 
     var that = instance.getActiveEditor(); 

     var keyCodes = Handsontable.helper.keyCode; 
     var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; //catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) 


     //Process only events that have been fired in the editor 
     if (!$(event.target).hasClass('select2-input') || event.isImmediatePropagationStopped()) { 
      return; 
     } 
     if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) { 
      //when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea 
      event.stopImmediatePropagation(); 
      return; 
     } 

     var target = event.target; 

     switch (event.keyCode) { 
      case keyCodes.ARROW_RIGHT: 
       if (Handsontable.Dom.getCaretPosition(target) !== target.value.length) { 
        event.stopImmediatePropagation(); 
       } else { 
        that.$textarea.select2('close'); 
       } 
       break; 

      case keyCodes.ARROW_LEFT: 
       if (Handsontable.Dom.getCaretPosition(target) !== 0) { 
        event.stopImmediatePropagation(); 
       } else { 
        that.$textarea.select2('close'); 
       } 
       break; 

      case keyCodes.ENTER: 
       var selected = that.instance.getSelected(); 
       var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]); 
       if ((ctrlDown && !isMultipleSelection) || event.altKey) { //if ctrl+enter or alt+enter, add new line 
        if (that.isOpened()) { 
         that.val(that.val() + '\n'); 
         that.focus(); 
        } else { 
         that.beginEditing(that.originalValue + '\n') 
        } 
        event.stopImmediatePropagation(); 
       } 
       event.preventDefault(); //don't add newline to field 
       break; 

      case keyCodes.A: 
      case keyCodes.X: 
      case keyCodes.C: 
      case keyCodes.V: 
       if (ctrlDown) { 
        event.stopImmediatePropagation(); //CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context) 
       } 
       break; 

      case keyCodes.BACKSPACE: 
      case keyCodes.DELETE: 
      case keyCodes.HOME: 
      case keyCodes.END: 
       event.stopImmediatePropagation(); //backspace, delete, home, end should only work locally when cell is edited (not in table context) 
       break; 
     } 

    }; 

    Select2Editor.prototype.open = function() { 
     this.refreshDimensions(); 
     this.textareaParentStyle.display = 'block'; 
     this.instance.addHook('beforeKeyDown', onBeforeKeyDown); 

     this.$textarea.css({ 
      height: $(this.TD).height() + 4, 
      'min-width': $(this.TD).outerWidth() - 4 
     }); 

     //display the list 
     this.$textarea.show(); 

     //make sure that list positions matches cell position 
     // this.$textarea.offset($(this.TD).offset()); 

     var self = this; 
     this.$textarea.select2(this.options) 
      .on('change', onSelect2Changed.bind(this)) 
      .on('select2-close', onSelect2Closed.bind(this)); 

     self.$textarea.select2('open'); 
    }; 

    Select2Editor.prototype.init = function() { 
     Handsontable.editors.TextEditor.prototype.init.apply(this, arguments); 
    }; 

    Select2Editor.prototype.close = function() { 
     this.instance.listen(); 
     this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); 
     this.$textarea.off(); 
     this.$textarea.hide(); 
     Handsontable.editors.TextEditor.prototype.close.apply(this, arguments); 
    }; 

    Select2Editor.prototype.val = function (value) { 
     if (typeof value == 'undefined') { 
      return this.$textarea.val(); 
     } else { 
      this.$textarea.val(value); 
     } 
    }; 


    Select2Editor.prototype.focus = function() { 

     this.instance.listen(); 

     // DO NOT CALL THE BASE TEXTEDITOR FOCUS METHOD HERE, IT CAN MAKE THIS EDITOR BEHAVE POORLY AND HAS NO PURPOSE WITHIN THE CONTEXT OF THIS EDITOR 
     //Handsontable.editors.TextEditor.prototype.focus.apply(this, arguments); 
    }; 

    Select2Editor.prototype.beginEditing = function (initialValue) { 
     var onBeginEditing = this.instance.getSettings().onBeginEditing; 
     if (onBeginEditing && onBeginEditing() === false) { 
      return; 
     } 

     Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments); 

    }; 

    Select2Editor.prototype.finishEditing = function (isCancelled, ctrlDown) { 
     this.instance.listen(); 
     return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments); 
    }; 

    Handsontable.editors.Select2Editor = Select2Editor; 
    Handsontable.editors.registerEditor('select2', Select2Editor); 

})(Handsontable); 

我也使用ng2-handsontable爲它的分量,我想如果這是造成更多的問題或沒有?

+0

我確實意識到小提琴使用的是舊版本的handsontable和select2。我修改它是最新的,但仍然有問題。 –

回答

0

我能夠獲得select2大部分工作。

import * as Handsontable from 'handsontable'; 

export const Select2Editor = Handsontable.editors.TextEditor.prototype.extend(); 

Select2Editor.prototype.prepare = function (row, col, prop, td, originalValue, cellProperties) { 

    Handsontable.editors.TextEditor.prototype.prepare.apply(this, arguments); 

    this.options = {}; 

    if (this.cellProperties.select2Options) { 

     this.options = $.extend(this.options, cellProperties.select2Options); 
    } 
}; 

Select2Editor.prototype.createElements = function() { 
    this.$body = $(document.body); 

    this.TEXTAREA = document.createElement('select'); 
    this.$textarea = $(this.TEXTAREA); 

    Handsontable.Dom.addClass(this.TEXTAREA, 'handsontableInput'); 

    this.textareaStyle = this.TEXTAREA.style; 
    this.textareaStyle.width = 0; 
    this.textareaStyle.height = 0; 

    this.TEXTAREA_PARENT = document.createElement('DIV'); 
    Handsontable.Dom.addClass(this.TEXTAREA_PARENT, 'handsontableInputHolder'); 

    this.textareaParentStyle = this.TEXTAREA_PARENT.style; 
    this.textareaParentStyle.top = 0; 
    this.textareaParentStyle.left = 0; 
    this.textareaParentStyle.display = 'none'; 

    this.TEXTAREA_PARENT.appendChild(this.TEXTAREA); 

    this.instance.rootElement.appendChild(this.TEXTAREA_PARENT); 

    var that = this; 
    this.instance._registerTimeout(setTimeout(function() { 
     that.refreshDimensions(); 
    }, 0)); 
}; 

var onSelect2Changed = function (e) { 
    //console.log(e); 
    console.log(this.$textarea.val()); 
    // this.close(); 
    // this.finishEditing(); 
}; 
var onSelect2Closed = function() { 
    this.close(); 
    this.finishEditing(); 
}; 
var onBeforeKeyDown = function (event) { 
    var instance = this; 
    var that = instance.getActiveEditor(); 

    var keyCodes = (<any>Handsontable.helper).keyCode; 
    var ctrlDown = (event.ctrlKey || event.metaKey) && !event.altKey; //catch CTRL but not right ALT (which in some systems triggers ALT+CTRL) 


    //Process only events that have been fired in the editor 
    if (!$(event.target).hasClass('select2-input') || event.isImmediatePropagationStopped()) { 
     return; 
    } 
    if (event.keyCode === 17 || event.keyCode === 224 || event.keyCode === 91 || event.keyCode === 93) { 
     //when CTRL or its equivalent is pressed and cell is edited, don't prepare selectable text in textarea 
     event.stopImmediatePropagation(); 
     return; 
    } 

    var target = event.target; 

    switch (event.keyCode) { 
     case keyCodes.ARROW_RIGHT: 
      if ((<any>Handsontable.Dom).getCaretPosition(target) !== target.value.length) { 
       event.stopImmediatePropagation(); 
      } else { 
       that.$textarea.select2('close'); 
      } 
      break; 

     case keyCodes.ARROW_LEFT: 
      if ((<any>Handsontable.Dom).getCaretPosition(target) !== 0) { 
       event.stopImmediatePropagation(); 
      } else { 
       that.$textarea.select2('close'); 
      } 
      break; 

     case keyCodes.ENTER: 
      var selected = that.instance.getSelected(); 
      var isMultipleSelection = !(selected[0] === selected[2] && selected[1] === selected[3]); 
      if ((ctrlDown && !isMultipleSelection) || event.altKey) { //if ctrl+enter or alt+enter, add new line 
       if (that.isOpened()) { 
        that.val(that.val() + '\n'); 
        that.focus(); 
       } else { 
        that.beginEditing(that.originalValue + '\n') 
       } 
       event.stopImmediatePropagation(); 
      } 
      event.preventDefault(); //don't add newline to field 
      break; 

     case keyCodes.A: 
     case keyCodes.X: 
     case keyCodes.C: 
     case keyCodes.V: 
      if (ctrlDown) { 
       event.stopImmediatePropagation(); //CTRL+A, CTRL+C, CTRL+V, CTRL+X should only work locally when cell is edited (not in table context) 
      } 
      break; 

     case keyCodes.BACKSPACE: 
     case keyCodes.DELETE: 
     case keyCodes.HOME: 
     case keyCodes.END: 
      event.stopImmediatePropagation(); //backspace, delete, home, end should only work locally when cell is edited (not in table context) 
      break; 
    } 

}; 

Select2Editor.prototype.open = function() { 
    this.refreshDimensions(); 
    this.textareaParentStyle.display = 'block'; 
    this.instance.addHook('beforeKeyDown', onBeforeKeyDown); 

    this.$textarea.css({ 
     height: $(this.TD).height() + 4, 
     'min-width': $(this.TD).outerWidth() - 4 
    }); 

    //display the list 
    this.$textarea.show(); 

    //make sure that list positions matches cell position 
    // this.$textarea.offset($(this.TD).offset()); 

    var self = this; 
    this.$textarea.select2(this.options) 
     .on('change', onSelect2Changed.bind(this)) 
     .on('select2-close', onSelect2Closed.bind(this)); 

    self.$textarea.select2('open'); 
}; 

Select2Editor.prototype.init = function() { 
    Handsontable.editors.TextEditor.prototype.init.apply(this, arguments); 
}; 

Select2Editor.prototype.close = function() { 
    this.instance.listen(); 
    this.instance.removeHook('beforeKeyDown', onBeforeKeyDown); 
    this.$textarea.off(); 
    this.$textarea.hide(); 
    Handsontable.editors.TextEditor.prototype.close.apply(this, arguments); 
}; 

Select2Editor.prototype.val = function (value) { 
    if (typeof value == 'undefined') { 
     return this.$textarea.val(); 
    } else { 
     this.$textarea.val(value); 
    } 
}; 

Select2Editor.prototype.getValue = function() { 
    return this.$textarea.val(); 
}; 

Select2Editor.prototype.setValue = function(value) { 
    this.$textarea.val(value); 
}; 

Select2Editor.prototype.focus = function() { 

    this.instance.listen(); 

    // DO NOT CALL THE BASE TEXTEDITOR FOCUS METHOD HERE, IT CAN MAKE THIS EDITOR BEHAVE POORLY AND HAS NO PURPOSE WITHIN THE CONTEXT OF THIS EDITOR 
    //Handsontable.editors.TextEditor.prototype.focus.apply(this, arguments); 
}; 

Select2Editor.prototype.beginEditing = function (initialValue) { 
    var onBeginEditing = this.instance.getSettings().onBeginEditing; 
    if (onBeginEditing && onBeginEditing() === false) { 
     return; 
    } 

    Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments); 

}; 

Select2Editor.prototype.finishEditing = function (isCancelled, ctrlDown) { 
    this.instance.listen(); 
    return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments); 
};