When using vue3 options api, how do I use template content?

here my code : DashboardLayoutView sample

//DashboardLayoutView.vue

<template>

<div class="container-fluid">

<div class="row">

<ejs-dashboardlayout id="dashboard_default" :columns="5">

<e-panels>

<e-panel

:sizeX="1"

:sizeY="1"

:row="0"

:col="0"

:content="testTemplate"

></e-panel>

<e-panel

:sizeX="3"

:sizeY="2"

:row="0"

:col="1"

content="<div class='content'>1</div>"

></e-panel>

<e-panel

:sizeX="1"

:sizeY="3"

:row="0"

:col="4"

content="<div class='content'>2</div>"

></e-panel>

<e-panel

:sizeX="1"

:sizeY="1"

:row="1"

:col="0"

content="<div class='content'>3</div>"

></e-panel>

<e-panel

:sizeX="2"

:sizeY="1"

:row="2"

:col="0"

content="<div class='content'>4</div>"

></e-panel>

<e-panel

:sizeX="1"

:sizeY="1"

:row="2"

:col="2"

content="<div class='content'>5</div>"

></e-panel>

<e-panel

:sizeX="1"

:sizeY="1"

:row="2"

:col="3"

content="<div class='content'>6</div>"

></e-panel>

</e-panels>

</ejs-dashboardlayout>

</div>

</div>

</template>


<script>

import {

DashboardLayoutComponent,

PanelsDirective,

PanelDirective,

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

import testTemplate from "./testTemplate.vue";

export default {

name: "DashboardLayoutView",

data() {

return {

headerCount: 0,

spacing: [10, 10],

testTemplate: () => {

return { template: testTemplate };   // not working

},

};

},

components: {

"ejs-dashboardlayout": DashboardLayoutComponent,

"e-panels": PanelsDirective,

"e-panel": PanelDirective,

},

methods: {},

};

</script>

<style></style>


//testTemplate.vue

<template>

<div>this is template</div>

</template>

<script>

export default {

data() {

return {};

},

};

</script>


//runtime error message

template.js:68 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'components')

    at template.js:68:64

    at template-engine.js:31:22

    at DashboardLayout2.renderTemplate (dashboard-layout.js:385:30)

    at DashboardLayout2.renderPanels (dashboard-layout.js:426:22)

    at DashboardLayout2.renderCell (dashboard-layout.js:1055:34)

    at DashboardLayout2.renderDashBoardCells (dashboard-layout.js:1139:33)

    at DashboardLayout2.initialize (dashboard-layout.js:265:18)

    at DashboardLayout2.render (dashboard-layout.js:191:14)

    at Component2.appendTo (component.js:224:18)

    at Proxy.mounted (component-base.js:94:27)

(anonymous) @ template.js:68

(anonymous) @ template-engine.js:31

DashboardLayout2.renderTemplate @ dashboard-layout.js:385

DashboardLayout2.renderPanels @ dashboard-layout.js:426

DashboardLayout2.renderCell @ dashboard-layout.js:1055

DashboardLayout2.renderDashBoardCells @ dashboard-layout.js:1139

DashboardLayout2.initialize @ dashboard-layout.js:265

DashboardLayout2.render @ dashboard-layout.js:191

Component2.appendTo @ component.js:224

mounted @ component-base.js:94

(anonymous) @ runtime-core.esm-bundler.js:2675

callWithErrorHandling @ runtime-core.esm-bundler.js:158

callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:166

hook.__weh.hook.__weh @ runtime-core.esm-bundler.js:2655

flushPostFlushCbs @ runtime-core.esm-bundler.js:325

flushJobs @ runtime-core.esm-bundler.js:363

Promise.then (async)

queueFlush @ runtime-core.esm-bundler.js:270

queueJob @ runtime-core.esm-bundler.js:264

(anonymous) @ runtime-core.esm-bundler.js:5810

triggerEffect @ reactivity.esm-bundler.js:373

triggerEffects @ reactivity.esm-bundler.js:363

triggerRefValue @ reactivity.esm-bundler.js:974

(anonymous) @ reactivity.esm-bundler.js:1135

triggerEffect @ reactivity.esm-bundler.js:373

triggerEffects @ reactivity.esm-bundler.js:358

triggerRefValue @ reactivity.esm-bundler.js:974

(anonymous) @ reactivity.esm-bundler.js:1135

triggerEffect @ reactivity.esm-bundler.js:373

triggerEffects @ reactivity.esm-bundler.js:358

triggerRefValue @ reactivity.esm-bundler.js:974

(anonymous) @ reactivity.esm-bundler.js:1135

triggerEffect @ reactivity.esm-bundler.js:373

triggerEffects @ reactivity.esm-bundler.js:358

triggerRefValue @ reactivity.esm-bundler.js:974

(anonymous) @ reactivity.esm-bundler.js:1135

