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

Remove on client all data from grid can not go to page 0

10 Answers 468 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
Dan asked on 02 May 2018, 02:09 PM

I have a page where one grid has to have the possibility to add/remove rows on the client before saving all the changes to the server.

The grid is created like this

@(Html.Kendo().Grid(Model.AssignedObjects)
          .Name("AssignedGrid")
          .Columns(columns =>
          {
              columns.Select().Width(35);
              columns.Bound(p => p.Description);
          })
          .Pageable(p => p.PageSizes(true)
                     .ButtonCount(5))
          .Sortable()
          .Scrollable()
          .HtmlAttributes(new { style = "height: 450px;" })
          .DataSource(dataSource => dataSource.Ajax()
                                   .ServerOperation(false)))

The remove is done using the below javascript code

function removeSelected() {
      var grid = $('#AssignedGrid').data('kendoGrid');
      var dataSource = grid.dataSource;
      var rows = grid.select();
      var data = rows.map(function () {
         return grid.dataItem($(this));
      });
      for (var i = 0; i < data.length; i++) {
         dataSource.remove(data[i]);
      }
      grid.clearSelection();
   }

On the remove function I had also had a code to go to the first page ( dataSource.page(1) ) but if I remove all the data going to page 1 would display the initial data. Now without the code to go to the first page it works by going to page 0 and displaying no items.

However I still have a problem when I change the number of records on a page I get again to the first page and the initial data. Is there a way to really remove the data, so regardless what actions I do (), not to get the initial data?

 

10 Answers, 1 is accepted

Sort by
0
Alex Hajigeorgieva
Telerik team
answered on 04 May 2018, 12:12 PM
Hi, Dan,

Thank you very much for the provided code snippet.

I would suggest using the selectedKeyNames() method instead, whereas the select() method only returns the current page. This distinction seems to be lacking from the documentation and I shall see to add it there so no one stumbles upon it in the future. Here is my suggested modification for the  custom code which removes selected items:

var dataSource = grid.dataSource;
 var selected = grid.selectedKeyNames();
$.each(selected, function(idx, key){
  var item = grid.dataSource.get(key);
  grid.dataSource.remove(item);
});
grid.dataSource.page(1);

Here is a runnable Dojo that I tested with for your reference:

https://dojo.telerik.com/@bubblemaster/AhURAzOX

Let me know what you think and if you need further assistance, please do not hesitate to ask.

Kind Regards,
Alex Hajigeorgieva
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
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 04 May 2018, 05:49 PM

Hi Alex,

Unfortunally that dojo you provided is not really the same situation as the MVC. I tried to make also a dojo when I placed the question but ended in the same situation as the one that I tried now to change your dojo (the data is not displayed in the grid).

So I updated your dojo to emulate what MVC produces by having the datasource transport do not do anything on read and added the data option setting to be the sampleData. Also on the grid I updated the pageable to have 3 options

however just like my first atempt to create a dojo the grid is loaded with nothing displayed in it just an empty row

https://dojo.telerik.com/avUSUduD.

If you manage to make it work here is the workflow that I need:

delete all the rows from the only one page (so all the rows have to fit in one page)

the grid should go to page 0 (by calling grid.dataSource.page(1) would load the initial data so it might need to comment it to get to the page 0)

change the number of item on the page (so my problem here is that when I do this the initial data is displayed even though I removed them)

0
Accepted
Alex Hajigeorgieva
Telerik team
answered on 08 May 2018, 02:39 PM
Hello, Dan,

Thank you for your feedback. Indeed there was a difference in the behaviour of the Kendo UI Grid. So I went ahead and prepared a test project which I believe behaves as you wish. Since this is a forum thread, I removed the Kendo.Mvc.dll but you may add it in the lib folder to run the project.

I made a little change in the Grid definition - I added the model id as well as set "PersistSelection(true)":

@(Html.Kendo().Grid(Model)
   .Name("AssignedGrid")
   .ToolBar(t=>t.Custom().Name("RemoveSelected").IconClass("k-icon k-i-trash"))
   .Columns(columns =>
   {
       columns.Select().Width(50);
       columns.Bound(p => p.ShipName);
   })
   .Pageable(p => p.PageSizes(true)
              .ButtonCount(5))
   .Sortable()
   .Scrollable()
   .PersistSelection(true)
   .HtmlAttributes(new { style = "height: 450px;" })
   .DataSource(dataSource => dataSource.Ajax()
   .Batch(true)
   .Model(m=>m.Id("OrderID"))         
      .ServerOperation(false))
 )

The handler of the toolbar custom command now uses the grid API - removeRow() method instead of the dataSource

$(".k-grid-RemoveSelected").on("click", function (e) {
    e.preventDefault()
    var grid = $("#AssignedGrid").data("kendoGrid")
    var dataSource = grid.dataSource;
    var selected = grid.select();
    $.each(selected, function (idx, row) {
       grid.removeRow(row);
    });
    grid.dataSource.page(1);
});

Let me know if this is the desired outcome when you get the chance to test my suggestion.

