I have a kendo grid with custom popup edit window to imitate popup edit, but with batch edit. Everything works fine, but I am experiencing a small issue. Whenever value is changed, the grid cell does not have that red triangle thingy in the corner indicating that this particular value different from original.
As I understand in this post, manually made changes in datasource does not appear on the grid, so I have to add them manually.
This post 'manually maintain dirty cell marker on paging in Kendo grid' gives an idea how to get it working. I could attach some listeners to kendoWindow inputs, track what fields are being edited, compare old and new values...
But is there a less painful way to achieve this functionality? Maybe there is some built in kendo function to achieve that?
Here's a small working example http://dojo.telerik.com/aSaXe/4
The red "dirty" marks appear automatically only when the built-in in-cell editing is used. From this point of view, your scenario requires these to be added manually after the custom editing popup is closed.
You may find the change event of the data item useful in the task. It will be fired each time a value in the popup is changed and the respective textbox is blurred.
var uid = $(e.target).parents('tr').attr('data-uid');
var grid = $('#grid').data("kendoGrid");
var dataItem = grid.dataSource.getByUid(uid);
dataItem.bind("change", function(args) {
// args.field
});
Finally, keep in mind that each change in the Grid dataSource causes the whole table to be redrawn (unless the built-in in-cell editing is used), so you will lose any previously applied custom styling.
You can use the save event on your kendo grid as:
save: function (e) {
addDirtyUid(e.model.uid);
setTimeout(refreshVisualDirtyElements, 100);
}
Other functions and var:
var dirtyIds = [];
function addDirtyUid(currentUid) {
if (dirtyIds.indexOf(currentUid) === -1) {
dirtyIds.push(currentUid);
}
}
function refreshVisualDirtyElements() {
for (var i = 0; i < dirtyIds.length; i++) {
var thisUid = dirtyIds[i];
$("tr[data-uid='" + thisUid + "']").find("td:eq(0)").addClass("k-dirty-cell");
$("tr[data-uid='" + thisUid + "']").find("td:eq(0)").prepend('<span class="k-dirty"></span>');
}
}
Related
I need to edit two columns of my grid using combos as editors, and I need the values shown in the second to be filtered accordingly to the value selected in the first one.
There is also the problem that I need to show the "bound" value (i.e. "description") instead of the Id, in the grid cell.
I prepared a (very simplified) fiddle to show the problem here
Click here for the fiddle
Looking at the fiddle, I'd need to select the brand in the first combo and then a model in the second, but I should obviously find only the models from the selected brand in there.
How can I show the descriptive text in the cell?
How can I filter the second combo?
Thanks
The editing plugin has an beforeedit event you can use, for example:
listeners: {
beforeedit: function(editor, context) {
var record = context.record;
if (context.field !== 'modelId') {
return;
}
models.clearFilter(true);
models.filter({
property: 'brandId',
value: record.getId()
});
}
}
Working example: https://fiddle.sencha.com/#fiddle/12hn
Is there a way to make data entry on a kendo ui grid behave like excel?
i.e using the arrow keys and just entering data without pressing the enter key.
I am using the javascript version of kendo ui grid. Our users have an excel background,
so we are trying to make the transition easy.
Thanks in advance
There's no default way, but you can emulate it to a certain extent by adding custom behaviour to certain key navigation actions.
This answer will emulate the following from Excel:
Excel Navigation - Grid should be navigatable by arrow keys
Automatic Cell Entry - When a grid cell is navigated to, typing will automatically start editing the cell
Next Cell Navigation - When done editing the cell, pressing enter will exit the cell and then navigate to the next row's corresponding cell if the same data type (so that user can keep entering data concerning a specific data column)
Here is a DEMO, explanation is below.
Excel Navigation
Make your grid navigatable, this allows user to use keys to move to each cell with arrow keys just like excel. Also ensure your grid's editable property is set to "incell". This sets the grid into a cell by cell edit mode.
navigatable: true,
editable: "incell",
Automatic Cell Entry
Excel allows data editing without pressing Enter. Typically, Kendo Grid will only allow you to start editing after pressing enter. As long as the cell is focused, this code will allow user to immediately start typing without the Enter step. Put this after the initialization of your grid, bind the keypress event:
var grid = $("#grid").data("kendoGrid");
grid.table.bind("keypress", function (e) {
if (e.which !== 0 && e.charCode !== 0 && !e.ctrlKey && !e.metaKey && !e.altKey) {
//get currently navigated cell, this id follows user's navigation
var activeCell = $("#grid_active_cell");
//don't do anything if already editing cell
if (activeCell.hasClass("k-edit-cell")) return;
grid.editCell(activeCell);
var input = activeCell.find("input");
//number datatype editor loses key press character when entering edit
if (input.last().attr('data-type')==='number') {
input.val(String.fromCharCode(e.keyCode | e.charCode));
} else {
input.val("");
}
}
});
Basically I just make sure that the key pressed is a text character and not something like "ALT" or "ESC" for example. Then I programmatically set the cell into edit mode.
There are some quirks with different data types and different column editors. I found that the numeric datatype editor loses the keypress value, which is why I had to make a special case for it and re-enter the key character.
Next Cell Navigation
In excel, after you are satisfied with the data edit and you press Enter, the navigation goes to cell directly below it. This allows user to continuously go down a list of items and edit a specific column of information. To do this with Kendo Grid, add this code:
//Kendo "Enter" key input is captured through this binding
$("#grid table").on("keydown", "tr", function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 13) { //If key is ENTER
//find index of the td element
var tdIndex = $(e.target).closest('td').index();
//get the next row's cell
var nextRow = $(e.target).closest('tr').next();
var nextRowCell = $(nextRow).find('td:eq(' + tdIndex + ')');
//focus the next cell on a different context
setTimeout(function () {
var grid = $("#grid").data("kendoGrid");
grid.current(nextRowCell);
}, 0);
}
});
The reason why this is different function binding is because Kendo Grid has a default keydown binding on the table object, so we must add our custom functionality to the tr element before the event bubbles up.
Notes
This is a baseline demo, more complicated things will most likely break this code like custom data editors, grid grouping, etc... in which case you'll have to add more code to handle all the situations as necessary.
Keypress event is used for automatic cell entry because it is more reliable in terms of character code determination.
Keypress event may not work on mobile, in which case keyup might be a better replacement event binding.
If you are using your mouse to edit the grid on my demo, it will still work as normal Kendo Grids do, but you're missing out on the point of my demo.
As I am using KendoUI for development of my application.I have used Multiple Grid in my application.My Problem is that i want to disable the animation for filter option that is when we click on each column for filter the menu is slide down giving us various options to filter.
I want to disable the animation when i click that column for filtration that option must not slide down. Here i am adding an Image.
I don't think there are "official" configuration options for this.
You can disable it for all popups like this:
kendo.ui.Popup.fn.options.animation.open.duration = 0;
kendo.ui.Popup.fn.options.animation.close.duration = 0;
(demo)
Note that this will affect other widgets as well (e.g. the dropdowns inside the filter menu), so you may need to explicitly set the animation config for those if you need it.
An alterative would be to set the animation for all filter menus (there is one per column), for example like this:
$(".k-grid-header").find("th").each(function () {
var menu = $(this).data("kendoFilterMenu");
var init = menu._init;
menu._init = function () {
init.apply(this, arguments);
this.popup.options.animation.open.duration = 0;
this.popup.options.animation.close.duration = 0;
};
});
(demo)
The above answer was useful to me, however for how we were using kendo grid, the grid's column menu brought up another submenu (as seen here http://demos.telerik.com/kendo-ui/grid/column-menu). It turns out that though the initial dropdown is of Kendo type "Popup", the sub-menu is of Kendo type "Menu". So if you also want the sub-menu to have no animation, you would add these lines:
kendo.ui.Menu.fn.options.animation.open.duration = 0;
kendo.ui.Menu.fn.options.animation.close.duration = 0;
Alternatively, you can disable the animation with the shorthand of animation = false, so the final result could be:
kendo.ui.Popup.fn.options.animation = false;
kendo.ui.Menu.fn.options.animation = false;
Again note that this will turn off animations for all popups and menus.
I'm attempting to rebind the listview data after changing the template, based on a DropDownList value. I've included a JSFiddle for reference. When I rebind currently the values in the template are undefined.
Thanks!
JSFiddle link
I was thinking the best way to handle it would be in the 'select' or 'change' function:
var cboDetailsCategory = $("#detail").kendoDropDownList({
data: [
"All",
"Customer",
"Location",
"Meter",
"Other"],
select: function (e) {
var template = $("#" + e.item.text()).html();
console.log("template", template);
$("#details").html(template);
},
change: function (e) {
},
please refer to the JSFiddle link and this graphic as a visual
Here is a lengthier workflow:
User completes a name search and clicks a search button.
Name results are populated in a listview, rendered individually as button controls using a template.
User then clicks one of the name results (shown as the button text).
A dropdownlist of categories ('All' <--default , 'Location', 'Customer'...) gives the user the ability to target what subject of data they want to see. 'All' is the default, showing all details about the selected name.
So by default the 'All' template is populated.
If user wants to see the 'Location' details (template) they select it from the dropdownlist.
The template shows but the values are all blank. The only way to populate it is to click the name (button) again.
I want to remove the need for having to re-click the button (name) to populate the template ('Location', etc...).
I have put together a JSFiddle showing the structure. Though due to the data being private and served over secure network I cannot access it.
Refer to JSFiddle:
I believe the issue is that the onclick event grabs the data-uid and passes it to the initial default template (named 'All' but it's not included in code as it's lengthy). When the user changes the dropdownlist (cboDetailsCategory) and selects a new template I lose the data.
Thanks for your help. I'm really stuck on this and it's a current show stopper.
There isn't an officially supported way to change templates, without destroying the listview and rebuilding it. However, if you don't mind poking into into some private api stuff (be warned I can't guarantee that kendo won't break it without telling you) you can do this
var listview = $("#MyListview").getKendoListView();
listview.options.template = templateString;
listview.template = kendo.template(listview.options.template);
//you can change the listview.altTemplate the same way
listview.refresh(); //redraws the elements
if you want to protect against unknown API changes you can do this, which has A LOT more overhead, but no risk of uninformed change (untested!)
var listview = $("#MyListview").getKendoListView(),
options = listview.options;
options.dataSource = listview.dataSource;
listview.destroy();
$("#MyListview").kendoListView(options);
Here's the solution, thanks for everyone's help!
JSFiddle Link
The issue was where I was setting the bind:
$("#list").on("click", ".k-button", function (e) {
var uid = $(e.target).data("uid");
var item = dataSource.getByUid(uid);
var details = dropdown.value();
var template = $("#" + details).html();
$("#details").html(template);
kendo.bind($("#details"), item);
currentData = item;
});
I am using Yahoo UI library, in particular this example.
What I want is to get a particular column's value when clicking (selecting) a row.
I am using this code:
var makis = function() {alert("blabla"); };
myDataTable.subscribe("rowClickEvent", makis);
and works, but I just don't know how to get a column's value in the particular row.
Ok i found it on my own, i am posting if anyone has the same problem.
myDataTable.subscribe("rowClickEvent", function(oArgs) {
var elTarget = oArgs.target;
var oRec = this.getRecord(elTarget);
console.log("value:" + oRec.getData("column_we_want"));
}