Kendo Grid: Group by first element in a list - javascript

So I'm working with a Kendo Grid and how it's headers are grouped. One option that I have working currently is for the Grid to grab my list and sort group by checking every element in that list. So I get something like:
->Roles:
->Roles: Tester, Manager, Team Lead
->Roles: Tester
->Roles: CEO, Tester
->Roles: Team Lead, CEO
(you get the idea). This is because "Roles" in my database model are in a list (since a person can have many roles) and the Kendo Grid is comparing every element in that list. However, I want it to group by just the first element in each person's list so I instead get something like:
->Roles: Tester
->Roles: Manager
->Roles: Team Lead
->Roles:
->Roles: CEO
etc. Does anyone know how to do this? Currently I am doing
group: {
field: "RoleName",
aggregates: [
{ field: "ResourceName", aggregate: "count" },
{ field: "OrganizationName", aggregate: "count" }
]
},
And I assume that I want to be doing something more along the lines of:
group: {
field: "RoleName.get(0)",
aggregates: [
{ field: "ResourceName", aggregate: "count" },
{ field: "OrganizationName", aggregate: "count" }
]
},
However, I'm not familiar enough with Kendo Grid to know the syntax to do this correctly. Thanks in advance for all help!
Edit: I should add that because many of the people that will be using this still need IE8 support, I am using Kendo Grid imports from /2012.2.710 instead of the latest update

*Edit My Answer assumes the user loads the data outside the function and doesn't hard code in the data.
Try using the parse function in schema,
I'll just add to what you should have in your project already, for example:
$('.grid').kendoGrid({
dataSource: {
schema: {
parse: function(data) {
for (var i = 0; i < data.length; i++) {
data[i].firstWord = data[i].name.split(' ')[0];
}
return data;
}
}
group: {
field: "firstWord"
}
},
columns: [{
field: "name"
}, {
field: "firstWord",
hidden: true,
groupHeaderTemplate: "#=value#"
}]
});

This is just a fix over Ryan Hoyle answer's example:
var grid = $('#grid').kendoGrid({
dataSource: {
data: [{
name: 'Hello world'
}, {
name: 'Hello John Doe'
}, {
name: 'Hello Jane Doe'
}, {
name: 'Bye Jane Doe'
}, {
name: 'Bye World'
}],
schema: {
parse: function(data) {
data.forEach(d => d.firstWord = d.name.split(' ')[0]);
return data;
}
},
group: {
field: "firstWord"
}
},
columns: [{
field: "name"
}, {
field: "firstWord",
hidden: true,
groupHeaderTemplate: "#=value#"
}]
}).data().kendoGrid;
<link href="http://kendo.cdn.telerik.com/2016.2.607/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.607/js/kendo.all.min.js"></script>
<div id="grid"></div>

Related

How to display different column data as tool tip in ag grid pivot mode?

var ColDef = [{
headerName: "colA",
field: 'colA',
rowGroup: true
},
{
headerName: "colB",
field: 'colB',
pivot: true,
enablePivot: true
},
{
headerName: "colC",
field: 'colC',
rowGroup: true
},
{
field: 'colD',
aggFunc: 'first',
valueFormatter: currencyFormatter,
tooltip: function(params) {
return (params.valueFormatted);
},
},
{
field: 'comment'
},
{
field: 'colF'
}
];
function currencyFormatter(params) {
return params.value;
}
above code is from different question. it works but i want to use different 'comment' field as tool tip to current 'colD' . also this is a group and pivot agGrid,if it is normal grid this is not a problem. I would appreciate any ideas for group and pivot agGrid?
Not sure if there is good way for the grid to get the data in your scenario then, as your rows and columns are different than original model after pivot.
Maybe you can consider retrieve this information outside of grid. Assume you also want some aggregated information displays in the tooltip, the tooltip function may eventually look like this:
tooltip: params => {
const country = params.node.key;
const year = params.colDef.pivotKeys[0];
const athletesWithNumbers = this.state.rowData
.filter(d => d.year == year)
.filter(d => d.country === country)
.filter(d => d.gold > 0)
.map(d => d.athlete + ': ' + d.gold);
return athletesWithNumbers.join(', ');
}
See this plunker for what I am talking about - again, not sure if this is what you want but just an FYI.
just use tooltipValueGetter
{
field: 'message',
headerName: 'Message',
headerTooltip: 'Message',
width: 110,
filter: 'agSetColumnFilter',
tooltipValueGetter: (params) => `${params.value} some text`
}
or just use the same method for tooltipValueGetter
UPDATE:
Okay, I understood
but it also easy
Ag-grid has property tooltipField - where you can choose any field from grid
For example here - in the column of 'sport' I am showing tooltip of the previous column
Example: https://plnkr.co/edit/zNbMPT5HOB9yqI08
OR
You can easily manipulate with data for each field by tooltipValueGetter
with next construction:
tooltipValueGetter: function(params) {
return `Country: ${params.data.country}, Athlete: ${params.data.athlete}, Sport: ${params.data.sport}`;
},
Example: https://plnkr.co/edit/zNbMPT5HOB9yqI08
Result:
UPDATE 2
Hey Man! I do not understand was is wrong
I just used your code snippet and my solution
And it works as you want
Example: https://plnkr.co/edit/zNbMPT5HOB9yqI08
UPDATE 3
A little bit of manipulation and I can get the data
{ field: 'gold', aggFunc: 'sum',
tooltipValueGetter: function(params) {
var model = params.api.getDisplayedRowAtIndex(params.rowIndex);
return model.allLeafChildren[0].data.silver;
},
},
The Last:
https://plnkr.co/edit/9qtYjkngKJg6Ihwb?preview
var ColDef = [{
headerName: "colA",
field: 'colA',
rowGroup: true
},
{
headerName: "colB",
field: 'colB',
pivot: true,
enablePivot: true
},
{
headerName: "colC",
field: 'colC',
rowGroup: true
},
{
field: 'colD',
aggFunc: 'last',
tooltipValueGetter: commentTooltipValueGetter
},
{
field: 'comment'
},
{
field: 'colF'
}
];
function commentTooltipValueGetter(params) {
const colB = params.colDef.pivotKeys[0];
var model = params.api.getDisplayedRowAtIndex(params.rowIndex);
for (var i = 0; i < model.allLeafChildren.length ; i++) {
if (model.allLeafChildren[i].data.colB=== colB) {
return model.allLeafChildren[i].data.comments;
}
}
}
This is what i had to do for my question. It is combination of answers from #wctiger and #shuts below. So please also refer them for more context

