Can Kendo Grid be always in edit mode? - kendo-ui

Does anyone know if the kendo grid could be always set to edit mode at all times?
We don't want the user to click on a cell or a button to activate the edit mode. We want it the widgets to be displayed and available at all times.
Is it possible at all?

Apart from using batch editing mode you can try setting the template of every column and binding the input elements to the data items using MVVM.
$("#grid").kendoGrid({
dataSource: {
schema: {
model: {
id: "id",
fields: {
id: { editable: false }
}
}
}
data: [
{ id:1, age: 30, name: "John Doe" }
]
},
columns: [
{ field: "id", width: 50 },
{ field: "age", template: "<input data-bind='value: age' data-role='numerictextbox'>" },
{ field: "name", template:"<input data-bind='value: name' >" }
],
dataBound: function() {
var rows = this.tbody.children();
var dataItems = this.dataSource.view();
for (var i = 0; i < dataItems.length; i++) {
kendo.bind(rows[i], dataItems[i]);
}
}
});
Here is a live demo: http://jsbin.com/ApoFobA/2/edit

Out of the box, not exactly. You can enable Batch editing which displays everything normally, but clicking a cell will switch it to an editor automatically.
Example
To enable it, set { batch: true } on the table's datasource. Otherwise you're off to some deeper scripting. Checked and simply calling editRow on all rows doesn't do it. Default behavior is to disable editing on a row when a new one is taken into edit mode.
So, quick look says Batch mode - won't display editors all the time, but works and out of the box.

I found the above answer to be excellent. One issue though, is that Kendo doesn't clean up bindings when it refreshes the grid (such as when sorting or filtering or when refresh() is called) and deletes the grid's DOM elements. The result is the dataItems will have an increasing number of "change" events queued up -- a bit of a memory leak. This can be avoided by unbinding in the dataBinding event, as below:
dataBinding: function() {
var rows = this.tbody.children();
for (var i = 0; i < rows.length; i++) {
kendo.unbind(rows[i]);
}
}

Related

kendo listBox disable items

I would like to disable some items in the kendo ListBox.
There is a Sample in the kendo docs to disable: http://docs.telerik.com/kendo-ui/api/javascript/ui/listbox#methods-enable
But I would like disable some items in the list like:
var data = [
{ 'ProductID':'1', 'ProductName': 'Spalte 1', 'Discontinued': true, 'disabled': true },
{ 'ProductID':'2', 'ProductName': 'Spalte 2', 'Discontinued': true, 'disabled': false},
];
My full sample code: http://dojo.telerik.com/iKOmo/10
My goal is, disable items in the listBox when disabled = true is in the data object.
Thanks for some help
Severin
One solution for this Problem is:
$("#disable").click(function () {
//console.log("my object: %o", opt_kendoListBox);
//alert(JSON.stringify(opt_kendoListBox.options.dataSource._data));
for (i = 0; opt_kendoListBox.options.dataSource._data.length > i; i++) {
if(opt_kendoListBox.options.dataSource._data[i].disabled){
opt_kendoListBox.enable($(".k-item").eq(i), false);
}
}
});
It works correct only after initialization of listBox.
A sample code: http://dojo.telerik.com/iKOmo/24
Not a perfect solution, but a helping solution i hope so.

Export to PDF increase number of items per page

