This is a migrated thread and some comments may be shown as answers.

Problem editing with multiple instances of same Grid

2 Answers 338 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Javier
Top achievements
Rank 1
Javier asked on 06 Jul 2018, 12:27 PM

I am showing multiple instances of the same grid in the same view. And everything works fine except if you try to edit a record on two grids at the same time.

The problem seems to be that the EditorFor elements created when switching to in-line edit mode all end up named the same, so the second set of editors don't work as expected (as-in, the DatePicker doesn't render, I just end-up with a non-formatted date in a regular textbox).

 

I tried adding an HtmlFieldPrefix to each partial (the helper to create the view is held within a PartialView that's called for each team).

That makes the actual editors render appropriately, but they don't get properly bound to the underlying model (as-in, I can see the datepicker, but it doesn't have the existing value, nor posts back to the model as expected).

 

As far as the model, the key portion would be with the Date fields, where I have the model decorated so that it shows the appropriate date picker.

The way I'm creating multiple grids is that I loop through a collection of teams and call a helper to create each grid with a separate Id.

[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
[UIHint("Date")]
public DateTime DateStart { getset; }
 
@helper TeamGrid(int id)
{
    @(Html.Kendo().Grid<KTeam>()
          .Name("gridTeam" + id)
          .DataSource
          (
              d => d
                  .Ajax()
                  .ServerOperation(false)
                  .PageSize(20)
                  .Model(model =>                   {
                      model.Id(u => u.Id);
                   })
                  .Events(events => events.Error("onError"))
                  .Read(r => r.Action("ReadTeam""Report").Data("dataTeamId(" + id + ")"))
                  .Update(u => u.Action("EditTeam""Report"))
                  .Sort(sort => sort.Add(s => s.Member).Ascending())
          )
          .Columns(columns =>           {
              columns.Bound(u => u.Id).Hidden();
              columns.Bound(u => u.Member).Width(200);
              columns.Bound(u => u.DateStart).Width(120);
              columns.Bound(u => u.DateEnd).Width(120);
              columns.Command(command => command.Edit()).Width(177);
          })
          .Filterable(f => f.Extra(false).Operators(o => o.ForString(s => s.Clear().Contains("Contains"))))
          .Sortable(s => s.SortMode(GridSortMode.MultipleColumn).AllowUnsort(true))
    ) }

 

2 Answers, 1 is accepted

Sort by
0
Konstantin Dikov
Telerik team
answered on 10 Jul 2018, 07:51 AM
Hello Javier,

In order for the editors to be bound correctly to the edited dataItem, their name should match exactly the name of the field, which is why it fails to bind the value when you change the names of the editors. I have to say that there is no workaround that I could suggest for this scenario, especially when the same model is bound all Grids. The only option would be to switch to Batch (InCell) edit mode, which will render only one editor at a time:

Best Regards,
Konstantin Dikov
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Matus
Top achievements
Rank 1
Iron
answered on 21 Apr 2022, 07:42 AM | edited on 21 Apr 2022, 07:51 AM

Hello Javier, Konstantin,

I had a similar issue.
I used a Kendo TabStrip. First tab contained a main grid of deliveries. Clicking on a row opened a new tab containing a Delivery detail (Form + Grid of products) = all generated from the same partial view.

The problem was, that after opening more detail tabs, technically all the grids were present on a single page, so I had to distinguish them by their own IDs.

A read-only grid would be no big deal. The form was also quite easy.

The problem came, when I started edit(InLine) of two grids. The first grid-edit row renders OK, but the second had broken Dropdowns.
As for Konstantin's solution (InCell edit), that's still not enough, because if you edit the same cell (e.g. Product delivery status - dropdown) in both grids, the second one opened is broken (can't render because ID is already present on page).
Allowing the user to have only one cell / line in edit mode was not suitable for me.

What's even worse, I used Edit templates in 3 columns (UIHint in model etc.), 2 of them were Kendo.Autocomplete with server-search functionality...

The solution took me more than 1 day of work. I had to:

- distinguish all the Form fields (inputs, buttons, datepickers...)
(note: since using DatePickerFor, I could not set the .Name(""), therefore I used HtmlAttribute @id=... )

@(Html.Kendo().DatePickerFor(m => m.OrderDate)
    ...
    .HtmlAttributes(new { @id = "orderDate" + Model.DeliveryId })

- distinguish every grid in partial view by Id, and add this parameter to every CRUD dataSource event.
Note: separate the DeliveryId with '_' because we will be looking for it in JavaScript.

@(Html.Kendo().Grid<DeliveryModel>() .Name("gridDeliveryDetail_" + Model.DeliveryId) ...

dataSource.Read(ev => ev.Action("GetDeliveryProducts", "Delivery", new { id = Model.DeliveryId }))
...

- but the worst pain was handling the JS events / JS functions called by grid.
Since in every event (onEdit, onDataBound, onClick, isVisible etc) there's a different object as 'e', it was not always possible to know, who's triggering the event (which grid ID), so in each, I had to make a different way up to the parent/sibling/child Grid Id, split it by '_' and get the deliveryId from there.
Note: setting a grid JS event function with brackets and parameters inside triggers the function on load (!) so that didn't work out.

// this event function with brackets is triggered on load
// not a solution @(Html.Kendo().Grid<DeliveryModel>() .Events(e => e .Edit("Delivery.List.OnEdit(" + Model.DeliveryId + ")") ...


Some examples of event handling:

var onDataBound = function(e){
    var grid = $(e.sender.element).data("kendoGrid");
    var gridId = $(e.sender.element).attr("id");
    var deliveryId = gridId.split('_')[1];
    ... //e.g. an AJAX call with the id }

// can a product (a dropDown on row edit/create) be of status New?
var canBeNew = function() {
        var grid = $(event.currentTarget).closest("[data-role=grid]").data("kendoGrid");
        var gridId = grid.element.attr('id');
        var deliveryId = gridId.split('_')[1];
        var canHaveNew = $('#deliveryCanHaveNew_' + deliveryId).val();  // a control in Form
        return { canBeNew: canHaveNew };
    }

- and the last (probably not your) problem were the Editor Templates - partial views with a single control
as for the partial view, I only had to somehow differ every generated control, so it's different. A NewGuid never fails me.

@model SomeModel
@{
    var uqId = Guid.NewGuid().ToString().Replace("-", string.Empty);
}

@(Html.Kendo()
    .DropDownListFor(m => m)
    .HtmlAttributes(new { @id = "Status" + uqId })
    ....

- and in these editors, the JS events were very complicated. Not for this Dropdown, but I had an AutoComplete with search functionality, onAdditionalData getting parameters to search (needed deliveryId there too)...
You probably don't need this, so I won't post it.

I hope this answer helps somebody to save a lot of time and nerves.

Have a nice day

Eyup
Telerik team
commented on 25 Apr 2022, 06:26 AM

Hi


Tags
Grid
Asked by
Javier
Top achievements
Rank 1
Answers by
Konstantin Dikov
Telerik team
Matus
Top achievements
Rank 1
Iron
Share this question
or