Kanban templates (card, columns and swimlane) not working in Vue3

Hello all,

I am having problems with the Kanban component in Vue3 when using the templates. The problem is as follows:

I want to use templates for cards, headers and columns. I followed the documentation and I just can't get it to work.


Let's take the card template as an example. The code looks like this:

Planner.vue:


<template>
<div class='row justify-between q-col-gutter-sm'>
<div class='col-12 container'>
<ejs-kanban
ref='KanbanObj'
id='Kanban'
keyField='ScheduledId'
cssClass='kanban-header-template'
height='550px'
:dataSource='kanbanData'
:query='query'
:cardSettings='cardSettings'
:swimlaneSettings='swimlaneSettings'
enablePersistence='true'
>
<e-columns>
<e-column
v-for='workstation in workstations'
:key='workstation.keyField'
:headerText='workstation.headerText'
:keyFields='workstation.keyField'
:allowToggle='workstation.allowToggle'
:width='workstation.width'
:isExpanded='workstation.isExpanded'
>
</e-column>
</e-columns>
</ejs-kanban>
</div>
</div>
</template>
<script>
import '../../../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css'

import { apiUrlV1 } from 'src/env'

import { computed, defineComponent, onMounted, reactive, toRefs, watch } from 'vue'
import { DataManager, UrlAdaptor, Query } from '@syncfusion/ej2-data'
import { KanbanComponent, ColumnsDirective, ColumnDirective} from '@syncfusion/ej2-vue-kanban'
import { useStore } from 'vuex'
import { createApp } from 'vue/dist/vue.esm-bundler'

import KanbanCardTemplate from 'components/Planner/KanbanCardTemplate'
import SwimlaneTemplate from 'components/Planner/SwimlaneTemplate'

const app = createApp()
let cardTemplateVue = app.component('cardTemplate', KanbanCardTemplate) // 'cardTemplate' not working
let swimlaneTemplateVue = app.component('swimlaneTemplate', SwimlaneTemplate) ​// 'swimlaneTemplate' not working

const APIManager = new DataManager({
url: `${apiUrlV1}/manufacture/read?token=` + localStorage.getItem('token'),
crudUrl: `${apiUrlV1}/manufacture/update?token=` + localStorage.getItem('token'),
adaptor: new CustomAdaptor(),
crossDomain: true
})

export default defineComponent({
name: 'Planner',
props: {
isoWeek: {
type: Number,
required: true
}
},
components: {
'ejs-kanban': KanbanComponent,
'e-columns': ColumnsDirective,
'e-column': ColumnDirective
},
setup (props) {
const store = useStore()

const event = reactive({
kanbanData: APIManager,
query: null,

workstations: computed(() => { return store.getters['workstation/kanban'] }),
shift: computed(() => { return store.getters['shiftWeek/shift'] })
})

function updateView () {
let kanbanObj = document.getElementById('Kanban').ej2_instances[0]
kanbanObj.columns = event.workstations
}

function setQueryParameters () {
event.query = new Query().addParams('IsoWeek', String(props.isoWeek) || '20')
}

function setKanbanRemoteData () {
event.kanbanData = APIManager
}

function fetchData () {
setKanbanRemoteData()
setQueryParameters()
}

watch(() => event.shift, () => {
fetchData()
updateView()
})

onMounted(() => {
fetchData()
updateView()
})

return {
...toRefs(event),

swimlaneSettings: {
keyField: 'ProjectId',
enableFrozenRows: true,
template: function () {
return {
template: SwimlaneTemplateVue
}
}
},
cardSettings: {
contentField: 'ProcessingTimeTotal',
headerField: '_id',
template: function () {
return {
template: cardTemplateVue
}
}
}
}
}
})

When I define new template components via app.component('cardTemplate', KanbanCardTemplateVue), the card template is not rendered. The only way to get it to work is to define the template by changing the template name from 'cardTemplate' to 'template'. The same applies to the other templates (swimlane, columns). 

But obviously there are conflicts if all templates are declared as 'template'.


Additionally, I would like to collapse all swimlanes when the kanban control is rendered and if the containing data changes. Maybe you could also provide a solution for this.


Many thanks in advance!


Beste regards



10 Replies

VJ Vinitha Jeyakumar Syncfusion Team October 18, 2021 12:51 PM UTC

Hi Kayleezee, 
 
 
Currently, we are validating your reported query. We will update you the further details in two business days on or before 20th October 2021. 
 
Regards, 
Vinitha 



KA Kayleezee replied to Vinitha Jeyakumar October 21, 2021 01:29 PM UTC

Hi Vinitha,


I wanted to ask whether there is news on this? Many thanks in advance!


Regards



VJ Vinitha Jeyakumar Syncfusion Team October 21, 2021 02:55 PM UTC

Hi Kayleezee,  
 
 
We are working on it. We will update you the details about the issue soon. 
 
We appreciate your patience until then. 
 
Regards, 
Vinitha 