triggerEffect @ reactivity.esm-bundler.js:373

triggerEffects @ reactivity.esm-bundler.js:358

triggerRefValue @ reactivity.esm-bundler.js:974

set value @ reactivity.esm-bundler.js:1018

finalizeNavigation @ vue-router.mjs:3355

(anonymous) @ vue-router.mjs:3220

Promise.then (async)

pushWithRedirect @ vue-router.mjs:3187

push @ vue-router.mjs:3112

install @ vue-router.mjs:3551

use @ runtime-core.esm-bundler.js:3752

(anonymous) @ main.js?t=1692758188952:47


thank you~


5 Replies

PM Prasanth Madhaiyan Syncfusion Team August 23, 2023 06:59 AM UTC

Hi Aim,


Greetings from Syncfusion support.


Based on the shared details, we understand that you want to set the panel content template in the Dashboard Layout component from another Vue component at your end. To fulfill your requirement, we have prepared Vue 3 Dashboard Layout sample with v-slot Template support. Here, we mapped the panel content Template from another page to the Dashboard Layout component using slot support.


Refer to the below code snippets.


[App.vue]

 

<template>

  <div>

    <div class="dashboard-api">

      <div class="content-wrapper" style="max-width:100%">

        <ejs-dashboardlayout id="api_dashboard" :columns="10" :rows="10" :allowResizing="true">

          <e-panels>

            <e-panel :row="0" :col="0" :sizeX="5" :sizeY="5" :content="'documents'">

              <template v-slot:documents>

                <HelloWorld></HelloWorld>

              </template>

            </e-panel>

            <e-panel :row="5" :col="0" :sizeX="5" :sizeY="1" header="<div>Document Data</div>"></e-panel>

            <e-panel :row="6" :col="0" :sizeX="5" :sizeY="4" header="<div>Document Preview</div>"></e-panel>

            <e-panel :row="0" :col="5" :sizeX="5" :sizeY="1" header="<div>Templates</div>"></e-panel>

            <e-panel :row="1" :col="5" :sizeX="5" :sizeY="9" header="<div>Template Editor</div>"></e-panel>

          </e-panels>

        </ejs-dashboardlayout>

      </div>

    </div>

  </div>

</template>

 

<script>

import { ref } from "vue";

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

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

import { DashboardLayoutComponent, PanelsDirective, PanelDirective } from "@syncfusion/ej2-vue-layouts";

import HelloWorld from "./components/HelloWorld.vue";

export default {

  name: "App",

  components: {

    "ejs-dashboardlayout": DashboardLayoutComponent,

    "e-panels":PanelsDirective,

    "e-panel":PanelDirective,

    "HelloWorld": HelloWorld,

  },

  setup() {

    const dashboard = ref(null);

    const spacing = ref([5,5]);

    function documents() {

      return {template: HelloWorld };

    }

    return {

      dashboard,

      spacing,

      documents,

    };

  },

};

</script>

 

 


For your reference, we have attached the documentation and sample.


Documentation: https://ej2.syncfusion.com/vue/documentation/dashboard-layout/vue-3-getting-started


Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.


Attachment: Vue3DashboardLayoutTemplate_ee5d9d5e.zip


AS aim Systems August 24, 2023 06:18 AM UTC

Thank you, your kindness

Let me ask you one more question


Referring to the page below, I would like to add Panel.

https://ej2.syncfusion.com/vue/documentation/dashboard-layout/panels/add-remove-panels



<e-panel :row="0" :col="0" :sizeX="5" :sizeY="5" :content="'documents'">

     <template v-slot:documents>

          <HelloWorld></HelloWorld>

      </template>

</e-panel>


How do I handle s-lots with scripts when adding panels?


I tried like the code below.

...

not working..


mounted() {

   const _panels = []; 

    _panels.push({

                       id: "Panel1",

                       sizeX: 1,

                       sizeY: 1,

                       row: 0,

                       col: 0,

                       content: function () {

                              return {template: HelloWorld };   //not working error..

                       },

     });

    this.add(_panels);

},

methods: {

    add(_panels) {

    const dashboardIns = this.$refs.dashboard_default.ej2Instances;

    dashboardIns.addPanel(_panels[0]);

  },

}

....

Please guide me one more time.




PM Prasanth Madhaiyan Syncfusion Team August 26, 2023 06:59 AM UTC

Hi Aim,


Based on the shared details, we understand that you want to add the panel content as a template in the Dashboard Layout component through a button click. To achieve your exact requirement, please refer to the code snippets provided below.


[App.vue]

 

