Kendo grid sortingI - kendo-ui

I have the codes below for example:
$("#grid").kendoGrid({
dataSource: {
data: students,
pageable: false
},
scrollable: true
sortable: true,
selectable: true,
columns: [
{ field: "Name", title: "Name", width: 230},
{ field: "Sex", title: "Sex", width: 50 },
{ field: "Ca", title: "C.A." , width: 55 },
{ field: "TotolScore", title: "Totol Score", width: 100 },
{ field: "Rank", title: "Rank", width: 60 }
]
});
The codes above allows me to do sorting of columns. But I need to do extra special for the "Rank" column. What I want is when I click the column "Rank" it will sort but based on "TotalScore" value.
Is that possible?
Thanks

Yes, it is possible.
When a column is sortable, you can define a compare function and this does not have to compare the same column.
Example: Replace your Rank column definition by this...
{
field: "Rank",
title: "Rank",
width: 60,
sortable : {
compare : function (a, b) {
return a.TotolScore - b.TotolScore;
}
}
}
Here, I define a column that will show the value of Rank but I define my own compare function that is actually working on TotalScore values.
You can check compare documentation for more information.
And check a running example here: http://jsfiddle.net/OnaBai/p2tsupvx/

Related

How can I modify kendo Grid Column filter option when grid is loaded in JQuery?

How can I modify column filter option in kendo grid when grid is loaded? For example
add filter option filterable: { multi: true } or change width width: 120.
More detail, I have this code:
$("#Table").kendoGrid({
dataSource: { data },
pageSize: 30,
pageable: true,
sortable: true,
navigatable: true,
resizable: true,
groupable: true,
filterable: true,
selectable: "multiple, row",
columns:
[{ field: "ID", title: "ID", width: "20px", },
{ field: "Customer.Title", title: "Customer", width: "30px" },
{ field: "Author.Title", title: "Expert", width: "30px" },
{ field: "Body", title: "Body", width: "200px" },
{ field: "RemainderBody", title: "RemainderBody", width: "50px" },
]
}).data("kendoGrid");
I want to modify Customer filterable like filterable: { multi: true }
Going along with #NigelK and suggesting to use setOptions. Here is an example of setting an individual column to use multicheck filtering.
<div id="grid"></div>
<script>
grid = $("#grid").data("kendoGrid");
grid.setOptions({
columns: {
1: {
filterable: {
multi: true
}
}
}
});
</script>
Here is a dojo to test the code above.
You can use the setOptions method to change the grid configuration after it has been created. Check the API reference for the grid:
https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/setoptions
Note that this will destroy and recreate the grid.

kendo grid date filter not working with before and after

