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.
Related
I have an Ag Grid table. In that table one pinned column is with action buttons (like edit row, print row item, open in popup, etc). I want to prevent row selection when user clicks on any cell in column with action buttons, but at the same time I need common row multiSelection behaviour with Shift button for all other columns. How can I achieve this?
You can use the onCellClicked event of the Ag-Grid API. In the event callback, you can check the column that was clicked, and if it is the column with the action buttons, you can call the stopPropagation() method on the event object to prevent the row from being selected. For all other columns, you can continue to allow the default row selection behavior.
const gridOptions = {
onCellClicked: (event) => {
if (event.column.colId === 'actionColumnId') {
event.stopPropagation();
}
}
};
For the Multi-Selection behavior with shift button, you could enable the suppressRowClickSelection flag on the grid options and handle the multi-selection by your own by listening to the 'rowSelected' event and use the shift button detection or programatically change the selection via the API.
const gridOptions = {
suppressRowClickSelection: true,
onRowSelected:(event)=>{
//Check if the shift button is pressed and act accordingly
}
};
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>');
}
}
I have a jgrid with inline editing, when i click on "+" in the pager button it adds a row in editable mode. When the row is in editable mode i click on "+" again at tht time i want to show a message saying "the grid is in edit mode please save it".
document.getElementById('partnerGrid_iladd').onclick = function() {
var rowid = jQuery("#partnerGrid").jqGrid('getGridParam', 'selrow');
var edited = "";
var ind = jQuery("#partnerGrid").getInd(rowid, true);
if (ind != false) {
edited = $(ind).attr("editable");
}
if (edited === "1") {
alert("There is an row in editable mode ,Please save the row before adding another row");
return;
}
}
But this gets fired after a row is added in the grid and the row is in added mode.. So i want to check if the row is a new one if the row is new one i don't want to throw error on click of +.
There are many ways to implement your requirement. You don't posted enough details about what you do, but because you test editable attribute I can guess that you write about the "+" button added by inlineNav. In the case jqGrid calls addRow on the click on the Add button. The method addRow have beforeAddRow callback and jqGridInlineBeforeAddRow event which you can use. The callback/event should return false to prevent adding new row and starting the editing. Moreover you can use savedRow parameter of jqGrid to test whether some other row is in editing mode. You can use getGridParam to get "savedRow" parameter. The returned value is array of saved rows with the values before starting editing. Thus if the length of the array grater as 0 then some other row is still editing.
I have been struggling to get a very simple feature working using jqxGrid and a cell rendered with a jqxNumberInput
editor.jqxNumberInput({ decimalDigits: 2, spinButtonsStep: 0.1, spinMode: "simple", decimalSeparator: decimalSeparator, groupSeparator: groupSeparator });
Basically when the user clicks on the cell the cursor is placed all the way to the right of the text (number), my boss wants the contents of the cell to be highlighted (text selected) so the user does not have to move the cursor to the left in order to start typing
I have been digging through the jqx grid docs for quite some time and there doesnt seem to be anything I can find to achieve this.
http://www.jqwidgets.com/jquery-widgets-documentation/documentation/jqxgrid/jquery-grid-api.htm
I attempted to tie into the cellbeginedit event and assumed I could use the event to get the target element and selected it that way, but the event.target value is the entire grid, not the cell itself.
$(element).on('cellbeginedit', function (event) { // event.target == grid not cell });
I also attempted to get the cell by using the getcell method, but this returns the data for that cell not the element itself.
var cell = $(element).jqxGrid("getcell", args.rowindex, args.datafield);
// cell then equals the data for the row not with no reference to the
element in question
To reiterate, i need to modify, hack update do something so when a user clicks on a jqxNumberInput and the cell goes into edit mode all the text in the cell is selected (highlighted)
any help on this issue would be greatly appreciated
You should put your editor customization logic within your column's initeditor callback function. There you can try with jqxNumberInput API such as "focus" or code for selecting all text within input.
var input = editor.find('input');
var length = input.val().length;
try {
if ('selectionStart' in input) {
input.focus();
input.setSelectionRange(0, length);
}
else {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', length);
range.moveStart('character', 0);
range.select();
}
}
catch (error) {
}
In the above code, editor is the argument passed from jqxGrid to your column's initeditor function.
I want to make an editable, navigable kendo grid, that can set fields when some others filled. My problem is, the row must be selected to do such thing, but the standard keyboard navigation only moves the focused field, not the selected, using the arrow keys.
Additionally, i find something that might be it, but i don't seem to have a crack at it. Here's the link:
http://www.kendoui.com/forums/kendo-ui-complete-for-asp-net-mvc/grid/grid-keyboard-navigation-code-sample.aspx
So basically, i need some sort of a function, binding the selected row to the focused cell when navigated by arrow keys, or a new row created, or the selected deleted. If someone's willing to help me, i'd be very thankful. :)
To enable keyboard navigation in Kendo UI Grid you must enable this feature by navigatable option in initialization (http://demos.telerik.com/kendo-ui/grid/keyboard-navigation)
$("#grid").kendoGrid({
...
selectable: "row",
navigatable: true,
...
});
If you want to navigate rows by its selection (without focusing and confirming), you should handle manually keydown event. In this event you can find focused cell and select row for this cell.
var data = $("#grid").data('kendoGrid');
var arrows = [38, 40];
data.table.on("keydown", function (e) {
if (arrows.indexOf(e.keyCode) >= 0) {
setTimeout(function () {
data.select($("#grid_active_cell").closest("tr"));
},1);
}
}