Inject vue component to task text


#1

Hi, I’m trying your gantt library written in pure JS. Is there possibility to inject vue component inside columns?
I check documentation, samples, your community forum and I’m run out from ideas how to solve this.
Here is my code

  async mounted() {
    await this.fetchData()
    console.log('AFTER FETCH')
    const gantt = await this.initGantt()
    const SearchInput = Vue.extend({
      components: {
        AntInput,
        MyIcon,
      },
      data: () => {
        return {
          placeholder: this.$t('projects.searchBarPlaceholder'),
        }
      },
      methods: {
        searchProjectsQuery: () => {
          console.log('DHSIHDISH')
        },
      },
      template:
        '        <a-input\n' +
        '          size="large"\n' +
        '          type="text"\n' +
        '          allow-clear\n' +
        '          v-bind:placeholder="placeholder"\n' +
        '          @change="searchProjectsQuery"\n' +
        '        >\n' +
        '          <template slot="prefix">\n' +
        '            <MyIcon type="search" />\n' +
        '          </template>\n' +
        '        </a-input>',
    })
    const searchInputInstatnce = new SearchInput({})
    searchInputInstatnce.$mount('#search-input')

    const tasks = gantt.getTaskByTime()
    const Avatar = Vue.extend({
      components: {
        AvatarHero,
      },
      props: {
        record: {
          type: Object,
          default: () => {
            return {}
          },
        },
      },
      template:
        '        <avatar-hero\n' +
        '          slot="icon"\n' +
        '          :img-url="record.avatarUrl"\n' +
        '          :avatar-name="record.fullName"\n' +
        '        ></avatar-hero>',
    })
    tasks.forEach((task: any) => {
      if (task.type === 'person') {
        try {
          new Avatar({ propsData: { record: task } }).$mount(
            document.getElementById(task.id)
          )
        } catch (error: any) {
          console.log('ERROR', error)
        }
      }
    })

    // setTimeout(() => {
    //   console.log('REFRESHHH')
    //   gantt.refreshData()
    // }, 2500)
  }

Here is my video. These grey circles are avatar which I want to inject. They are dissapear after gantt’s rerender


#2

Hello Rafał,
In the 7.1 version, it is possible to render Vue components only inside the grid and additional task layer elements. That can be done by using the onrender function:
https://docs.dhtmlx.com/gantt/desktop__specifying_columns.html#modifyingcellsafterrendering
https://docs.dhtmlx.com/gantt/api__gantt_addtasklayer.html
Unfortunately, I don’t have a Vue.js demo. But here is a React demo, maybe, it will help you:
https://files.dhtmlx.com/30d/efb3a18eb56931812d221983d65249f2/reactive-gantt+gantt-instance+react-components+fluent-ui+7.1.9_trial.zip
The idea is simple: after Gantt renders the grid, it will call the onrender function and you can use it to tell Vue to render its components.
Here is the part of the code from the demo that you need to change to the Vue logic:

    gantt.config.columns = [
      { name: "text", label: "Task name", tree: true, width: "*" },
      { name: "start_date", label: "Start time", align: "center" },
      { name: "duration", label: "Duration", align: "center" },
      {
        name: "dropdown1", label: "dropdown 1", align: "center", width: 120,
        onrender: (item, node) => {
          return <Dropdown
          placeholder="Progress"
          options={options}
         />
        }
      },
      {
        name: "dropdown2", label: "dropdown 2", align: "center", width: 120,
        onrender: (item, node) => {
          return <Select labelId="label" id="select" value="20">
            <MenuItem value="10">Ten</MenuItem>
            <MenuItem value="20">Twenty</MenuItem>
          </Select>
        }
      },
      {name: "add"}
    ];

    gantt.config.external_render = {
      // checks the element is a React element
      isElement: (element) => {
        return React.isValidElement(element);
      },
      // renders the React element into the DOM
      renderElement: (element, container) => {
        ReactDOM.render(element, container);
      }
    };