<template>

  <div>

    <div class="dashboard-api">

      <div class="content-wrapper" style="max-width:100%">

        <ejs-dashboardlayout id='api_dashboard'  :columns="5" :allow-resizing="true">

            <e-panels>

              <e-panel id="Panel0" :row="0" :col="0" :sizeX="5" :sizeY="5" :content="'documents'">

                <template v-slot:documents>

                  <HelloWorld></HelloWorld>

                </template>

              </e-panel>

              <e-panel id="Panel1" :sizeX="1" :sizeY="1" :row="6" :col="0" content="<div class='content'>1</div>"></e-panel>

              <e-panel id="Panel2" :sizeX="1" :sizeY="1" :row="6" :col="1" content="<div class='content'>2</div>"></e-panel>

              <e-panel id="Panel3" :sizeX="1" :sizeY="1" :row="6" :col="2" content="<div class='content'>3</div>"></e-panel>

              <e-panel id="Panel4" :sizeX="1" :sizeY="1" :row="7" :col="0" content="<div class='content'>4</div>"></e-panel>

              <e-panel id="Panel5" :sizeX="1" :sizeY="1" :row="7" :col="1" content="<div class='content'>5</div>"></e-panel>  

              <e-panel id="Panel6" :sizeX="1" :sizeY="1" :row="7" :col="2" content="<div class='content'>6</div>"></e-panel>  

            </e-panels>

        </ejs-dashboardlayout>

      </div>

    </div>

    <div className="col-lg-4 property-section dashboard" id="api_property">

        <div className="row property-panel-content">

            <div className="card-body">

                <div className="form-group row">

                    <table id ="add">

                        <tbody>

                            <tr>

                                <td>

                                    <ejs-button id="add" class="e-primary" @click="onAdd"  >Add Panel</ejs-button>

                                </td>

                            </tr>

                        </tbody>

                    </table>

                    </div>

                </div>

            </div>

        </div>

  </div>

</template>

 

<script>

import { ref } from "vue";

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

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

import { DashboardLayoutComponent, PanelsDirective, PanelDirective } from "@syncfusion/ej2-vue-layouts";

import HelloWorld from "./components/HelloWorld.vue";

// Import syncfusion button component from buttons package

import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";

 

export default {

  name: "App",

  components: {

    "ejs-dashboardlayout": DashboardLayoutComponent,

    "e-panels":PanelsDirective,

    "e-panel":PanelDirective,

    "HelloWorld": HelloWorld,

    "ejs-button": ButtonComponent,

  },

  setup() {

    const dashboard = ref(null);

    const spacing = ref([5,5]);

    function documents() {

      return {template: HelloWorld };

    }

    function onAdd() {

            var dashboardObj = document.getElementById("api_dashboard").ej2_instances[0];

            var count = 7;

            var panel = [{

                'id': "Panel"+ count.toString(),

                'sizeX': 5,

                'sizeY': 5,

                'row': 0,

                'col': 0,

                'content': 'documents'

            }];

            count = count + 1;

            dashboardObj.addPanel(panel[0]);

        }

 

    return {

      dashboard,

      spacing,

      documents,

      onAdd,

    };

  },

};

</script>

 


For your reference, we have attached the sample. Check out the attached sample and let us know if you need any further assistance.


Regards,

Prasanth Madhaiyan.


Attachment: Vue3DashboardLayoutTemplate_5edadc5e.zip


TI Tim replied to Prasanth Madhaiyan August 1, 2024 04:15 AM UTC

This is a very helpful example.

However I think his question is when he adds a panel. He also wants to add a custom component content on it.

this function ..

function documents() {

  return { template: HelloWorld };

}


does not work with error : Uncaught (in promise) TypeError: templateElement.call is not a function

and this function

function onAdd() {

  var dashboardObj = document.getElementById("api_dashboard").ej2_instances[0];

  var count = 7;

  var panel = [{

    'id': "Panel" + count.toString(),

    'sizeX': 5,

    'sizeY': 5,

    'row': 0,

    'col': 0,

    'content': 'documents'

  }];

  count = count + 1;

  dashboardObj.addPanel(panel[0]);

}


only yields panel with the text 'documents' on it and not the component that we want to be in the content.

I too am facing this problem and want to know how can I achieve adding panels using v-slot.



LD LeoLavanya Dhanaraj Syncfusion Team September 3, 2024 04:37 AM UTC

Hi Tim,


With the shared details, we understand that you are facing an issue with adding the panel content as a template (v-slot) in the Dashboard Layout component. In our previous update, we achieved this requirement and shared a solution. We have mapped the content from another page to the Dashboard panel addition as content using slot support, and it is rendered properly; it does not display the content as a string, like “documents”. For your reference, we have included a sample. We have also handled similar requirements in the below forum, please refer to the following link:


https://www.syncfusion.com/forums/191677/dashboard-layout-dynamic-components-with-vue-vite-laravel?reply=zyyiol


Regards,

Leo Lavanya Dhanaraj


Attachment: DashboardVueLaravel_9e38f634.zip

Loader.
Up arrow icon