Kendo grid on edit number display `,` seperator

I create a simple demo here. When edit at amount field I want to display , separator ? Currently it only display the , when not in edit mode. Any idea how to achieve this?
DEMO IN DOJO
var data = [{ "name": 'Venue A', "amount": 10000.50},
{"name": 'Venue B', "amount": 250000.00},
{"name": 'Venue C', "amount": 1500000.43 }];
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
data: data,
schema: {
model: {
id: "id",
fields: {
name: { type: "string" },
amount: { type: "amount" }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
toolbar: [{ name: "create", text: "Add" }],
columns: [
{ field:"name" , title: "Name"},
{ field: "amount", title: "Amount", format: "{0:n}" }],
editable: true
});
});
<div id="grid"></div>
Per the documentation you only have the following types allowed:
The available dataType options are:
"string"
"number"
"boolean"
"date"
"object"
(Default) "default"
I suggest you to use "number" in this case, as it will work for sorting and filtering.
You can check that Kendo doesn't understand the "amount" type by writing some incorrect text in the editor and see it stays as it was.
You can create your own editor as shown in this dojo:
{ field: "amount", title: "Amount", format: "{0:c}",
editor: function(container, options) {
const input = $(`<input name="${options.field}">`).appendTo(container);
input.kendoNumericTextBox({
format: "c"
});
}
}
However, if you test Kendo NumericTextBox here, you'll see it doesn't display the section separators when editing.
You could do a custom text editor and handle all the events - that's a pure JavaScript question.

jquery DataTables Editor: "select" field displays option value instead of label

