event generate and handle inside custom template of tree-view

Hi,
I am integrating a custom template for tree-view list. I have list of task and There are 2 icons  Edit and Delete for each row(task) inside the template component(demo) using which each task can be edited or deleted with the help of their id, for that 2 methods are written editTask and deleteTask. But when I click the icons to edit/delete no event is generated to access those methods or is there a way to handle those events in in my base component. How can I trigger those methods  inside that template. Here is the code

<template>
  <div id="app">
    <div class="control_wrapper">
        <ejs-treeview id='treeview' :fields="fields" :showCheckBox='true' :allowDragAndDrop="true" :nodeDropped="nodeDropped"  :nodeTemplate="Template" :nodeClicked='nodeclicked' :nodeSelected="nodeSelected">
        </ejs-treeview>
    </div>
  </div>
</template>

<script>

export default ({
    data () {
        var demoVue = Vue.component("demo", {
            template: `
                <div data-item-id="data.id">
                    <span class="text" >{{ data.description }}</span>
                    <span class="modify-items" style="position:absolute;right:15px;font-size:18px"> 
                        <i class="fa fa-edit mod-update" style="margin:5px;" v-on:click="editTask()"></i>
                        <i class="fa fa-trash-o mod-delete" v-on:click="deleteTask()"></i>
                        <ejs-button v-on:click="AddSubTask()>Add</ejs-button>
                    </span>
                </div>
            `,

            data() {
                return {
                    data: {},
                };
            },
            methods: {
                editTask:function() {
                    // Edit task
                    //this.$emit('open-edit-modal');
                    console.log('task edited');
                },
                destroyTask() {
                    // delete task
                },
                AddSubTask() {

                }
            }
        });
        var dataSource =  [            
            {
                'id': 1,
                'description': 'Design a nice theme',
            },
            {
                'id': 2,
                'description': 'Make the theme responsive',
            },  
            {
                'id': 3,
                'description': 'Let theme shine like a star',
            },
            {
                'id': 4,
                'description': 'Check your messages and notifications',
            }, 
            {
                'id': 5,
                'description': 'Let theme shine like a star',
            }
        ];
        return {
            fields: { dataSource: dataSource, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' },
            Template: function(e) {
                return {
                    template: demoVue
                };
            }   
        }
    },
    methods: {
        nodeSelected(args) {
            
        },
        nodeclicked: function(args) {
            
        },
        menuclick: function(args) {
            //this.$emit('open-add-modal');
        },
    }
})
</script>

Thanks


5 Replies

SP Sowmiya Padmanaban Syncfusion Team September 7, 2020 07:50 AM UTC

Hi Munna Yadav, 
 
Greetings from Syncfusion support. 
 
We have checked your reported problem that unable to trigger click events in icon inside the node template of TreeView component. By default, we have prevented the click action in node template of TreeView component. Setting pointer-events as auto for tree nodes will resolve your problem and invoke the click event, when icons within tree nodes are clicked. Refer the below code snippet. 
 
<style> 
    .e-treeview.e-fullrow-wrap .e-text-content { 
      pointer-events: auto; 
    } 
 
</style> 
 
Refer the below sample link. 
 
 
To know more about the TreeView component. Refer the below links. 
 
UG Documentation 
 
Demo link 
 
API reference 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



MY Munna Yadav September 7, 2020 08:50 AM UTC

Thanks Sowmiya.P  for such a quick reply.

I have one more doubt regarding this.  Now I can handle the event in my native template, But, Is there a way to  handle this click event of edit button in the the default component. Like, here I have made a method called "editTaskHavingId()" in my the default ejs component which i want to trigger on the click of this edit button of the template so that i can modify the data in the default ejs component.

<template>
  <div id="app">
    <div class="control_wrapper">
        <ejs-treeview id='treeview' :fields="fields" cssClass='custom' :nodeTemplate='Template'></ejs-treeview>
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import { TreeViewPlugin } from "@syncfusion/ej2-vue-navigations";
import { ButtonPlugin } from "@syncfusion/ej2-vue-buttons";


Vue.use(TreeViewPlugin);
Vue.use(ButtonPlugin);

export default {

  name: 'app',
  data () {
      var demoVue = Vue.component("demo", {
        template: `<div> <span class="text" >{{ data.name }}</span>
                    <span class="modify-items" style="position:absolute;right:15px;font-size:18px">  
                         <ejs-button id="add" class="e-btn e-info"  v-on:click.native="editTask">editTask </ejs-button>
                    </span>
                  </div>`,
        data() {
            return {
              data: {}
            };
        },
        methods: {
            editTask:function() {
                // Edit task
                this.$emit('editTaskHavingId', { Id: 1 });
                //console.log('task edited');
            },           
        }
    });
    var dataSource =  [
        { id: 1, name: 'Steven Buchanan', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/10.png', job: 'CEO', hasChild: true, expanded: true },
        { id: 2, pid: 1, name: 'Laura Callahan', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/2.png', job: 'Product Manager', hasChild: true },
        { id: 3, pid: 2, name: 'Andrew Fuller', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/7.png', job: 'Team Lead', hasChild: true },
        { id: 4, pid: 3, name: 'Anne Dodsworth', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/1.png', job: 'Developer' },
        { id: 5, pid: 1, name: 'Nancy Davolio', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/4.png', job: 'Product Manager', hasChild: true },
        { id: 6, pid: 5, name: 'Michael Suyama', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/9.png', job: 'Team Lead', hasChild: true },
        { id: 7, pid: 6, name: 'Robert King', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/8.png', job: 'Developer ' },
        { id: 8, pid: 7, name: 'Margaret Peacock', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/6.png', job: 'Developer' },
        { id: 9, pid: 1, name: 'Janet Leverling', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/3.png', job: 'HR' },
    ];
    return {
        fields: { dataSource: dataSource, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' },
        Template: function(e) {
            return {
                template: demoVue
            };
        }
    }
 }, 
 methods: {
    editTaskHavingId(obj = null) {
      console.log('object received', obj.Id);
    }
  }
}
</script>

<style>

 @import "../node_modules/@syncfusion/ej2-base/styles/material.css";
  @import "../node_modules/@syncfusion/ej2-vue-navigations/styles/material.css";
    @import "../node_modules/@syncfusion/ej2-vue-buttons/styles/material.css";
 .control_wrapper {
        display: block;
        max-width: 450px;
        max-height: 350px;
        margin: auto;
        overflow: auto;
        border: 1px solid #dddddd;
        border-radius: 3px;
    }
.e-treeview.e-fullrow-wrap .e-text-content {
  pointer-events:auto;
}
</style>


Thanks





SP Sowmiya Padmanaban Syncfusion Team September 8, 2020 09:43 AM UTC

Hi Munna Yadav,  
 
We can invoke the method between components. To achieve this, you need to define the event on mounted life cycle hook. Refer the below code snippet. 
 
var demoVue = Vue.component("demo", { 
  template: `<div> <span class="text" >{{ data.name }}</span> 
                    <span class="modify-items" style="position:absolute;right:15px;font-size:18px">   
                         <ejs-button id="add" class="e-btn e-info"  v-on:click.native="editTask">editTask </ejs-button> 
                    </span></div>`, 
  data() { 
    return { 
      data: {} 
    }; 
  }, 
  methods: { 
    editTask: function() { 
      console.log("Template event triggered"); 
      EventBus.$emit("editTaskHavingId"); 
    } 
  } 
}); 
export default { 
  data: function() { 
  mounted: function() { 
    console.log("mounted triggered"); 
    EventBus.$on("editTaskHavingId", this.editTaskHavingId); 
  }, 
  methods: { 
    editTaskHavingId: function() { 
      console.log("parent event triggered"); 
    } 
  } 
}; 
 
Refer the sample link below. 
 
 
Check out the following links which has similar requirement queries and solutions. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 



MY Munna Yadav September 15, 2020 08:33 AM UTC

Hi Sowmiya.P,

Thanks for the reply, Event Bus works for me for notifying the event.

But, When I modify/delete an element or add a new element in the datasource from the default component, it's not getting reflected in the already plotted data, how can i achieve the reactivity ?
Here is the sample code for my requirement.

<template>
  <div id="app">
    <div class="control_wrapper">
        <ejs-treeview id='treeview' :fields="fields" cssClass='custom' :nodeTemplate='Template'></ejs-treeview>
    </div>
  </div>
</template>

<script>
import Vue from 'vue';
import { TreeViewPlugin } from "@syncfusion/ej2-vue-navigations";
import { ButtonPlugin } from "@syncfusion/ej2-vue-buttons";

import Vue from 'vue';
const EventBus = new Vue();

Vue.use(TreeViewPlugin);
Vue.use(ButtonPlugin);

export default {

  name: 'app',
  data () {
      var demoVue = Vue.component("demo", {
        template: `<div> <span class="text" >{{ data.name }}</span>
                    <span class="modify-items" style="position:absolute;right:15px;font-size:18px">  
                         <ejs-button id="add" class="e-btn e-info"  v-on:click.native="editTask">editTask </ejs-button>
                         <ejs-button id="add" class="e-btn e-info"  v-on:click.native="addTask">Add Task </ejs-button>
                    </span>
                  </div>`,
        data() {
            return {
              data: {}
            };
        },
        methods: {
            editTask:function() {
                // Edit task
                EventBus.$emit('editTaskHavingId', { Id: 1 });
                //console.log('task edited');
            },
            destroyTask(taskId) {
                EventBus.$emit('destroy-task', taskId);
            },
            addTask(obj) {
                EventBus.$emit('add-task', taskId);
            }        
        }
    });
    var dataSource =  [
        { id: 1, name: 'Steven Buchanan', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/10.png', job: 'CEO', hasChild: true, expanded: true },
        { id: 2, pid: 1, name: 'Laura Callahan', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/2.png', job: 'Product Manager', hasChild: true },
        { id: 3, pid: 2, name: 'Andrew Fuller', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/7.png', job: 'Team Lead', hasChild: true },
        { id: 4, pid: 3, name: 'Anne Dodsworth', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/1.png', job: 'Developer' },
        { id: 5, pid: 1, name: 'Nancy Davolio', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/4.png', job: 'Product Manager', hasChild: true },
        { id: 6, pid: 5, name: 'Michael Suyama', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/9.png', job: 'Team Lead', hasChild: true },
        { id: 7, pid: 6, name: 'Robert King', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/8.png', job: 'Developer ' },
        { id: 8, pid: 7, name: 'Margaret Peacock', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/6.png', job: 'Developer' },
        { id: 9, pid: 1, name: 'Janet Leverling', eimg: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/3.png', job: 'HR' },
    ];
    return {
        fields: { dataSource: dataSource, id: 'id', parentID: 'pid', text: 'name', hasChildren: 'hasChild' },
        Template: function(e) {
            return {
                template: demoVue
            };
        }
    }
 }, 
 mounted() {
    EventBus.$on('add-task', addTask);
    EventBus.$on('destroy-task', deleteTask);
 },
 methods: {
    editTaskHavingId(obj = null) {
      console.log('object received', obj.Id);
    },
    deleteTask(index) {
        this.dataSource.splice(index,1);
    },
    addTask(obj) {
        this.dataSource.push(obj);
    }
  }
}
</script>

<style>

 @import "../node_modules/@syncfusion/ej2-base/styles/material.css";
  @import "../node_modules/@syncfusion/ej2-vue-navigations/styles/material.css";
    @import "../node_modules/@syncfusion/ej2-vue-buttons/styles/material.css";
 .control_wrapper {
        display: block;
        max-width: 450px;
        max-height: 350px;
        margin: auto;
        overflow: auto;
        border: 1px solid #dddddd;
        border-radius: 3px;
    }
.e-treeview.e-fullrow-wrap .e-text-content {
  pointer-events:auto;
}
</style>


SP Sowmiya Padmanaban Syncfusion Team September 16, 2020 10:08 AM UTC

Hi Munna Yadav,  
 
We have checked your attached code snippet, we found that you are updating the data to the datasource variable. We have not provided two way binding support for datasource property. To resolve this, you need to add/remove the data using addNodes and removeNodes method of TreeView component. 
 
Refer the below code snippet. 
 
  methods: { 
    editTaskHavingId: function() { 
      var treeview = document.getElementById("treeview").ej2_instances[0]; 
      treeview.addNodes([{ id: "20", name: "new_node" }], null); 
      console.log("parent event triggered"); 
    }, 
    remove_node: function(args) { 
      var treeview = document.getElementById("treeview").ej2_instances[0]; 
      treeview.removeNodes(["2"]); 
    } 
  } 
 
Please, refer the sample from the following link. 
 
 
Refer the following link to know more about the addNodes and removeNodes method. 
 
 
Please let us know, if you need any further assistance. 
 
Regards,  
Sowmiya.P 


Loader.
Up arrow icon