1
votes

In an MVC program, I am using a Kendo Grid to display a list of data items (Facilities in this case). The model for the grid contains many more columns than are being displayed and I have a separate area beside the grid where those values are displayed for the user to edit. As the user changes the values, they are reflected back in the Grid's datasource. If the user moves to another row without saving, they are prompted to save the changes.

The code for the grid:

    @(Html.Kendo().Grid(Model)    
    .Name("FacilityGrid")       
    .Columns(columns => {
        columns.Bound(p => p.Name).Width(100);
        columns.Bound(p => p.ShortDescription).Width(150);
        })
    .ToolBar(toolbar => toolbar.Create().Text("Add New Facility"))
    .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("FacilityPopup"))
    .Pageable()
    .Resizable(resize => resize.Columns(true)) 
    .Sortable()
    .Selectable()
    .Scrollable()
    .Filterable()
    .DataSource(dataSource => dataSource
        .Ajax()
        .PageSize(10)
        .Model(model => 
            {
                model.Id(p => p.FacilityID); 
                model.Field(p=>p.FacilityID).DefaultValue(new Guid("00000000-0000-0000-0000-000000000000"));
            })
        .Read(read => read.Action("Facility_Read", "Setup"))
        .Create(update => update.Action("Facility_Create", "Setup"))
        .Update(update => update.Action("Facility_Update", "Setup"))
        .Destroy(update => update.Action("Facility_Destroy", "Setup"))
        )
        .Events(events => events
        // Subscribe to the "change" event.
        .Change("rowChange")
        )

For now I just have some inputs to edit the additional data:

    <p id="FacilityID"> </p>
    <p> Facility Name: <input ID="Name" class="GridLinked" type="text"></p>
    <p> Description: <input ID="Description" class="GridLinked" type="text"></p>
    <p> Address 1: <input ID="Address1" class="GridLinked" type="text"></p>
    <p> Address 2: <input ID="Address2" class="GridLinked" type="text"></p>
    <p> City: <input ID="City" class="GridLinked" type="text"></p>
    <p> State: <input ID="State" class="GridLinked" type="text"></p>
    <p> Country: <input ID="Country" class="GridLinked" type="text"></p>

The values are set on the change event for the grid

function rowChange(e) { 
    // handle the "change" event
    // Get the values from the Grid to display in the detail area
    $("#Name").val(this.dataItem(this.select()).Name);
    $("#FacilityID").text(this.dataItem(this.select()).FacilityID);
    $("#Description").val(this.dataItem(this.select()).Description);
    $("#Address1").val(this.dataItem(this.select()).Address1);
    $("#Address2").val(this.dataItem(this.select()).Address2);
    $("#City").val(this.dataItem(this.select()).City);
    $("#State").val(this.dataItem(this.select()).State);
    $("#Country").val(this.dataItem(this.select()).Country);

    if (this.dataSource.hasChanges()) {
        if (confirm("You have unsaved changes. Do you want to save them?")) {
            $('#FacilityGrid').data('kendoGrid').saveChanges();
        }
        else {
            $('#FacilityGrid').data('kendoGrid').cancelChanges();
        }
    };
}    

and the datasource for the grid is updated with change to the input fields.

 $(".GridLinked").change(function (event) {
     var grid = $('#FacilityGrid').data('kendoGrid');
// See if there are any pending changes
   debugger;

     var cell = event.target;
     var selectedRow = grid.select();
     var selectedRowIndex = selectedRow.index();
     grid.dataSource.data()[selectedRowIndex].set(cell.id, cell.value);
     grid.select(selectedRowIndex);
    // Set the focus back to the Grid
});

The problem I am facing is that when cell values are set in the grid, the focus indicator (highlighted row) goes away and when I attempt to set it back again (using Grid.select(selectedRowIndex)), it causes the rowChange event to fire on the grid and my handler throws an error

JavaScript runtime error: Unable to get property 'Name' of undefined or null reference

Does anyone have any suggestions on how to have some sort of indicator as to the selected row in the grid?

Is this a good design practice, to manipulate the grid datasource directly?

1
The manipulations you are doing are fine. You can actually use grid.dataItem(selectedRow) which should return you a data item for that row - instead of going inside the datasource. Please take into account grid.select() might return several rows for multiselection grids - Alex Sorokoletov
BTW, did you submit the issue to Kendo Telerik forum? - Alex Sorokoletov

1 Answers

0
votes

You can highlight a selected row by painting the the selected grid using the dataSource.view(). I will advice you to do the following in the rowChange event

var cell = event.target;  var selectedRow = grid.select();   
var selectedRowIndex = selectedRow.index() 
var dataView = this.dataSource.view();  
$("#FacilityGrid tbody").find("tr[data-uid=" + selectedRowIndex + "]").css("backgroundcolor", "grey");

Hope this helps ...happy Coding