kendo grid inline edit dropdown will not expand on tab navigation

2 posts, 1 answers
  1. Ian
    Ian avatar
    12 posts
    Member since:
    Feb 2016

    Posted 17 Feb 2016 Link to this post

    I'm having an issue with Kendo Grid in Angular where the custom drop down I've implemented will not open when tab navigating to that column. The built in text and number editor fields are editable on tab navigation but my custom drop down will not expand. I have to click on it to get the drop down effect.

    My goal here is to allow the user to log an an entire row of data without having to take their hands off the keyboard.

    My column is defined like so:

     

    gridColumns.push({
        field: currentField.FieldName.replace(/ /g, "_"),
        title: currentField.FieldName,
        editor: $scope.dropDownAttEditor,
        template: function (dataItem) {
                    return $scope.dropDownTemplate(dataItem, currentField.FieldName);
            }
    });

     

    My gridOptions are defined as follows:

    $scope.gridOptions = {
                dataSource: new kendo.data.DataSource({
                    transport: {
                        read: {
                            url: appconfig.basePath + '/api/DrillHoleManager/DrillHoleInterval',
                            type: 'POST',
                            contentType: 'application/json'
                        },
                        update: {
                            url: appconfig.basePath + '/api/DrillHoleManager/DrillHoleIntervalUpdate',
                            type: 'POST',
                            contentType: 'application/json'
                        },
                        parameterMap: function (data, operation) {
                            if (operation === "read") {
                                data.DrillHoleId = $scope.entity.Id;
                                data.DrillHoleIntervalTypeId = $stateParams.ddhinttypeid;
                            // convert the parameters to a json object
                            return kendo.stringify(data);
                        }
     
                        if (operation === 'update') {
                            // build DrillHoleIntervalDto object with all ATT/CMT values to send back to server
                            var drillHoleInterval = { Id: data.Id, Name: data.Name, From: data.From, To: data.To };
                            drillHoleInterval.Attributes = [];
                            drillHoleInterval.Comments = [];
     
                            var attributeFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalAttribute });
                            $.each(attributeFields, function (idx, attributeField) {
                                drillHoleInterval.Attributes.push({
                                    Id: attributeField.AttributeDto.Id,
                                    LookupId: data[attributeField.FieldName.replace(/ /g, "_")]
                                });
                            });
     
                            var commentFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalComment });
                            $.each(commentFields, function (idx, commentField) {
                                drillHoleInterval.Comments.push({
                                    Id: commentField.CommentDto.Id,
                                    Value: ((data[commentField.FieldName.replace(/ /g, "_")] != "") ? data[commentField.FieldName.replace(/ /g, "_")] : null)
                                });
                            });
     
                            return kendo.stringify(drillHoleInterval);
                        }
     
                        // ALWAYS return options
                        return options;
                    }
                },
                schema: { model: { id : "Id" }},
                serverPaging: false,
                serverSorting: false,
                serverFiltering: false
                //,autoSync: true
            }),
            columns: gridColumns,
            dataBound: onDataBound,
            autoBind: false,
            navigatable: true,
            scrollable: false,
            editable: true,
            selectable: true,
            edit: function (e) {
                var grid = $("#ddhintgrid").data("kendoGrid");
                //grid.clearSelection();
                grid.select().removeClass('k-state-selected');
     
                // select the row currently being edited
                $('[data-uid=' + e.model.uid + ']').addClass('k-state-selected');
     
                e.container[0].focus();
            }
        };

    Here is a custom event to handle the 'Tab' keypress. The point of this is I want a new record automatically added to the grid if the user presses 'Tab' at the end of the last line:

    $("#ddhintgrid").keydown(function (e) {
                if (e.key == "Tab") {
                    var grid = $("#ddhintgrid").data("kendoGrid");
                    var data = grid.dataSource.data();
                    var selectedItem = grid.dataItem(grid.select());
                    var selectedIndex = null
     
                if (selectedItem != null) {
                    selectedIndex = grid.select()[0].sectionRowIndex;
     
                    if (selectedIndex == data.length - 1) {  // if the bottom record is selected
                        // We need to manually add a new record here so that the new row will automatically gain focus.
                        // Using $scope.addRecord() here will add the new row but cause the grid to lose focus.
                        var newRecord = { From: grid.dataSource.data()[selectedIndex].To };
     
                        var currentCmtFields = $.grep($scope.currentFields, function (e) { return e.DrillHoleTabFieldType == DrillHoleTabFieldTypeEnum.IntervalComment; });
     
                        $.each(currentCmtFields, function (idx, currentCmtField) {
                            newRecord[currentCmtField.FieldName.replace(/ /g, "_")] = null;
                        });
     
                        grid.dataSource.insert(data.length, newRecord);
     
                        // edit the new row
                        grid.editRow($("#ddhintgrid tr:eq(" + (data.length) + ")"));
     
                    }
                }
            }
        });

    Here is my template for the drop down column:

    $scope.dropDownTemplate = function (dataItem, fieldName) {
            var currentLookups = $.grep($scope.currentFields, function (e) { return e.FieldName == fieldName; })[0].AttributeDto.Lookups;
            var selectedLookup = $.grep(currentLookups, function (e) { return e.Id == dataItem[fieldName.replace(/ /g, "_")]; })[0];
     
        // With the custom dropdown editor when going from null to a value the entire lookup object (id, name) is placed in the
        // dataItem[field_name] instead of just the id. We need to replace this object with just the id value and return the name of
        // the lookup to the template.
        if (typeof selectedLookup == 'undefined' && dataItem[fieldName.replace(/ /g, "_")] != null) {
            selectedLookup = angular.copy(dataItem[fieldName.replace(/ /g, "_")]);
            dataItem[fieldName.replace(/ /g, "_")] = selectedLookup.Id;
        
     
        if (selectedLookup != null && selectedLookup != '') {
            return selectedLookup.Name;
        }
     
        else {
                return '';
        }
    };

     And finally here is the custom editor for the drop down column:

    $scope.dropDownAttEditor = function (container, options) {
        var editor = $('<input k-data-text-field="\'Name\'" k-data-value-field="\'Id\'" k-data-source="ddlDataSource" data-bind="value:' + options.field + '"/>')
            .appendTo(container).kendoDropDownList({
                dataSource: $.grep($scope.currentFields, function (e) { return e.FieldName == options.field.replace(/_/g, ' '); })[0].AttributeDto.Lookups,
                dataTextField: "Name",
                dataValueField: "Id"
            });
    };

    I know this is a lot to take in but if you have any questions just let me know.
    My ultimate goal is that I want the user to be able to navigate the grid using the 'Tab' key and edit every field without having to use the mouse.

     

  2. Answer
    Alexander Valchev
    Admin
    Alexander Valchev avatar
    2895 posts

    Posted 19 Feb 2016 Link to this post

    Hello Ian,

    The DropDownList should be focused when the cell enters in edit mode. Then you may use the DropDownList keyboard shortcuts to control it through the keyboard:
    • http://demos.telerik.com/kendo-ui/dropdownlist/keyboard-navigation

    For example in order to open it the users can use alt + down arrow.

    Regards,
    Alexander Valchev
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top