1
votes

Looking for some help with Tabulator (https://tabulator.info/).
I'm trying to use vue components (from Quasar) inside Tabulator cells to edit table data, but can't get it right.

I'm creating my components instance as described in this article: https://css-tricks.com/creating-vue-js-component-instances-programmatically/, then listen to events from said components and update table cell data by calling Tabulators own success() method (or cancel() to cancel editing).

Tabulator.prototype.extendModule('edit', 'editors', {
  customEditor(cell, onRendered, success, cancel, editorParams) {
    const colType = cell.getField()
    const ComponentClass = Vue.extend(
      self.compList.find(item => item.type.includes(colType)).comp
    )
    const cellValue = cell.getValue()

    self.tableInputInstance = new ComponentClass({
      propsData: {
        value: cellValue,
        indicator: false,
        autofocus: true,
        ...self.compList.find(item => item.type.includes(colType)).props
      }
    }).$mount()

    self.tableInputInstance.$on('input', e => onChange(e, 'input'))
    self.tableInputInstance.$on('change', e => onChange(e, 'change'))
    self.tableInputInstance.$on('blur', e => onChange(e, 'blur'))

    function onChange(e, evtType) {
      if (e !== cellValue) {
        success(e)
      } else {
        cancel()
      }
    }
    return self.tableInputInstance.$el
  }
})

Right now one of the issues I'm facing is that if I'm currently editing a cell and success() isn't called, I can't click another cell to make it editable / render my input component, only each second clicked cell turns editable.

enter image description here
What I want to have is a behavior exactly like in Tabulator demo here: http://tabulator.info/docs/4.6/edit#edit just with my own Vue input components. I've put up a demo app with my current setup here: https://codesandbox.io/s/tabulator-w-custom-inputs-4lr7k?file=/src/pages/Index.vue Will greatly appreciate any ideas on how to fix this!

1

1 Answers

0
votes

This is happening because you are trying to use Vue Components after Vue has parsed the DOM.

Vue will look for component tags when the DOM is first loaded, Instantiate each of the components and convert their tags into actual HTML from inside the components definition.

This only happens when the page is loaded, so when you are using a formatter and passing in a component you are just passing in standard HTML and that component tag isnt valid, therefore non of its functionality is triggered.

As far as i am aware there is no way to instantiate a component in that way after the page has loaded (i would very much love it if someone could prove me wrong on this)

Therefore any formatter that you want to set would need to use vanilla JavaScript, not a Vue component