js
export let customDropdownRenderer = (instance, td, row, col, prop, value, cellProperties) => {
// let selectedId
// console.log('答应optionsList', instance, td, row, col, prop, value, cellProperties)
let optionsList = cellProperties.chosenOptions.data
if (typeof optionsList === 'undefined' || typeof optionsList.length === 'undefined' || !optionsList.length) {
Handsontable.cellTypes.text.renderer(instance, td, row, col, prop, value, cellProperties)
return td
}
//
let values = (value + '').split(',')
value = []
for (var index = 0; index < optionsList.length; index++) {
if (values.indexOf(optionsList[index].id + '') > -1) {
// selectedId = optionsList[index].id
value.push(optionsList[index].label)
}
}
value = value.join(', ')
Handsontable.cellTypes.text.renderer(instance, td, row, col, prop, value, cellProperties)
// td.innerText = values
return td
}
<hot-table :settings="hotSettings" :data="hotData" ref="table">
</hot-table>
class Myselect extends TextEditor {
// const CustomEditor = Handsontable.editors.BaseEditor.prototype.extend()
// ...rest of the editor code
// console.log('触发')
// eslint-disable-next-line no-useless-constructor
constructor (props) {
super(props)
}
// let MySelectEditor = Handsontable.editors.TextEditor.prototype.extend()
prepare (row, col, prop, td, originalValue, cellProperties) {
super.prepare(row, col, prop, td, originalValue, cellProperties)
this.options = {}
console.log('答应prepare', originalValue)
if (this.cellProperties.chosenOptions) {
this.options = $.extend(this.options, cellProperties.chosenOptions)
}
this.originalValue = originalValue
cellProperties.chosenOptions = $.extend({}, cellProperties.chosenOptions)
}
createElements () {
let $ = window.$
super.createElements()
// this.$body = $(document.body)
this.TEXTAREA = document.createElement('select')
// Handsontable copy paste plugin calls this.TEXTAREA.select()
this.TEXTAREA.select = function () { }
// 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.textareaParentStyle.width = '200px'
this.TEXTAREA_PARENT.appendChild(this.TEXTAREA)
this.instance.rootElement.appendChild(this.TEXTAREA_PARENT)
let that = this
this.instance._registerTimeout(setTimeout(function () {
that.refreshDimensions()
}, 0))
}
onChosenChanged () {
let options = this.cellProperties.chosenOptions
if (!options.multiple) {
this.close()
this.finishEditing()
}
}
onChosenClosed () {
let options = this.cellProperties.chosenOptions
if (!options.multiple) {
this.close()
this.finishEditing()
} else {
}
}
onBeforeKeyDown (event) {
let instance = this
let that = instance.getActiveEditor()
let keyCodes = Handsontable.helper.KEY_CODES
let 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.tagName !== 'INPUT') {
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
}
let target = event.target
switch (event.keyCode) {
case keyCodes.ARROW_RIGHT:
if (Handsontable.dom.getCaretPosition(target) !== target.value.length) {
event.stopImmediatePropagation()
} else {
that.$textarea.trigger('chosen:close')
}
break
case keyCodes.ARROW_LEFT:
if (Handsontable.dom.getCaretPosition(target) !== 0) {
event.stopImmediatePropagation()
} else {
that.$textarea.trigger('chosen:close')
}
break
case keyCodes.ENTER:
if (that.cellProperties.chosenOptions.multiple) {
event.stopImmediatePropagation()
event.preventDefault()
event.stopPropagation()
}
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:
let txt = $(that.TEXTAREA_PARENT).find('input').val()
$(that.TEXTAREA_PARENT).find('input').val(txt.substr(0, txt.length - 1)).trigger('keyup.chosen')
event.stopImmediatePropagation()
break
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
}
}
open (keyboardEvent) {
this.refreshDimensions()
this.textareaParentStyle.display = 'block'
this.instance.addHook('beforeKeyDown', this.onBeforeKeyDown)
this.$textarea.css({
height: $(this.TD).height() + 4,
'min-width': $(this.TD).outerWidth() - 4
})
// display the list
this.$textarea.hide()
// make sure that list positions matches cell position
// this.$textarea.offset($(this.TD).offset());
let options = $.extend({}, this.options, {
width: '100%',
search_contains: true
})
if (options.multiple) {
this.$textarea.attr('multiple', true)
} else {
this.$textarea.attr('multiple', false)
}
this.$textarea.empty()
this.$textarea.append("<option value=''></option>")
let el = null
let originalValue = (this.originalValue + '').split(',')
if (options.data && options.data.length) {
for (let i = 0; i < options.data.length; i++) {
el = $('<option />')
el.attr('value', options.data[i].id)
el.html(options.data[i].label)
if (originalValue.indexOf(options.data[i].id + '') > -1) {
el.attr('selected', true)
}
this.$textarea.append(el)
}
}
if ($(this.TEXTAREA_PARENT).find('.chosen-container').length) {
this.$textarea.chosen('destroy')
}
// console.log('thishtishthsi', this)
this.$textarea.chosen(options)
let self = this
setTimeout(function () {
self.$textarea.on('change', this.onChosenChanged.bind(self))
self.$textarea.on('chosen:hiding_dropdown', this.onChosenClosed.bind(self))
self.$textarea.trigger('chosen:open')
$(self.TEXTAREA_PARENT).find('input').on('keydown', function (e) {
if (e.keyCode === Handsontable.helper.KEY_CODES.ENTER /* || e.keyCode === Handsontable.helper.KEY_CODES.BACKSPACE */) {
if ($(this).val()) {
e.preventDefault()
e.stopPropagation()
} else {
e.preventDefault()
e.stopPropagation()
self.close()
self.finishEditing()
}
}
if (e.keyCode === Handsontable.helper.KEY_CODES.BACKSPACE) {
let txt = $(self.TEXTAREA_PARENT).find('input').val()
$(self.TEXTAREA_PARENT).find('input').val(txt.substr(0, txt.length - 1)).trigger('keyup.chosen')
e.preventDefault()
e.stopPropagation()
}
if (e.keyCode === Handsontable.helper.KEY_CODES.ARROW_DOWN || e.keyCode === Handsontable.helper.KEY_CODES.ARROW_UP) {
e.preventDefault()
e.stopPropagation()
}
})
setTimeout(function () {
self.$textarea.trigger('chosen:activate').focus()
if (keyboardEvent && keyboardEvent.keyCode && Number(keyboardEvent.keyCode) !== 113) {
let key = keyboardEvent.keyCode
let keyText = (String.fromCharCode((key >= 96 && key <= 105) ? key - 48 : key)).toLowerCase()
$(self.TEXTAREA_PARENT).find('input').val(keyText).trigger('keyup.chosen')
self.$textarea.trigger('chosen:activate')
}
}, 1)
}, 1)
}
init () {
Handsontable.editors.TextEditor.prototype.init.apply(this, arguments)
}
close () {
this.instance.listen()
this.instance.removeHook('beforeKeyDown', this.onBeforeKeyDown)
this.$textarea.off()
this.$textarea.hide()
Handsontable.editors.TextEditor.prototype.close.apply(this, arguments)
}
getValue () {
if (!this.$textarea.val()) {
return ''
}
if (typeof this.$textarea.val() === 'object') {
return this.$textarea.val().join(',')
}
return this.$textarea.val()
}
// setValue(value) {
// console.log('答应setValue', value)
// this.select.value = value;
// }
focus () {
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);
}
beginEditing (initialValue) {
let onBeginEditing = this.instance.getSettings().onBeginEditing
if (onBeginEditing && onBeginEditing() === false) {
return
}
Handsontable.editors.TextEditor.prototype.beginEditing.apply(this, arguments)
}
finishEditing (isCancelled, ctrlDown) {
this.instance.listen()
return Handsontable.editors.TextEditor.prototype.finishEditing.apply(this, arguments)
}
}
{
tittle: '媒介',
editor: Myselect,
data:'fdMediaIds',
renderer: customDropdownRenderer,
chosenOptions: {
multiple: true,
data: [
{
id: '1',
label: 'NNN'
}, {
id: '2',
label: 'YYY'
}, {
id: '3',
label: 'QQQ'
}, {
id: '4',
label: 'TTT'
}
]
},
width: 150
}
代码不全 但是关键配置都在这里 需要的话可以看官方文档补全
通过修改里面的一些配置
Cell editor - Guide - Handsontable Documentation
关键的api 有
this.$refs.table.hotInstance.loadData(this.hotData) // 更新数据
let index = this.$refs.table.hotInstance.getDataAtRow(i) // 获取 行数据
this.hotSettings.columns[11].source = res.data.data this.$refs.table.hotInstance.updateSettings(this.hotSettings) // 更新setting
上面大部分覆盖了大部分场景 定制需求的话需要理解render和edit的写法 会稍微复杂点