VJ Vinitha Jeyakumar Syncfusion Team October 22, 2021 02:35 PM UTC

Hi Kayleezee, 
 
 
We have validated your query “Kanban templates (card, columns and swimlane) not working in Vue3 
 
We have created a sample for your requirement to use card, column and swimlane templates for Kanban control in Vue3. Please check the code for your reference, 
 
Code snippet: 
<template> 
<div> 
<div class="col-md-12 control-section"> 
<div class="content-wrapper"> 
<ejs-kanban id="kanban" cssClass="kanban-overview" keyField="Status" :dataSource="kanbanData" 
:enableTooltip="enableTooltip" :cardSettings="cardSettings" :swimlaneSettings="swimlaneSettings" :dialogSettings="dialogSettings" :cardRendered='cardRendered'> 
<e-columns> 
<e-column headerText="To Do" keyField="Open" :allowToggle="allowToggle" :template="columnsTemplate"></e-column> 
<e-column headerText="In Progress" keyField="InProgress" :allowToggle="allowToggle" :template="columnsTemplate"></e-column> 
<e-column headerText="In Review" keyField="Review" :allowToggle="allowToggle" :template="columnsTemplate"></e-column> 
<e-column headerText="Done" keyField="Close" :allowToggle="allowToggle" :template="columnsTemplate"></e-column> 
</e-columns> 
</ejs-kanban> 
</div> 
</div> 
</div> 
</template> 
<script> 
import { extend, addClass } from "@syncfusion/ej2-base"; 
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-vue-kanban"; 
import { cardData } from "./datasource"; 
import { createApp } from "vue"; 
const app = createApp({ 
template: '<hello></hello>' 
}); 
var columnTemplate = app.component('columnsTemplate', { 
template:`<div class="header-template-wrap"> 
<div :class="getClassName(data)"></div> 
<div class="header-text">{{data.headerText}}</div> 
</div>`, 
data () { 
return { 
} 
}, 
methods: { 
getClassName: function(data) { 
return "header-icon e-icons " + data.keyField; 
} 
} 
}); 
var cardTemplate = app.component('cardRowTemplate', { 
template:`<div class="card-template"> 
<div class="e-card-header"> 
<div class="e-card-header-caption"> 
<div class="e-card-header-title e-tooltip-text">{{data.Title}}</div> 
</div> 
</div> 
<div class="e-card-content e-tooltip-text"> 
<div class="e-text">{{data.Summary}}</div> 
</div> 
<div class="e-card-custom-footer" v-html="getCardFooter(data)"></div> 
</div> 
`, 
data () { 
return { 
} 
}, 
methods: { 
getString: function(name) { 
return name.match(/\b(\w)/g).join("").toUpperCase(); 
}, 
getCardFooter: function(data) { 
let tagDiv = ""; 
let tags = data.Tags.split(","); 
for (let tag of tags) { 
tagDiv += "<div class='e-card-tag-field e-tooltip-text'>" + tag + "</div>"; 
} 
tagDiv += "<div class='e-card-avatar'>" + this.getString(data.Assignee) + "</div>"; 
return tagDiv; 
} 
} 
}); 
var rowTemplate = app.component('swimlaneRowTemplate', { 
template:`<div class='swimlane-template e-swimlane-template-table'> 
<div class="e-swimlane-row-text"> 
<span>{{data.textField}}</span></div> 
</div> 
`, 
data () { 
return { 
} 
}, 
methods: { 
image: function(data) { 
return 'source/kanban/images/' + data.keyField + '.png'; 
} 
} 
}); 
export default { 
name: "App", 
components: { 
'ejs-kanban' : KanbanComponent, 
'e-columns': ColumnsDirective, 
'e-column': ColumnDirective, 
}, 
data() { 
var swimlaneRowTemplate = function() { 
return { template: rowTemplate }; 
}; 
var cardRowTemplate = function() { 
return { template: cardTemplate }; 
}; 
return { 
kanbanData: extend([], cardData, null, true), 
allowToggle: true, 
enableTooltip: true, 
swimlaneSettings: { 
keyField: "Assignee", 
template: swimlaneRowTemplate 
}, 
cardSettings: { 
headerField: "Title", 
template: cardRowTemplate, 
selectionType: "Multiple" 
}, 
columnsTemplate: function() { 
return { template: columnTemplate }; 
}, 
dialogSettings: { 
fields: [ 
{ text: 'ID', key: 'Title', type: 'TextBox' }, 
{ key: 'Status', type: 'DropDown' }, 
{ key: 'Assignee', type: 'DropDown' }, 
{ key: 'RankId', type: 'TextBox' }, 
{ key: 'Summary', type: 'TextArea' } 
] 
} 
}; 
}, 
methods: { 
cardRendered: function (args) { 
let val = args.data.Priority; 
addClass([args.element], val); 
} 
} 
}; 
</script> 
<style> 
@import '../node_modules/@syncfusion/ej2-base/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-layouts/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-popups/styles/material.css'; 
@import '../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css'; 
</style> 
 
 
Please check the sample and code snippet and let us know if it resolves your issue. 
 