I am using jquery's DataTables which is really working great. Then only problem I got is, that I am facing (in non-edit-view) the value of the select-field (which is an id). The user of course doesn't want to see the id of course.
Therefore I am looking for a possibility to configure that column in a way to show always the value of label property.
Here a some snippets:
$(document).ready(function() {
var table = $('#overviewTable').DataTable({
dom: "Tfrtip",
ajax: "/Conroller/GetTableData",
columns: [
{ data: "Id", className: "readOnly", visible: false },
{
data: "LoanTransactionId",
className: "readOnly readData clickable",
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
$(nTd).html("<a href='#'>" + oData.LoanTransactionId + "</a>");
}
},
{ data: "Id", className: "readOnly" },
{ data: "property_1", className: "readOnly" },
{ data: "Priority" },
{ data: null, className: "action readOnly", defaultContent: 'Info' }
],
order: [1, 'asc'],
tableTools: {
sRowSelect: "os",
sRowSelector: 'td:first-child',
aButtons: []
}
});
// data reload every 30 seconds
setInterval(function() {
table.ajax.reload();
}, 30000);
editor = new $.fn.dataTable.Editor({
ajax: "PostTable",
table: "#overviewTable",
fields: [
{
label: "Id",
name: "Id"
},
{
label: "Column 1",
name: "property_1"
},
{
label: "Priority",
name: "Priority",
type: "select",
options: [
{ label: "low", value: 0 },
{ label: "mid", id: 1 },
{ text: "high", id: 2 }
]
}
]
});
// Inline Edit - only those who are not readOnly
$('#overviewTable').on('click', 'tbody td:not(:first-child .readOnly)', function(e) {
editor.inline(this, {
submitOnBlur: true
});
});
How it looks in the display mode
How it looks in the edit mode
See the documentation on columns.render
You want to modify your column options for priority
Preferred Option: Your data source has a field with the priority as a string
This is the best option, as you don't want to have two places with this business logic. Keep it out of the client code.
Also, you will want to modify the editor as well so that the options used have been retrieved dynamically from the server to keep this business logic out of the client too. This is left as an exercise for the reader.
Since you don't provide details on what your data structure looks lik, I'm assuming it is an object, and it has an attribute priorityAsString so use the string option type for render.
columns: [
...
{
data: "Priority" ,
render: "priorityAsString",
},
Option 2) You write a function to map priority to string
Do this if you can't get the data from the server. But remember you will need to update many places when the priority list changes.
columns: [
...
{
data: "Priority" ,
render: renderPriorityAsString,
},
...
function renderPriorityAsString(priority) {
const priorityToString = {
0: 'low',
1: 'med',
2: 'high',
};
return priorityToString[priority] || `${priority} does not have a lookup value`;
}
"render": function ( data, type, full ) { return label;}

Updating entire dojox.grid.datagrid row

I've been trying to update the entire row of my grid, but having issues. I am able to update a single cell (if it doesn't have a formatter), but I would like to be able to update the entire row. Alternatively, I could update the column, but I'm not able to get it working if it has a formatter.
Here is the code that I'm using to update the grid:
grid.store.fetch({query : { some_input : o.some_input },
onItem : function (item ) {
dataStore.setValue(item, 'input', '123'); //works!
dataStore.setValue(item, '_item', o); //doesn't work!
}
});
And the structure of my grid:
structure: [
{ type: "dojox.grid._CheckBoxSelector"},
[[{ name: "Field1", field: "input", width:"25%"}
,{ name: "Field2", field: "another_input", width:"25%"}
,{ name: "Field3", field: "_item", formatter:myFormatter, width:"25%"}
,{ name: "Field4", field: "_item", formatter:myOtherFormatter, width:"25%"}
]]
]
Got some information in the #dojo freenode channel from 'tk' who kindly put together a fiddle showing the proper way to do this, most noteably putting an idProperty on the memoryStore and overwriting the data: http://jsfiddle.net/few3k7b8/2/
var memoryStore = new Memory({
data: [{
alienPop: 320000,
humanPop: 56000,
planet: 'Zoron'
}, {
alienPop: 980940,
humanPop: 56052,
planet: 'Gaxula'
}, {
alienPop: 200,
humanPop: 500,
planet: 'Reiutsink'
}],
idProperty: "planet"
});
And then when we want to update:
memoryStore.put(item, {
overwrite: true
});
Remember that item has to have a field 'planet', and it should be the same as one of our existing planets in order to overwrite that row.

How to dynamically add and remove GROUPS to KendoUI Scheduler

I am using KendoUI Scheduler control and here is initialization code
$("#Scheduler").kendoScheduler({
dataSource: [],
selectable: true,
height: 500,
editable: false,
eventTemplate: $("#event-template").html(),
views: [
"day",
{ type: "week", selected: true },
"month",
"agenda"
],
resources: [
{
field: "resourceviewid",
name: "ResourceViews",
dataColorField: "key",
dataSource: [
{ text: "Appointments", value: 1, key: "orange" },
{ text: "Delivery Specialist", value: 2, key: "blue" },
{ text: "Orientation Specialist", value: 3, key: "green" }
]
}
],
group: {
resources: ["ResourceViews"],
orientation: "horizontal"
}
});
Here "Appointments" group is default, it will be available always
I have check box in my screen
<div id="divResourceView">
<label><input checked type="checkbox" value="1" />Delivery Specialist</label>
<label><input checked type="checkbox" value="2" />Orientation Specialist</label>
</div>
On change event I wrote below code to get selected values from checkbox and updating GROUP datasource of KendoUI scheduler as below
$("#divResourceView :checkbox").change(function (e) {
var checked = $.map($("#divResourceView :checked"), function (checkbox) {
return parseInt($(checkbox).val());
});
});
var scheduler = $("#Scheduler").data("kendoScheduler");
var arrayOfStrings = checked.toString().split(",");
for (var i = 0; i < arrayOfStrings.length; i++)
{
if(arrayOfStrings[i] == 1)
{
var data = [{ text: "Delivery Specialist", value: 2, color: "blue" }];
scheduler.resources[1].dataSource.data(data);
}
if (arrayOfStrings[i] == 2) {
var data = [{ text: "Orientation Specialist", value: 3, color: "green" }];
scheduler.resources[2].dataSource.data(data);
}
}
scheduler.refresh();
But it removes all groups and add only one. I want to see both groups when arrayOfStrings has values "1,2",
I can see all groups during initialization But it disappears when i check the check box.
Images for reference
During Initialization
After
As you can see clearly, Delivery Specialist is missing in scheduler control
Found some link: http://www.telerik.com/forums/add-filter-to-resource-datasource
But not sure what they talking about? seems like refresh issue.
I have done this I believe you're right and your issue is to do with refreshing, I use the following to refresh it.
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.view(scheduler.view().name);
hope this helps through it is stupidly late (I'm currently looking up how to do this lazerly

Categories