Kind Regards,
Alex Hajigeorgieva
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
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 05 Jun 2018, 12:52 PM

Hi Alex,

I manage to get to test your solution in my application and found that what I was missing and it was the most important part of this work is the line: .Model(m=>m.Id("OrderID")) . So you have to give an Id to the datasource in order for the removable to be permanent.

0
Alex Hajigeorgieva
Telerik team
answered on 07 Jun 2018, 08:03 AM
Hello, Dan,

The definition of a schema model id is crucial for the data source to work correctly.  

https://docs.telerik.com/kendo-ui/controls/data-management/grid/editing#define-fields-through-schema

The note is in the Kendo UI documentation, do you think we should add that in the MVC documentation as well, perhaps in all of the below articles or in another article for local data operations? Would you mind letting me know if you looked through them? In your opinion, what is the best place to add a note so that it is more visible?

https://docs.telerik.com/aspnet-mvc/helpers/grid/editing/batch-editing
https://docs.telerik.com/aspnet-mvc/helpers/grid/editing/ajax-editing
https://docs.telerik.com/aspnet-mvc/helpers/grid/editing/server-editing

Look forward to hearing back from you.

Kind Regards,
Alex Hajigeorgieva
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
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 07 Jun 2018, 08:30 AM

Hi Alex,

Honestly I did not know that the Model was crucial for datasource to work. Usually I add the model only when I want something special for the fields, like default value or if not editable. Also I had no problem not adding it to a grid just for viewing

As for the 3 links I don't think I have seen them before (or if I did I did not pay too much attention). Usually I look at the demos or search the web for similar situations and I get the kendo-ui version that I try to adapt to MVC 

0
Alex Hajigeorgieva
Telerik team
answered on 08 Jun 2018, 12:22 PM
Hello, Dan,

Thank you for your feedback. I will add a note to our backlog so that the requirement to have an "id" for editing is more visible. On a side note, the persistSelection property also requires the schema model id to be defined.

Kind Regards,
Alex Hajigeorgieva
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
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 13 Jun 2018, 06:20 AM

Hi Alex,

Please be aware that sometimes the Model.Id function throws an exception.

So I have the following configuration

@(Html.Kendo().DropDownListFor(m => m.DeviceDesignation)
              .DataTextField("Name")
              .DataValueField("Id")
              .HtmlAttributes(new
              {
                 @class = "form-control s-devicedesignation",
                 data_valuemapperurl = Url.Action("GetDeviceDesignationsValueMapper", "Common")
              })
              .Filter(FilterType.Contains)
              .OptionLabel(Localizer.GetString("Select a designation...").ToString())
              .DataSource(source => source.Ajax()
                                          .PageSize(50)
                                          .Read(read => read.Action("GetDeviceDesignations", "Common"))
                                          .Model(m => m.Id("Id"))
                                          .Events(events => events.Error("deviceclass.dataSourceError")))
              .Virtual(v => v.ValueMapper("deviceclass.deviceClassDesignationValueMapper"))
              .Deferred()

and I got this exception

System.NullReferenceException: Object reference not set to an instance of an object.
   at Kendo.Mvc.UI.Fluent.DataSourceModelDescriptorFactoryBase`1.Id(String fieldName)
   at AspNetCore._Views_DeviceClass_Edit_cshtml.<>c.<ExecuteAsync>b__19_4(DataSourceModelDescriptorFactory`1 m) in ...\Edit.cshtml:line 29
   at Kendo.Mvc.UI.Fluent.AjaxDataSourceBuilderBase`2.Model(Action`1 configurator)

The line 29 is the one with .Model(m => m.Id("Id"))

So it seems that not all the time the Model has to be defined.

0
Alex Hajigeorgieva
Telerik team
answered on 15 Jun 2018, 05:59 AM
Hello, Dan,

The schema model id is necessary for:

- grid editing to work correctly
- grid persistSelection to work correctly
- the dataSource get() method to work correctly

I suppose that the data in the provided snippet does not always have an Id field, hence the error?

In case this error is thrown during a Grid Create operation with a complex field, a default value for the DeviceDesignation model type should be provided in the grid data source definition. Let's say that the DeviceDesignation property is a DeviceDesignationViewModel class instance with two properties - Id and Name:

model.Field(p => p.DeviceDesignation).DefaultValue(new DeviceDesignationViewModel(){ Id = "abc", Name = "SomeName"});

The data source schema id of the dropdown data source is not necessary.

For a complete example, you may check the demo at:

https://demos.telerik.com/aspnet-mvc/grid/editing-custom

Kind Regards,
Alex Hajigeorgieva
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
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 15 Jun 2018, 09:01 AM

Hi Alex,

The dropdown was use outside of a grid and the data always had an Id for the returned values.

Also I assumed that the Model is necessary for the DataSource regardless of where it is used (Grid, DropDownList, TreeList, ListBox, etc...)

But you cleared my confusion that only in case of grid the Model is necessary.

Tags
Grid
Asked by
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
Answers by
Alex Hajigeorgieva
Telerik team
Dan
Top achievements
Rank 1
Iron
Iron
Veteran
Share this question
or