How to dynamically insert a button or icon in Grid column using Vue

Hi

I’m wanting to show a clickable icon conditionally in the grid part of the gantt.

I am using Vue.js 2.6.11.

I have a template function set on a “action” column which returns html

gantt.config.columns = [			
  ...
  { name:'action',   label:'Action', width: 40, template: 
        function(task) {
          if (task.my_state === PlanStateEnum.ACTIVE) {
             return '<button class="btn btn-icon icon-workflow-complete" value="complete" onclick="buttonComplete(\'' + task.id + '\')"  style="color:LightGray">Hello</button>'
          }

However this dynamically inserted html doesn’t appear to work - I just get “hello” shown (the text content within the html I set).

I can see the output content in the Document tree (via browser console)

<div class="gantt_tree_content"><button class="btn btn-icon icon-workflow-complete" value="complete" onclick="buttonComplete('5')" style="color:LightGray">Hello</button></div>

But the html is not rendered to show the button/icon.

Is there a way to do this with Vue.js - as I expect it comes down to it’s rendering process.

I have tried something along the lines of using a vue compile approach like this but I believe this requires the tag to be in the template html at render time to be able to react to the change and with the gantt usage the gantt libary is in control of the output.

I have solved the button/icon injection problem - turns out I was not using the Vue/mdi standard icon approach for loading. The correct way is to use the <i class="mdi mdi-account"> inclusion, as:

return '<button class="btn" onclick="buttonComplete(\'' + task.id + '\')"><i class="mdi mdi-account"></i></button>'

However my follow on issue is I can’t now get buttonComplete() to resolve I get Uncaught ReferenceError: buttonComplete is not defined.

I have tried placing function in several places including:

  • in and outside class handling gantt logic
  • in Vue page/component
  • in main.js

I think this is an issue (as per original question) that the injected button isn’t really in the Vue context.

Any ideas appreciated - if you’d like me to raise this as a seperate (linked) question I’m happy to do that

I seem to have resolve the second part of this.

By placing reference to the Vue instance into the window in my main.js (as per this)

window.vm = new Vue({
  router,
  store,
  render: (h) => h(App)
}).$mount('#app')

export default window.vm

This means I can add functions to Vue within my Vue component which has the gantt element loaded

import Vue from 'vue'

Vue.prototype.buttonComplete = function(taskId) {            
  const t = gantt.getTask(taskId)
  alert(t.text)
}

And then the injected code is

return '<button class="btn" onclick="window.vm.buttonComplete(\'' + task.id + '\')"><i class="mdi mdi-account"></i></button>'

and the function gets called and can access the gantt data