We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

editTemplate on DataGrid - return custom component in function and register event

Hi

Im trying to receive a changeEvent in my parent component from my custom child component.

In my parent component I have a Grid(allowEditing=true) and a Column like this:
   <e-column field='responsible.label' headerText='Responsible' :editTemplate='editTemplate' width='100'></e-column>
The corresponding function looks like this:
editTemplate: function () {return {template: UserDropdown}
In my UserDropdown component(my custom child component) I have a <ejs-dropdownlist> with all the necessary attributes:
    <ejs-dropdownlist name="userDropdown" ref="userDropdown" v-model="userId" placeholder="Select user..." :allowFiltering='allowFiltering' :ignoreAccent='ignoreAccent'
                      :dataSource="users" :fields="fieldsUsers" :change="doCustomAction"></ejs-dropdownlist>
and:
doCustomAction: function (event) {
                console.log("UserDropdown - doCustomActin: " + event);
                this.$emit('los', event.value);
            }
Now I want to adapt the editTemplate functions return value, so that I can register a listener for the "los" event. In the template it would look like this and that works just well:
<UserDropdown v-on:los="doSomething"/>

So how do I register the event los in the editTemplate function? Is that possible?

Thanks for your time and effort
Michel








5 Replies

TS Thiyagu Subramani Syncfusion Team November 13, 2019 01:40 PM UTC

Hi Michel 

Greetings from Syncfusion support. 

We have validated your requirement “editTemplate on DataGrid - return custom component in function and register event ” at our end. 
 
We suggest to use Vue Global Event Bus concept to achieve this requirement. By default this EventBus allows us to emit an event from one component and listen for that event in another component. So we can easily communicate with two Vue components by using this EventBus concept. In the below code we have showed how to use this concept to achieve your requirement. 

[Parent component
<template> 
  <div id="app"> 
    <ejs-grid 
        . . . . 
      :actionBegin="actionBegin" . . .> 
      <e-columns> 
      . . . 
        <e-column 
          field="ShipCountry" 
          headerText="Ship Country" 
          width="150" 
          :editTemplate="editTemplate" 
        ></e-column> 
       . . . . 
      </e-columns> 
    </ejs-grid> 
  </div> 
</template> 
<script> 

import UserDropdown from "./child"; 

Vue.prototype.$eventHub = new Vue(); 
export default { 
  components: { 
    UserDropdown 
  }, 
  data() { 
    return { 
      shipCountry: "", 
      . . .  
    }; 
  }, 
  methods: { 
    editTemplate: function() { 
      return { template: UserDropdown }; 
    }, 
    actionBegin: function(args) { 
      if (args.requestType === "beginEdit") { 
        this.$eventHub.$on("ShipCountry", this.getTemplateValue); 
      } 
      if (args.requestType === "save") { 
        args.data.ShipCountry = this.shipCountry; 
      } 
    }, 
    getTemplateValue: function(e) { 
      this.shipCountry = e; 
    } 
  } 


[child component

<template> 
  <ejs-dropdownlist 
    name="userDropdown" 
    id="dropdownlist" 
    :change="doCustomAction.bind(this)" 
    :dataSource="users" 
    :fields="fieldsUsers" 
  ></ejs-dropdownlist> 
</template> 

<script> 
export default { 
  data() { 
    return { 
      name: "userDropdown", 
      data: {}, 
      users: [ 
        { Id: "1", Country: "France" }, 
         . 
         . 
        ], 
      fieldsUsers: { text: "Country", value: "Country" } 
    }; 
  }, 
  methods: { 
    doCustomAction: function(args) { 
      console.log(args.value); 
      this.$eventHub.$emit("ShipCountry", args.value); 
    } 
  } 
}; 
</script> 


For your reference we have prepared the sample with this code and you can find that sample from the below link, 

 
General link for Vue Event Bus concept:  https://alligator.io/vuejs/global-event-bus/ 
  
Please get back to us, if you need any further assistance. 
  
Regards, 
Thiyagu S. 



MP Michel Pescatore November 18, 2019 03:01 PM UTC

Hi Thiyagu S.

Thanks for answering my question. That works like a charm.

Now another question came to my mind. We are using vuex and the data we'd like to show in the dropdownbox in my UserDropdown is in the state.
The architecture of our application is quite straight-forward. I initialize the Vue instance with the store and therefore every component should have access to
the store.  That works for my Views like Events.vue. When I use UserDropdown in the html part of Events.vue, the store can be accessed by the UserDropdown.
But when I return the UserDropdown in the column of the grid like this:
editTemplate: function() { 
      return { template: UserDropdown }; 
    },

then there is an error: TypeError: "this.$store is undefined"
That doesn't make any sense. How can I get that to work?

Thanks for your time
Michel


SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team November 19, 2019 11:47 AM UTC

Hi Michel, 

Thanks for your update. 

We have validated and  prepared a simple sample as per your requirement at our end and we suspect your reported issue may occurred  in missing import store in main.js and defending way of mutation, state and getters in store.js file. 

In our sample, we have stored editTemplate dropdown’s value using Vue store concept and displayed in parent page. 

We have achieved this requirement using below reference links 



Please refer to the below code and sample link. 

[child.vue] 
 
doCustomAction: function(args) { 
      console.log(args.value); 
      this.$eventHub.$emit("ShipCountry", args.value); 
      this.$store.commit("change", args.value); 
    } 

[parent.vue
. . . . . 
<p> <b>Modified value:</b>  {{ $store.getters.Value }} </p>  // to display the stored value 
. . .  . . .  
[store.js

import Vue from "vue"; 
import Vuex from "vuex"; 

Vue.use(Vuex); 

export const store = new Vuex.Store({ 
  state: { 
    Value: "" 
  }, 
  mutations: { 
    change: function(state, value) { 
      debugger; 
      state.Value = value; 
    } 
  }, 
  getters: 
    Value: state => state.Value 
  } 
}); 


[main.js

//import store in main.js  

import { store } from "./store/store"; 

new Vue({ 
  store, 
  render: h => h(App) 
}).$mount("#app"); 



Still facing this issue please share your code block. 

Please get back to us, if you need any further assistance. 

Regards,  
Seeni Sakthi Kumar S 



MP Michel Pescatore November 19, 2019 02:37 PM UTC

Hi

Thanks for getting in touch once more.
I can get my code running following your instructions. Still I don't understand why you have to import the store once more, since it should be available in every
component...

Thanks and kind regards
Michel



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team November 20, 2019 06:48 AM UTC

Hi Michel, 

Thanks for your update. 

We have validated your query at our end. By default, there is no need to initialize store in more than once. Have to initialize the store on the main.js page is enough. 

But our case has to initialize store in userDropdown because userDropdown’s vue page is not initialized globally on the main.js page. it is created while editing the dropdown on the App page. 

Refer to the below reference sample. 


In this above sample, The App page is initialized in main.js and it consisting of two components like parent and child. if using store concept in parent and child page, no need to initialize store because it's initialized globally in via App page. 


In our sample, The App page is initialized in main.js and it's not consisting of any components. if we using the store concept in usreDropDown page (child.vue), we need to initialize the store on the child page because it is created In edit mode. (not globally) 

So only we initialized the store on the required page. 

Please get back to us, if you need any further assistance. 

Regards,  
Seeni Sakthi Kumar S 


Loader.
Live Chat Icon For mobile
Up arrow icon