I'm using a kendo grid to display the data. When I filter on the date field specifying a date value (equals) then it works fine. But when I use the before or after conditions in the filter, it filters the data incorrectly.
Also sorting on the date field does not sort it properly. Any help would be greatly appreciated. FYI: I used the moment.js to format the data in dd/mm/yyyy format.
Here is the code snippet with the data:
$("#testgrid").kendoGrid({
change:onChange,
dataSource: {
data: [
{"No":"27691","ClientName":"ABC","ExpiryDate":"2015-03-14T00:00:00Z"},
{"No":"27691","Name":"DEF","ExpiryDate":"2016-03-22T00:00:00Z"},
{"No":"27691","Name":"ABC","ExpiryDate":"2015-02-28T00:00:00Z"},
{"No":"27691","Name":"ABC","ExpiryDate":"2011-07-03T00:00:00Z"},
{"No":"27691","Name":"ABC","ExpiryDate":"2015-07-31T00:00:00Z"},
{"No":"27691","Name":"ABC","ExpiryDate":null},
{"No":"27691","Name":"ABC","ExpiryDate":"2012-04-30T00:00:00Z"}
],
schema: {
model: {
fields: {
No: { type: "string" },
ExpiryDate: {
type: "date",
parse: function(inputdate) {
var dtval = moment(inputdate).format('DD/MM/YYYY');
if (dtval == "Invalid date")
return "";
else return dtval;}
},
Name: { type: "string" }
}
}
},
pageSize: 20
},
height: 550,
selectable: "single row",
allowCopy: true,
resizable: true,
groupable: true,
sortable: true,
filterable: {
mode: 'row',
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to"
}
}
},
pageable: true,
columns: [
{ field: "No", title: "Number", filterable: { cell: { showOperators: true, operator: "contains" } } , width: 150 },
{ field: "Name", title: "Name", filterable: { cell: { showOperators: true} }, width: 150 },
{ field: "ExpiryDate", title: "Expiry Date",
format: "{0:dd/MM/yyyy}", filterable: {
cell: {
template: function (args) {
args.element.kendoDatePicker({
format: "{0:dd/MM/yyyy}"
});
}
}}
, width: 150 }
]
});`
Interestingly, I've been struggling with an issue related to the filter field its self; I couldn't change the format of the date...
Your section of code for the "ExpiryDate" field helped solve my problem!
{ filterable: { cell: { template: function (args) { args.element.kendoDatePicker({ format: "{0:dd/MM/yyyy}" }); }
}}
Thought it might be useful to highlight this for others.
Removing the parse setting in the schema probably solves the sorting problem. On the filtering, perhaps the "problem" is that your dates are in UTC, but Kendo displays them in your browser's local time, and you need to deal with time.
I am in US Central Daylight Time (CDT), so 2015-03-14T00:00:00Z shows as 13/03/2015 in the grid. If I use an "equals" filter with 13/03/2015 then I get no results in the grid. Same thing - no result - with 14/03/2015. If I change the datepicker template format to dd/MM/yyyy HH:mm:ss and filter by equals 13/03/2015 19:00:00 then I get that entry, as expected.
Thus in order to use "equals" you must have (a) the time component and (b) remember the conversion of local to UTC.
Demo in Kendo Dojo

Kendo Grid Filterable cell

I have a requirement in which I have to show two dropdown list in the Filterable cell of kendo grid. These two dropdown lists would filter two different columns in the kendo grid.
One thought I had is having template which would be some kendo container like some panel probably, and then add two dropdowns to that container.
Is this even possible? If yes how to achieve this?
Here is my kendo grid definition.
ctrl.mainGridOptions = {
dataSource: ctrl.gridDataSource,
columns: [
{
title: 'Col1-Col2',
field: 'Col1',
width: 200,
template: kendo.template($("#col1").html()),
filterable: { cell: { template: ctrl.coonetemplate, showOperators: false } }
},
{
field: 'Col3',
width: 150,
title: 'Col3',
template: kendo.template($("#col3").html()),
filterable: { cell: { template: ctrl.colthreeTemplate, showOperators: false } }
}
]
}
Here is a mockup of what I want to achieve.
There are a few different parts to this.
First, if you want to have multiple filter controls for different pieces of data, you should define a column for each one. Then, put a template on the first column to have it display the data for two columns. Use the attributes option to set a colspan=2. Then, use the attributes option on the second columns to set style="display:none".
The second part is getting the dropdowns. I generally prefer to use the values option to accomplish this. The code below uses this for the OrderID column. The other alternative was the approach you were on, which is to use the cell template. The code below uses this on the ShipName column.
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function() {
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: { type: "string" },
Freight: { type: "number" },
ShipName: { type: "string" },
OrderDate: { type: "date" },
ShipCity: { type: "string" }
}
}
},
pageSize: 20,
serverPaging: true,
serverFiltering: true,
},
height: 550,
filterable: {
mode: "row"
},
pageable: true,
columns: [
{
field: "OrderID",
width: 150,
attributes: {
colspan: 2
},
values: [
{text: "10248", value: "one"},
{text:"10249", value: "two"}
],
template: '#:OrderID# (#:ShipName#)',
filterable: {
cell: {
operator: "eq",
showOperators: false
}
}
},
{
attributes: {
style: "display:none"
},
field: "ShipName",
width: 200,
title: "Ship Name",
filterable: {
cell: {
template: function(args) {
args.element.kendoDropDownList({
dataSource: args.dataSource,
dataTextField: "ShipName",
dataValueField: "ShipName",
valuePrimitive: true
});
},
operator: "eq",
showOperators: false
}
}
},
{
field: "Freight",
width: 255,
filterable: false
}]
});
});
</script>
</div>
Runnable Demo
Kendo Grid filterable cell with custom options column wise and by using this solution it also overwrites general filters settings in case specific column requirement. ASP.NET MVC C#.
columns.Bound(c => c.columnName)
.Format("{0}%")
.Filterable(ftb => ftb
.Cell(cell => cell.ShowOperators(true))
.Extra(false)
.Operators(op => op
.ForNumber(fn => fn
.Clear()
.IsEqualTo(CommonResource.GridFilter_IsEqualTo)
)
)
)
.Title("Column Name");

Event called when sorting data in kendo grid

I have the sample codes as follows:
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: getData(),
height: 550,
sortable: true,
pageable: true,
columns: [{
field: "ContactName",
title: "Contact Name",
width: 200
}, {
field: "ContactTitle",
title: "Contact Title"
}, {
field: "CompanyName",
title: "Company Name"
}]
});
function whenSorting(){
//// DO SOMETIME......
}
});
Now what I want is when I do sorting of any field the function "whenSorting" will be called. How to do that?
You have local sorting enabled "sortable: true," , for this you can capture it with databound event
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: getData(),
height: 550,
sortable: true,
pageable: true,
columns: [{
field: "ContactName",
title: "Contact Name",
width: 200
}, {
field: "ContactTitle",
title: "Contact Title"
}, {
field: "CompanyName",
title: "Company Name"
}],
dataBound: function(e) {
whenSorting();
}
});
function whenSorting(){
//// DO SOMETIME......
}
});
IF you are using server sorting you can handle it in the server read .
Hope this helps
You may bind Change function and check whether sorting exist or not on every grid change
$('#grid').data('kendoGrid').dataSource.bind('change',function(){
// Get the grid object
var grid = $("#grid").data("kendoGrid");
// Get the datasource bound to the grid
var ds = grid.dataSource;
// Get current sorting
var sort = ds.sort();
// Display sorting fields and direction
if (sort) {
for (var i = 0; i < sort.length; i++) {
alert ("Field:" + sort[i].field + " direction:" + sort[i].dir);
}
} else {
alert("no sorting");
}
});
i hope this will help you
You could define a custom sort function for each of your columns and fire your whenSorting event from there, like this:
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: getData(),
height: 550,
sortable: true,
pageable: true,
columns: [{
field: "ContactName",
title: "Contact Name",
width: 200,
sortable { compare: whenSorting }
}, {
field: "ContactTitle",
title: "Contact Title",
sortable { compare: whenSorting }
}, {
field: "CompanyName",
title: "Company Name",
sortable { compare: whenSorting }
}]
});
function whenSorting(a, b){
//// DO SOMETIME......
return a == b
? 0
: a > b
? 1
: -1;
}
});
I was using jQuery to hide columns, I was not able to use kendo's hideColumn and showColumn functions. When sorting I would end up with a column I wanted hidden showing up after the sort event was fired. I found that using the above mentioned block then writing a function using jQuery to show or hide the column worked like I intended things to.
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: getData(),
height: 550,
sortable: true,
pageable: true,
columns: [{
field: "ContactName",
title: "Contact Name",
width: 200
}, {
field: "ContactTitle",
title: "Contact Title"
}, {
field: "CompanyName",
title: "Company Name"
}],
dataBound: function(e) {
whenSorting();
}
});
function whenSorting(){
if(_checkBox.is(':checked'){
grid.find("table th").eq(4).show();
grid.children("div:eq(1)").find("table").find("tr").each(function () {
$(this).children("td:eq(4)").show();
});
}
});
Might want to check your formatting with this one too.

How to get selected row data of kendo detail grid

I am able to get the selected row in kendo grid ( master grid), But I am unable to get the selected row data in detail grid. Please provide me a code sample.
Thanks,
abhi
It is like for the main grid. Being childgrid the grid corresponding to details, do:
var row = childgrid.select();
var data = childgrid.dataItem(row);
console.log("row", row);
console.log("data", data);
Where I defined master grid as:
$("#grid").kendoGrid({
...
detailInit: detailInit,
...
});
And details grid is created using the following function when a row in master grid is expanded:
function detailInit(e) {
childgrid = $("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
},
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 5,
filter: { field: "EmployeeID", operator: "eq", value: e.data.EmployeeID }
},
scrollable: false,
sortable: false,
selectable: true,
pageable: true,
columns:
[
{ field: "OrderID", width: "70px" },
{ field: "ShipCountry", title: "Ship Country", width: "110px" },
{ field: "ShipAddress", title: "Ship Address" },
{ field: "ShipName", title: "Ship Name", width: "200px" }
]
}).data("kendoGrid");
}
Running example here : http://jsfiddle.net/OnaBai/2M86L/ (When you click on Show button, its displays in the console of your browser the selected row and its data).
Here a somewhat simpler example on how to get to the data of the clicked row: http://jsfiddle.net/Corne/AQqMH/5/
This is the code where the magic happens:
change: function (arg) {
var selectedData = this.dataItem(this.select());
// selectedData now points to the selected dataSource item!
alert("Clicked id: " + selectedData.id);
}

Resources