I am trying Kendo UI out and I am using the examples provided for studying purpose. Let's suppose I am using a large data source of several hundreds of thousand elements. If I'm using paging and the page size is 10, I would really like to be able to get only 10 elements from the web-page and if Kendo UI was able to know that in reality the number of elements is much bigger, but we are showing only 10.
This is what I currently have:
var initGrid = true;
var grid2Data;
function getDataSource()
{
return grid2Data.Data;
}
var grid;
function getPageIndex()
{
if (!(grid)) {
return 0;
}
return grid.pager.page() - 1;
}
function getPageSize() {
if (!(grid)) {
return 10;
}
return grid.pager.pageSize();
}
function getFilters() {
if (!(grid)) {
return "";
}
return grid.dataSource.filter();
}
function getSorts() {
if (!(grid)) {
return "";
}
return grid.dataSource.sort();
}
function getParams() {
return getPageSize();
}
function postTest() {
if (initGrid) {
$.post('myurl' + getParams(), function (data) {
grid2Data = data;
$("#grid").kendoGrid({
dataBound: onDataBound,
dataSource: {
data: getDataSource(),
schema: {
model: {
fields: {
Email: { type: "string" },
FullName: { type: "string" },
LogCreateDate: { type: "date" },
RoleName: { type: "string" },
UserName: { type: "string" }
}
}
},
pageSize: 10
},
height: 300,
scrollable: false,
sortable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
columns: [
{
field: "Email",
title: "Email",
width: 100
},
{
field: "FullName",
title: "Full Name",
width: 100
},
{
field: "LogCreateDate",
title: "Created",
template: '#= kendo.toString(LogCreateDate,"MM/dd/yyyy") #'
},
{
field: "RoleName",
title: "Role",
width: 50
},
{
field: "UserName",
width: 100
}
]
});
grid = $("#grid").data("kendoGrid");
});
}
else {
}
initGrid = false;
}
$(document).ready(function () {
postTest();
});
My problem is that the grid is showing that this is element 1-10 from 10 and it's the first page. I would like the grid to show me a page index and item count given by me. How can I set the number of elements and the page index of the grid? Is this possible? Thanks.
When you choose serverPaging in the DataSource by setting it to true. You receiver in the server information about the page number (page), the page size (pageSize), number of records to skip (skip)... (look for serverPaging in http://docs.kendoui.com/api/framework/datasource) and in exchange you should return not only the array with the data of that page but also the total number of rows. Then you implement in schema.total the function for accessing the number of records. I.e. Lets assume that you return as result the following object:
{
rows: [
{ id: 1, col1: "col1.1", col2: "col1.2" },
{ id: 2, col1: "col2.1", col2: "col2.2" },
{ id: 3, col1: "col3.1", col2: "col3.2" }
],
totalRows : 1000
}
Then you might implement schema.total as:
schema: {
total: function (response) {
return response.totalRows;
}
}
Where response is the object received from the server.
NOTE: Actually in this case would be enough defining the schema as:
schema: {
total: "totalRows";
}
}
Since total is directly stored in totalRows field.
Check http://demos.kendoui.com/web/grid/remote-data.html for an example.
Related
I want to add some styling to the last row in my grid. I wont know what the row number is as there could be any number of rows. How can I go about this? I've seen rowClass and rowRenderer but not a working example. Here is the code I have:
var displayData = function (itemViewModelList) {
var fields = [
{
name: 'ConsultantName', type: 'text', width: 100, title: 'Consultant Name'
},
{
name: 'BranchName', type: 'text', width: 100, title: 'Branch Name', css: "red"
},
{ name: 'NumberOfInvestments', type: 'text', title: 'Number Of Investments' },
{
name: 'ValueOfInvestments', type: 'money', width: 150, title: 'Value Of Investments',
itemTemplate: function (value) {
return tisCommon.formatForMoney(value);
}
},
{
name: 'AverageValueOfInvestments', type: 'money', width: 150, title: 'Average Value Of Investments',
itemTemplate: function (value) {
return tisCommon.formatForMoney(value);
}
},
{
name: 'Month', type: 'text', width: 100, title: 'Month',
itemTemplate: function (value) {
return moment(value, 'M').format('MMMM');;
}
},
];
var options = {
inserting: false,
editing: false,
pageSize: 20,
fields: fields,
rowHeaders: false,
colHeaders: false,
data: itemViewModelList,
controller: controller = {
loadData: function () {
},
},
};
$('#investment-grid').tisGrid('', options);
if (itemViewModelList[0].ConsultantName != null) {
$("#investment-grid").jsGrid("fieldOption", "BranchName", "visible", false);
} else {
$("#investment-grid").jsGrid("fieldOption", "ConsultantName", "visible", false);
}
};
My data being passed "itemViewModelList" is an array of objects
I resolved this by using rowClass as follows:
controller: controller =
{
loadData: function () {},
},
rowClass: function (item, itemIndex) //item is the data in a row, index is the row number.
{
if ((item.ConsultantName == "Totals") || (item.BranchName == "Totals"))
{
return "totalItem highlight";
}
}
I have my if statement where I find the item in the last row based on my conditions. When they are met, I add my custom CSS classes to that row.
I attempt bind data to Kendo UI grid for AngularJS.
Folowing is asp.net mvc controller method:
public string GetCdcReport()
{
return
"[{\"ProductID\":1,\"ProductName\":\"Chai\",\"UnitPrice\":18,\"UnitsInStock\":39,\"Discontinued\":false}," +
"{\"ProductID\":2,\"ProductName\":\"Chang\",\"UnitPrice\":19,\"UnitsInStock\":17,\"Discontinued\":false}]";
}
AngularJs service method:
function getImportResultReport() {
return httpPost('getCdcReport');
}
Data-binding in angularjs controller:
vm.mainGridOptions = {
columns: [
{ field: "ProductID", title: "ID" },
{ field: "ProductName", title: "Product Name" },
{ command: [{ template: "<button class='k-button' ng-click='showDetails(dataItem)'>Show details</button>" }] },
],
pageable: true,
dataSource: {
pageSize: 5,
transport: {
read: function (e) {
dataservice.getImportResultReport().
then(function (data) {
e.success(data);
});
}
}
}
};
This code don't return error. Grid rendering 37 pages of 5 rows, but they is empty.
I think that grid must know what type of data set for binding. In my case it is jSon. How set json type for grid datasource? Or what is wrong if don't need to do this?
Provided I have following models:
module.exports = function (sequelize, DataTypes) {
var WorkingCalendar = sequelize.define('WorkingCalendar', {
date: DataTypes.DATEONLY,
isWorking: DataTypes.BOOLEAN,
}, {
indexes: [{
unique: true,
fields: ['PeriodId', 'date']
}]
}, {
classMethods: {
associate: function (models) {
WorkingCalendar.belongsTo(models.Period);
}
}
});
return WorkingCalendar;
};
module.exports = function(sequelize, DataTypes) {
var Period = sequelize.define('Period', {
name: DataTypes.STRING,
numberOfPeriods: DataTypes.INTEGER
}, {
classMethods: {
associate: function(models) {
Period.hasMany(models.WorkingCalendar);
}
}
});
return Period;
};
And then trying to get the Period through the WorkingCalendar as follows:
return models.WorkingCalendar
.findAll({
attributes: [
'PeriodId',
'date'
],
include: [
{ model: models.Period }
],
group: ['date', 'PeriodId']
});
I'm getting following error: Unhandled rejection Error: Period is not associated to WorkingCalendar!
Yet it does work the other way around.
My question:
Why can't I get the Period through the WorkingCalendar? And what do I have to do to make sure I can?
I have already tried putting the foreignKey attribute on the association as wel as the as binding but to no avail sadly. Any help would be very welcome!
So finally found it.
The indexes should be in the same object as classMethods
WRONG
module.exports = function (sequelize, DataTypes) {
var WorkingCalendar = sequelize.define('WorkingCalendar', {
date: DataTypes.DATEONLY,
isWorking: DataTypes.BOOLEAN,
}, {
indexes: [{
unique: true,
fields: ['PeriodId', 'date']
}]
}, {
classMethods: {
associate: function (models) {
WorkingCalendar.belongsTo(models.Period);
}
}
});
return WorkingCalendar;
};
RIGHT
module.exports = function (sequelize, DataTypes) {
var WorkingCalendar = sequelize.define('WorkingCalendar', {
date: DataTypes.DATEONLY,
isWorking: DataTypes.BOOLEAN,
}, {
indexes: [{
unique: true,
fields: ['PeriodId', 'date']
}],
classMethods: {
associate: function (models) {
WorkingCalendar.belongsTo(models.Period);
}
}
});
return WorkingCalendar;
};
I'm working Extjs 4.2. I have grid with rowediting plugin. Problem is when starting edit row, columns with align:center not showing correctly, but align:right works correct on editor row. I searched problem, but didn't find solve. Please Help with this.
This is my editor:
buildPlugins: function () {
var rowEditing = Ext.create("Ext.grid.plugin.RowEditing",{
autoCancel: false,
pluginId: 'rowedit',
errorSummary: false
});
return [rowEditing];
},
This is last three column code
{
text: Message.cameralGrid.columns.menu5,
menuDisabled: true,
columns: [
{
text: Message.cameralGrid.columns.cameralMustHoldDate,
dataIndex: "cameralMustHoldDate",
width: 120,
sortable: false,
xtype: "datecolumn",
style: "text-align:left;",
align: "center"
},
{
text: Message.cameralGrid.columns.cameralHoldDate,
dataIndex: "cameralHoldDate",
width: 100,
sortable: false,
xtype: "datecolumn",
style: "text-align:left;",
align: "center",
editor: {
xtype: "datefield",
format: "d.m.Y",
allowBlank: false
}
},
{
text: Message.cameralGrid.columns.fineSum,
dataIndex: "fineSum",
width: 120,
sortable: false,
xtype: "numbercolumn",
style: "text-align:left;",
align: "right",
editor: {
xtype: "numberfield",
minValue: 0,
allowBlank: false
}
}
]
}
Thanks for Help!
I needed to override Ext.grid.RowEditor class. After this problem is solved.
Ext.define('helper.RowEditor', {
override: 'Ext.grid.RowEditor',
requires: [
'Ext.grid.RowEditor'
],
addFieldsForColumn: function(column, initial) {
var me = this,
i,
length, field;
if (Ext.isArray(column)) {
for (i = 0, length = column.length; i < length; i++) {
me.addFieldsForColumn(column[i], initial);
}
return;
}
if (column.getEditor) {
// Get a default display field if necessary
field = column.getEditor(null, {
xtype: 'displayfield',
// Override Field's implementation so that the default display fields will not return values. This is done because
// the display field will pick up column renderers from the grid.
getModelData: function() {
return null;
}
});
if (column.align === 'right') {
field.fieldStyle = 'text-align:right';
}
// this block is added -------------------------------->
if (column.align === 'center') {
field.fieldStyle = 'text-align:center';
}
// <-----------------------------------------------------
if (column.xtype === 'actioncolumn') {
field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field'
}
if (me.isVisible() && me.context) {
if (field.is('displayfield')) {
me.renderColumnData(field, me.context.record, column);
} else {
field.suspendEvents();
field.setValue(me.context.record.get(column.dataIndex));
field.resumeEvents();
}
}
if (column.hidden) {
me.onColumnHide(column);
} else if (column.rendered && !initial) {
// Setting after initial render
me.onColumnShow(column);
}
}
}
});
I've tried various ways to set the total number of records in the Kendo-UI Web Grid, without success.
I'm kind of lost on where I spend the amount processed in ajax, already assigns the total value in the schema for 4 to see if it happens more paging did not work, just shows the two records and it shows that there are more pages.
If anyone could help me I would be very grateful!
...
transport: {
read: function (option) {
$.ajax({
url: '<?=$view->encode('ctrl.php?turma=lista_turma');?>',
data:{
skip: option.data.skip,
take: option.data.take,
pageSize: option.data.pageSize,
page: option.data.page,
sorting: JSON.stringify(option.data.sort),
filter: JSON.stringify(option.data.filter)
},
success: function (result) {
option.success(JSON.parse(result));
},
error: function (result) {
alert(result);
}
},
schema: {
data: 'data',
total: function (data) {
return 4;
},
/*total: function (result) {
alert('aqui');
result = result.d || result;
return 4;
},*/
model: { id: "id_turma" },
fields: {
id_turma: { validation: { required: true } },
nome_turma: { validation: { required: true } },
sigla_turma: { validation: { required: true, max:12 } }
}
}
},
pageable: true,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
batch: true,
pageSize: 2
});
I'm not sure what you're trying to do with all those "eval" statements in your code. This looks like you're overcomplicating things a lot.
If you do server-side paging, the total should be returned from the server since the client typically doesn't know how many more records there are. If your response contains a property "total", then this should work:
schema: {
total: "total" // total is returned in the "total" field of the response
}
or this, if you want to use a function:
schema: {
total: function(response) {
return response.total; // total is returned in the "total" field of the response
}
}
Both taken from the docs:
http://docs.kendoui.com/api/framework/datasource#configuration-schema.total
Here's a working example: http://jsfiddle.net/lhoeppner/y6KdK/