I have a grid control which I wish to export the content of. Upon initialisation, the pageSize attribute is set to 10 items however I want to increase the number of items per page during exportToPDF.
I have tried to modify the pageSize of the dataSource prior to carrying out the export but this seems to have no effect on the end product.
var grid = $("#grid").data("kendoGrid");
var filter = grid.dataSource.filter;
grid.dataSource.query({
filter: filter,
pageSize: 20, // has no effect on the exported PDF
page: 1,
group: [{
field: "groupField1",
dir: "asc"
}, {
field: "groupField2",
dir: "asc"
}, {
field: "groupField3",
dir: "asc"
}]
});
var progress = $.Deferred();
grid._drawPDF(progress)
.then(function (root) {
return kendo.drawing.exportPDF(root, { forcePageBreak: ".page-break", multiPage: true });
})
.done(function (dataURI) {
// ... do some manual manipulation of dataURI
kendo.saveAs({
dataURI: manipualtedDataURI
});
progress.resolve();
Is there something I am missing so I can display more items on each page of the PDF export?
EDIT
Including my grid definition with the pdfExport function suggested by the below answer (which never gets called):
var grid = $("#reportGrid").kendoGrid({
pdf: {
allPages: true,
avoidLinks: true,
repeatHeaders: true,
template: kendo.template($("#page-template").html()),
scale: 0.7,
margin: { top: "2.5cm", right: "1cm", bottom: "1.5cm", left: "1cm" },
paperSize: "A4",
landscape: true
},
// *this function is not getting called*
pdfExport: function(e) {
e.sender.dataSource.pageSize(10);
e.promise.done(function() {
e.sender.dataSource.pageSize(20);
});
},
toolbar: kendo.template($("#template").html()),
...
});
Note: A template is used to include a header / footer on each page of the PDF export.
Another note: 'Manual manipulation of dataURI' includes going out to the server to perform a merge with another PDF file, so I cannot use the default export via the grid :(
EDIT 2
I have extended the Dojo example from #R.K.Saini's answer to use the method by which I need to generate the PDF export (as per original post).
The snippet logs the URI of the grid being exported and when the pdfExport function is called. As you will see, when using the built in grid 'Export to PDF' button, the pdfExport function is triggered but when using the additional button below the grid, it is not.
You can use pdfExport event to change page size of your grid datasource before pdf export started and then when the export finish you just need to revert back the previous page size.
The call back function of this event receive grid instance as e.sender and and a promise as e.promise which can be used to set back the page size when exporting finish.
For more info check http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-pdfExport
$("#grid").kendoGrid({
dataSource: dataSource,
pdf: {
allPages: true
},
pdfExport: function(e) {
e.sender.dataSource.pageSize(10);
e.promise.done(function() {
e.sender.dataSource.pageSize(20);
});
},
...
//Other configguration
});
Here is a working demo http://dojo.telerik.com/UzOXO
Edit
You can also change grid page size in your custom export function just change grid page size before calling _drawPdf() function and change it back when done.
$("#btnPdfExport").kendoButton({
click: function () {
var grid = $("#grid").data("kendoGrid");
var progress = $.Deferred();
// Change grid datasource pagesize before calling _drawPDF
grid.dataSource.pageSize(20);
grid._drawPDF(progress)
.then(function (root) {
return kendo.drawing.exportPDF(root, { forcePageBreak: ".page-break", multiPage: true });
})
.done(function (dataURI) {
console.log("Exporting " + dataURI);
kendo.saveAs({
dataURI: dataURI,
fileName: "export.pdf"
});
progress.resolve();
// Change grid datasource pagesize when done
grid.dataSource.pageSize(10);
});
}
});
Check Update DOJO here http://dojo.telerik.com/UzOXO/8

Grid.columns.editable not available where is wrong?

I have a problem with kendoGrid with popup editing. It displays value of first column as a label in popup even when I set editable property to false.
columns: [
{
template: kendo.template('<span>#: sys_index # </span>'),
width: 38,
editable: false
}, {
title: 'System Name',
field: 'SystemName'
}, {
command: ['edit', 'destroy'], width: 200
}
]
rendered grid
grid popup
Editability determines if the field value can be modified, but it will still appear in both cases. A possible option is to remove the readonly content in the Grid's edit event.
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-edit
http://dojo.telerik.com/ItUvA
Assuming that the readonly content is in the first column...
edit: function(e) {
var form = e.container;
form.find(".k-edit-label").eq(0).remove();
form.find(".k-edit-field").eq(0).remove();
}

ExtJS4 dataView - Select node id

I have an ExtJS 4 dataView and i would like to catch the id of a selected node.
It is the first time that i'm using the dataView, then, there are some troubles.
The store is loaded correctly and i see the datas into the view very well. The problem which i'm having, concern the "classic" actions of update and delete, particularly getting the id of a selected item.
For example into a grid i click, then select a record and through a button's pressing i open a window (or other actions) with a loaded form (by sending in AJAX to the store, the id of the selected row) and i update the datas.
I'm not still able to do it with the ExtJS 4 dataView.
Below my dataView:
dataView_player = Ext.create('Ext.Panel', {
id: 'images-view',
frame: true,
collapsible: false,
autoWidth: true,
title: 'Giocatori (0 items selected)',
items: [ Ext.create('Ext.view.View', {
id:'players-view',
store: store_player,
multiSelect: true,
height: 310,
trackOver: true,
overItemCls: 'x-item-over',
itemSelector: 'div.thumb-wrap',
emptyText: 'Nessun giocatore visualizzato',
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap" id="{id}-{name}">',
'<div class="thumb">',
'<img src="/img/players/{picture}" title="{name} {surname}" alt="{name} {surname}" style="">',
'</div>',
'<span class="" style="height:30px;">{general_description}{name} {surname}</span>',
'</div>',
'</tpl>',
'<div class="x-clear"></div>'
],
plugins: [
Ext.create('Ext.ux.DataView.DragSelector', {}),
Ext.create('Ext.ux.DataView.LabelEditor', {dataIndex: 'name'})
],
prepareData: function(data) {
Ext.apply(data, {
name: data.name,
surname: data.surname,
general_description: Ext.util.Format.ellipsis(data.general_description, 15)
});
return data;
},
listeners: {
'selectionchange': function(record, item, index, e) {
var node = this.getNode(record); //this.getNode(record);
console.log(node.get('id'));
}
}
}) ],
dockedItems: [{
xtype: 'toolbar',
items: [{
iconCls: 'delete',
text: 'Cancella Selezionati',
scale: 'medium',
tooltip: 'Per <b>cancellare</b> i giocatori selezionati',
tooltipType: 'qtip',
id: 'delete-player',
disabled: true,
handler: delete_news
}, '-', {
iconCls: 'edit',
text: 'Aggiorna Selezionata',
scale: 'medium',
tooltip: 'Per <b>aggiornare</b> un giocatore selezionato',
tooltipType: 'qtip',
disabled: false,
id: 'update-player',
handler: function(nodes) {
var l = nodes.get('id');
console.log(l);
}
}
}
]
}]
});
Of course, this is a wrong example (because the listeners don't work) but it's just to make an idea.
There are two main things what i would like to do:
1) Catch the id (and other store's fields) of the selected item on the action "selectionchange". Obviously, now it doesn't work because of this: node.get('id'). Of course it's a wrong syntax but make up the idea of my will.
2) Catch the id of the selected item on the handler event of the "update-player" button. As above, the issue is the nodes.get('id'). Further trouble, is how to pass the selected item's features. in handler: function(nodes) { the nodes variable does not assume any value and i don't know how to pass the params from the dataview to the handler function.
I hope that somebody will able to help me.
According to the docs the selectionchange event provides the selection model as well as the array of selected records, so you are probably assuming the wrong parameters in your listener.
Without doing further testing, I think it should be something like this:
listeners: {
'selectionchange': function(selModel, selection, eOpts) {
var node = selection[0];
console.log(node.get('id'));
}
}
Note that you're using multiSelect: true, so it could be more than one record in the selection array.
Answer for second part of the question:
In button handler, you need to get selection model of the view and from it get information about selected records:
handler: function(nodes) {
// find view component
var view = dataView_player.down('dataview');
// get all selected records
var records = view.getSelectionModel().getSelection();
// process selected records
for(var i = 0; i < records.length; i++) {
console.log(records[i].getId());
}
}

Kendo grid change indicator and cancel not working

I'm new to Kendo and the Kendo grid but I'm trying to learn how to use the master detail Kendo grid where the detail grid is supposed to support batch editing. The data is available in a local JavaScript object.
This jsFiddle demonstrates the problems I'm seeing.
Here's how the grid is being created - see the jsFiddle for the complete snippet -
$("#grid").kendoGrid({
dataSource: items,
detailInit: createDetail,
columns: [
{ field: "Item", width: "200px" },
]
});
function createDetail(e) {
$("<div/>")
.appendTo(e.detailCell)
.kendoGrid({
dataSource: {
batch:true,
transport: {
read: function (options) {
options.success(e.data.SubItems);
}
}
},
editable:true,
pageable:true,
toolbar: ["save", "cancel"],
columns: [
{ field: "SubItem", title: "Sub Item", width: 200 },
{ field: "Heading1", title: "Heading 1", width: 100 }
]
});
}
When you edit an item in the grid and click to the next cell, the details grid automatically collapses not matter where I click, even in an adjacent cell. When I open it again, I don't see the change indicator in the cell (red notch) but the new value is there.
If I were to hook up the save to an ajax call, Kendo sends the right detail item(s) that were edited.
Nothing happens when I click cancel changes.
How do I get the grid to not collapse and see the change indicators ?
How do I get canceling of changes to work correctly ?
[Update] - Further investigation reveals that if I use an older Kendo version 2011.3.1129 , this works as expected. But if I use the newer 2012.3.1114, it doesn't. Dont know if this is a bug or a change in behavior.
After much effort, I found that the cause seems to be that the master grid is rebinding automatically causing the behavior I observed. I was able to get around this by handling the dataBinding event in the master grid and within that, checking if any of the detail datasources were dirty and if so, calling preventDefault.
Here are relevant code snippets :
dataBinding: function (e) {
if (masterGrid.AreChangesPending()) {
e.preventDefault();
}
}
AreChangesPending : function () {
var pendingChanges = false;
// I gave each detail div an id so that I can get a "handle" to it
$('div[id^="detail_"]').each(function (index) {
var dsrc = $(this).data("kendoGrid").dataSource;
$.each(dsrc._data, function () {
if (this.dirty == true || this.isNew()) {
pendingChanges = true;
}
});
// For some reason, Kendo did not detect new rows in the isNew()
// call above, hence the check below
if (dsrc._data.length != dsrc._total) {
pendingChanges = true;
}
});
return pendingChanges;
}

Resources