Grid's header click
Hi
How can I catch the event when a user clicked on a header cell and know what header was it in order to do something with it?
Thanks
SIGN IN To post a reply.
11 Replies
MS
Manivel Sellamuthu
Syncfusion Team
May 15, 2020 06:11 AM UTC
Hi Amos,
Greetings from Syncfusion support.
You can use actionBegin event of the Grid to achieve your requirement. To catch the event only while clicking the header Cell we can differentiate from other actions by requestType as sorting. Please refer the below code example and sample for more information.
|
<template>
<div id="app">
<div>
<ejs-grid ref="grid" id="grid" :dataSource="data" :allowSorting=true :actionBegin="actionBegin">
<e-columns>
<e-column
field="OrderID"
headerText="Order ID"
textAlign="Right"
:isPrimaryKey="true"
width="100"
></e-column>
<e-column field="CustomerID" headerText="Customer ID" width="120"></e-column>
<e-column field="Freight" headerText="Freight" textAlign="Right" width="120" format="C2"></e-column>
</e-columns>
</ejs-grid>
</div>
</div>
</template>
<script>
import Vue from "vue";
import { GridPlugin, Page, Sort } from "@syncfusion/ej2-vue-grids";
import { ButtonPlugin } from "@syncfusion/ej2-vue-buttons";
import {gridData} from './data'
Vue.use(ButtonPlugin);
Vue.use(GridPlugin);
export default {
data() {
return {
data: gridData
};
},
methods: {
actionBegin: function(args) {
if (args.requestType === "sorting") {
console.log(args);
// here we can catch the event while clicking the headercell
alert(args.columnName + ':' + args.direction);
}
}
},
provide: {
grid: [Page, Sort]
}
};
</script>
|
Please let us know, if you need further assistance.
Regards,
Manivel
AM
Amos
May 15, 2020 06:29 AM UTC
Thanks, actually I disabled sorting for all columns except one that requires sorting.
I guess I can use args.columnName to differentiate the column that does sorting to the rest that doesn't.
I will try your suggestion but if after my additional explanation there's another method to achieve what I wrote, please let me know.
Thanks
AM
Amos
May 15, 2020 08:29 AM UTC
As expected, I had to allow sorting again to all columns and implement your actionBegin method and distinguish the only column that needed sorting.
The problem is that sometimes the sorting + icon occurs before my intended code (router to another page).
MS
Manivel Sellamuthu
Syncfusion Team
May 18, 2020 10:42 AM UTC
Hi Amos,
Thanks for your update.
By default the Sorted data will be applied to the Grid after the dataBound event of the Grid. So please explain more about your requirement with the Grid code.
Please share the video demonstration or screenshot of the issue, to validate the issue on our end. If possible, you can try to replicate the issue in our given sample and revert us.
Regards,
Manivel
AM
Amos
May 18, 2020 11:08 AM UTC
Please see here:

The first column should be sortable and it is, see the arrow.
The rest of the columns should be "clickable" and when clicked, I want it to route to another page.
Both are working with the following code
<ejs-grid
:dataSource="matrixData"
:actionBegin="headerClicked"
gridLines="Both"
:allowSorting="true"
>
headerClicked: function(args) {
if (args.requestType == "sorting" && args.columnName != undefined && args.columnName != "column1") {
this.$store.dispatch("userData/updateMonth", { month: monthValue }); this.$router.push("/monthlyView");
}
},
The problem is, as you wrote, is that sorting also happens right before the routing, this is not my intention.
If I disable sorting for those columns, assuming only my routing will happen, then headerClicked event is not triggered.
I was hoping that there is a way to get a headerClicked event even when the column is allowSorting = false;
MS
Manivel Sellamuthu
Syncfusion Team
May 19, 2020 02:00 PM UTC
Hi Amos,
Thanks for your update.
From your explanation we can clearly understand your requirement. You can use headerTemplate for this requirement.
The first column should be sortable and it is, see the arrow.
The rest of the columns should be "clickable" and when clicked, I want it to route to another page.
From the below code example you can see that sorting has been enabled for first column and disabled for the second column. Also as per your requirement we have used headerTempalte, so the sorting disabled column will be clickable.
Please refer the below code example, sample and demo for more information.
|
<template>
<div id="app">
<ejs-grid ref="grid" :dataSource="data" :allowSorting="true" :allowPaging="true" height="273px">
<e-columns>
<e-column field="no" headerText="Sort column" textAlign="Right" width="100"></e-column>
<e-column
field="name"
:headerTemplate="cTemplate"
:allowSorting="false"
headerText="Name"
width="120"
></e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import Vue from "vue";
import {
GridPlugin,
Page,
Filter,
Sort,
Toolbar,
Edit
} from "@syncfusion/ej2-vue-grids";
import { data } from "./datasource.js";
Vue.use(GridPlugin);
export default {
data() {
return {
data: [
{ no: 1, name: "Value1" },
{ no: 2, name: "Value2" },
{ no: 3, name: "Value3" }
],
cTemplate: function() {
return {
template: Vue.component("columnTemplate", {
template: `<div v-on:click="headerclicked($event,data)" class="headertemplate" style="color:red">
Field No
</div>`,
data: function() {
return {
data: {}
};
},
computed: {},
methods: {
headerclicked: function(e, data) {
console.log(e, data);
// here you can perform your actions
alert(data.field+ " " + "Clicked");
}
}
})
};
}
};
},
provide: {
grid: [Page, Filter, Sort, Edit, Toolbar]
}
};
</script>
<style>
@import "https://cdn.syncfusion.com/ej2/material.css";
</style> |
Please let us know, if you need further assistance.
Regards,
Manivel
AM
Amos
May 20, 2020 02:01 PM UTC
Thanks,
Started to implement it but 2 questions
1. How can I show the original headerText of the column in the template (instead of field no)? I have 14 columns that needs this behavior so I will assign the same template but I want the relevant headerText to show/
2. In the headerClicked event, I need to update my store and to route somewhere else
this.$store.dispatch("userData/updateMonth", { month: monthValue });
this.$router.push("/monthlyView");
The problem: this in this context is not the root so I have no access to my $store and $router, both are undefined. How can I have access
to the outer this so I can have access to both?
Thanks
MS
Manivel Sellamuthu
Syncfusion Team
May 21, 2020 01:04 PM UTC
Hi Amos,
Thanks for your update.
- How can I show the original headerText of the column in the template (instead of field no)? I have 14 columns that needs this behavior so I will assign the same template but I want the relevant headerText to show/
You can show the headerText of the corresponding column as like the below code example inside the headerTemplate. By default headerTemplate will corresponding column details inside the data property.
|
cTemplate: function() {
return {
template: Vue.component("columnTemplate", {
template: `<div v-on:click="headerclicked($event,data).bind(this)" style="color:red" class="headertemplate">
// here we can show the headertext
{{data.headerText}}
</div>`,
data: function() {
return {
data: {}
};
},
|
2) The problem: this in this context is not the root so I have no access to my $store and $router, both are undefined. How can I have access
to the outer this so I can have access to both?
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.
Please refer the below code example and sample for more information.
|
<template>
<div id="app">
<ejs-grid
ref="grid"
:destroyed="destroyed"
:load="load"
:dataSource="data"
:allowSorting="true"
:allowPaging="true"
>
<e-columns>
<e-column field="OrderID" headerText="Order ID" width="120" textAlign="Right"></e-column>
<e-column
field="CustomerID"
:headerTemplate="cTemplate"
:allowSorting="false"
headerText="Customer Name"
width="150"
></e-column>
<e-column
field="OrderDate"
:headerTemplate="cTemplate"
:allowSorting="false"
headerText="Order Date"
width="130"
format="yMd"
textAlign="Right"
></e-column>
. . .
></e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import Vue from "vue";
import {
GridPlugin,
Page,
Filter,
Sort,
Toolbar,
Edit
} from "@syncfusion/ej2-vue-grids";
Vue.use(GridPlugin);
//initialize the eventhub
Vue.prototype.$eventHub = new Vue();
export default {
data() {
return {
data: [
. . .
],
cTemplate: function() {
return {
template: Vue.component("columnTemplate", {
template: `<div v-on:click="headerclicked($event,data).bind(this)" style="color:red" class="headertemplate">
{{data.headerText}}
</div>`,
data: function() {
return {
data: {}
};
},
computed: {},
methods: {
headerclicked: function (e, data) {
console.log(e, data);
alert("From HeaderTemplate" + data.field + " " + "Clicked");
// here emitting the values when the header is clicked
this.$eventHub.$emit("template", data);
}
}
})
};
}
};
},
methods: {
// here we can listen the values when the header is clicked
getTemplateValue: function(e) {
alert("From root" + e.field + " " + "Clicked");
//here you can perform your actions
},
load: function() {
//adding listener
this.$eventHub.$on("template", this.getTemplateValue);
},
destroyed: function() {
//removing listener
this.$eventHub.$off("template", this.getTemplateValue);
}
},
provide: {
grid: [Page, Filter, Sort, Edit, Toolbar]
}
};
</script>
<style>
@import "https://cdn.syncfusion.com/ej2/material.css";
</style>
|
Please let us know, if you need further assistance.
Regards,
Manivel
AM
Amos
May 22, 2020 11:25 PM UTC
Thank you for the tip. Before using it, a question.
My other communications are done via
this.$root.$emit(...);
I understand that this is a different context but I was hoping that they have the same root hence emitting will do the trick.
In my case, the relevant method is not triggered.
Is there a way for the components to communicate through $root.emit or eventbus is the only way in this case?
Thanks
AM
Amos
May 25, 2020 05:40 PM UTC
Your eventbuf implementation is working great.
If there is a way to implement it using this.$root.$emit(...);
Please let me know
Thanks
MS
Manivel Sellamuthu
Syncfusion Team
May 26, 2020 11:41 AM UTC
Hi Amos
Thanks for your update.
We are glad that the provided solution is working.
Unfortunately , we were unable to communicate between components in this.$root, so we suggest you to use the event bus to achieve your requirement.
Please let us know, if you need further assistance.
Regards,
Manivel
SIGN IN To post a reply.
- 11 Replies
- 2 Participants
-
AM Amos
- May 14, 2020 06:11 PM UTC
- May 26, 2020 11:41 AM UTC