Regards, 
Vinitha 



MG Mauro Gesuitti June 13, 2022 04:44 PM UTC

The same code fails (I mean I see a blank template) on a new project started using Vite development server (that is actually the suggested environment for vue 3). Any working example with Vite?




MG Mauro Gesuitti replied to Mauro Gesuitti June 13, 2022 07:17 PM UTC

I found how to solve it, using different Vue.js instances to register the templates globally, I debugged the card template compilation step and found that it was loading the column template instead of the card template:


const columnApp = createApp();
const columnTemplate = columnApp.component("columnTemplate", ColumnTemplate);

const cardApp = createApp();
const cardTemplate = cardApp.component("cardTemplate", CardTemplate);


BS Buvana Sathasivam Syncfusion Team June 15, 2022 03:49 AM UTC

Hi Mauro,


Currently, we are validating your reported query. We will update you with further details on or before June 16, 2022.


Regards,

Buvana S



BS Buvana Sathasivam Syncfusion Team June 20, 2022 09:46 AM UTC

Hi Mauro,


Thank you for your patience.


We have created a sample using vite with the vue 3 application and provided a column, card, and swimlane template using the slot. In the below sample, we have rendered the Kanban component using slot template support instead of creating different components. Please find
the below code and sample for your reference.


App.vue

<script>

import { extend } from "@syncfusion/ej2-base";

import {

  KanbanComponent,

  ColumnsDirective,

  ColumnDirective,

} from "@syncfusion/ej2-vue-kanban";

const cardData = [

  {

    Id: "Task 1",

    Title: "Task - 29001",

    Status: "Open",

    Summary: "Analyze customer requirements.",

    Priority: "High",

    Tags: "Bug, Release Bug",

    RankId: 1,

    Assignee: "Nancy Davloio",

  },

  {

    Id: "Task 2",

    Title: "Task - 29002",

    Status: "InProgress",

    Summary: "Add responsive support to applicaton",

    Priority: "Low",

    Tags: "Story, Kanban",

    RankId: 1,

    Assignee: "Andrew Fuller",

  }

];

 

export default {

  components: {

    "ejs-kanban": KanbanComponent,

    "e-columns": ColumnsDirective,

    "e-column": ColumnDirective,

  },

  data() {

    return {

      kanbanData: extend([], cardData, null, true),

      swimlaneSettings: {

        keyField: "Assignee",

        template: "swimlaneTemplate"

      },

      cardSettings: {

        headerField: "Title",

        template: "cardsTemplate",

        selectionType: "Multiple",

      },

    };

  },

  methods: {

    getClassName: function(data) {

      return "header-icon e-icons " + data.keyField;

    },

    image: function(data) {

        return 'source/kanban/images/' + data.keyField + '.png';

      },

  },

};

</script>

 

<template>

   <ejs-kanban

    id="kanban"

    keyField="Status"

    :dataSource="kanbanData"

    :cardSettings="cardSettings"

    :swimlaneSettings="swimlaneSettings"

  >

    <e-columns>

      <e-column

        headerText="To Do"

        keyField="Open"

        :template="'columnsTemplate'">

            <template v-slot:columnsTemplate={data}>

              <div class="header-template-wrap">

                <div :class="getClassName(data)"></div>

                <div class="header-text">{{data.headerText}}</div>

              </div>

            </template>

      </e-column>

    ………….

    </e-columns>

    <template v-slot:swimlaneTemplate={data}>

      <div class='swimlane-template e-swimlane-template-table'>

        <div class="e-swimlane-row-text"><img :src="image(data)" :alt="data.keyField" />

          <span>{{data.textField}}</span>

        </div>

      </div>

    </template>

    <template v-slot:cardsTemplate={data}>

      <div class="card-template">

        <div class="e-card-header">

          <div class="e-card-header-caption">

            <div class="e-card-header-title e-tooltip-text">{{data.Title}}</div>

          </div>

        </div>

      </div>

  </template>

 </ejs-kanban>

</template>

 

<style>

@import "../node_modules/@syncfusion/ej2-base/styles/material.css";

@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";

@import "../node_modules/@syncfusion/ej2-layouts/styles/material.css";

@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";

@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";

@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";

@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";

@import "../node_modules/@syncfusion/ej2-vue-kanban/styles/material.css";

</style>


Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/ej2-vue-vite-with-kanban771028638


Please check the above code and sample and let us know if you have any further assistance.


Regards,

Buvana S



MG Mauro Gesuitti replied to Buvana Sathasivam June 22, 2022 08:06 PM UTC

Thx! the solution using v-slot was really helpful. 



BS Buvana Sathasivam Syncfusion Team June 23, 2022 09:43 AM UTC

You are welcome. Please get back to us if you need any other assistance.


Loader.
Up arrow icon