Jquery grid not loading data even though Json is returned

2 Answers 3839 Views
Grid
Frank
Top achievements
Rank 1
Frank asked on 30 Apr 2019, 08:50 AM

I am having an issue which I am hoping is obvious but that I haven't been able to figure out.

I have a grid that when I use call the Read controller the MVC grid it works perfectly fine as below.

@(Html.Kendo().Grid<ProductModel>()
 .Name("grid1")
 .Columns(columns =>
{
 columns.Bound(p => p.Id).Filterable(false);
 columns.Bound(p => p.Name);
})
  .Pageable()
  .Sortable()
  .Scrollable()
  .Filterable()
  .HtmlAttributes(new { style = "height:550px;" })
  .DataSource(dataSource => dataSource
  .Ajax()
  .PageSize(20)
  .Read(read => read.Action("ProductRead", "Admin"))
  )
)

 

But when I use Jquery to create the grid dynamically it makes the call to the controller and retrieves the same JSON correctly as below, but the grid is always blank.  The databound event also

 

{"Data":[{"Id":1,"Name":"Testing1"},{"Id":2,"Name":"Testing2"},{"Id":3,"Name":"Testing3"},],"Total":3,"AggregateResults":null,"Errors":null}

Here is the javascript.  I must be missing something:

<script>
CreateGrid("myGrid");
 
function CreateGrid(gridID) {
        var dataSource = new kendo.data.DataSource({
            //type: "odata",
            transport: {
                read: function (options) {
                    $.ajax({
                        url: "/Admin/Wells/ReadAll",
                        dataType: "json",
                        data: {
                            models: kendo.stringify(options.data.models)
                        },
                        success: function (result) {
                            options.success(result);
                        }
                    });
                },
               parameterMap: function (options, operation) {
                    if (operation !== "read" && options.models) {
                        return {
                            models: kendo.stringify(options.models)
                        };
                    }
                }
            },
            batch: true,
            pageable: true,
            schema: {
                model: {
                    id: "Id",
                    fields: {
                    "Id": { "type": "number", "nullable": false },
                    "Name": { "type": "string", "nullable": false }
                }
                }
            }
        });
 
 
        $(gridID).kendoGrid({
            sortable: true,
            autoBind: false,
            dataSource: dataSource,
            filterable: true,
            columnMenu: true,
            resizable: true,
            selectable: "single",
            autoFitColumn: false,
            pageable: {
                pageSize: 10 // specifying the pagesize inside the datasource fixed my problem (Nan-Nan of 1 items)
            },
            //columns: myColumnObject,
            columns: [{ field: "Id", minResizableWidth: "125px", type: "number" },
            { field: "Name", minResizableWidth: "350px" }
            ],
            editable: "popup"
        });
        //Now load the grid with data
        var grid = $(gridID).data("kendoGrid");
        grid.bind("dataBound", grid_dataBound);
        grid.dataSource.fetch();
 
}
 
function grid_dataBound(e) {
    console.log("dataBound");
}
</script>

 

and for reference here is the controller it hits.

Productcontroller.cs

public ActionResult ReadAll([DataSourceRequest] DataSourceRequest request)
{
    var data = productService.Read();
    var serializer = new JavaScriptSerializer();
    var result = new ContentResult();
    serializer.MaxJsonLength = Int32.MaxValue; // Whatever max length you want here
    result.Content = serializer.Serialize(data.ToDataSourceResult(request));
    result.ContentType = "application/json";
    return result;
}

productService.cs

public IEnumerable<ProductModel> Read()
{
    return GetAll();
}

public IQueryable<ProductModel> GetAll()
{
     var wells = entities.WellModel.AsNoTracking().AsQueryable();
    return wells;
}

 


Frank
Top achievements
Rank 1
commented on 30 Apr 2019, 08:53 AM

Sorry I copy and pasted the wrong productservice.cs and I can't edit my post.  That last ProduceService.cs is actually this:

public IEnumerable<ProductModel> Read()
{
    return GetAll();
}
 
 public IQueryable<ProductModel> GetAll()
 {
      var products = entities.ProductModel.AsNoTracking().AsQueryable();
 
     return products;
 }

 

2 Answers, 1 is accepted

Sort by
0
Tsvetomir
Telerik team
answered on 01 May 2019, 01:12 PM
Hi Frank,

I have investigated the provided code snippets. The server-side and the response from the server looks correct to me. As you may have noticed the response is actually a JSON object - "Data" which contains a collection. Generally, the data source of the grid is configured to work with collections. Now that an object is passed, the collection has to be specified explicitly:

schema: {
    data: 'Data',
    model: {
    // . . .

Also, the type of the data source currently is actually "aspnetmvc-ajax" instead of "odata". What this gives is predefined configuration settings. 

Try these suggestions and let me know in case the data is still not loaded to the grid. 


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Frank
Top achievements
Rank 1
commented on 08 May 2019, 07:55 AM

Hi Tsvetomir,

Thank you for that.  I am now able to read the data and have pagination for large datasets by referencing Data in the schema and also changing the transport to 'aspnetmv-ajax'.

The issue I have now unfortunately is when trying to update the data.  I was able to do it before without a problem... but now the update does not get triggered if I leave the update code like it was before.

update: function (options) {
                    alert("Is this being triggered?");
                    $.ajax({
                    url: "/Admin/Wells/Update",
                        data: {
                            models: kendo.stringify(options.data.models)
                    },
                    type: "post"
                    });
                },

If I change it to use what I suspect is the MVC way of doing a read by doing this... it triggers the Update function in the controller but the model is no longer being passed (as I am unable to figure out how to pass the ParameterMap options).

Is there something I am missing here?

update: "/Admin/Wells/Update",


parameterMap: function (options, operation) {
                    if (operation !== "read" && options.models) {
                        return {
                            models: kendo.stringify(options.models)
                        };
                    }
                }


0
Alex Hajigeorgieva
Telerik team
answered on 10 May 2019, 07:52 AM
Hi, Frank,

When the Kendo UI Grid Data Source is set as the built-in type "aspnetmvc-ajax", there is no need to add a parameter map because it will be done internally. Just ensure that all of the CRUD operations are defined as an object. Since you will be using the predefined data source type, ensure that the action methods accept the expected parameters and return the expected response, too:

// Read      
 public ActionResult Orders_Read([DataSourceRequest]DataSourceRequest request)
{
    return Json(orders.ToDataSourceResult(request));
}
 
// Update
public ActionResult Orders_Update([DataSourceRequest]DataSourceRequest request, OrderViewModel order)
{
   // find and update order in db
    return Json(new[] { order }.ToDataSourceResult(request));
}

I have attached a project here with full CRUD operations in an Ajax bound jQuery grid for your reference, too.

I would like to use this opportunity to give you an insider tip.The easiest way to "translate" an existing UI for ASP.NET MVC Grid declaration is to inspect the dom and see what the wrappers have generated. You can then copy the serialized grid settings into a js beautifying site like https://beautifier.io/ to see these settings in a human-readable format. 

- Open the Developer tools, find the grid element and look for the script that is placed immediately after:

This is from the inline editing demo for MVC:



After pasting that in the jsbeautifier and extracting the data source alone, here is what you should have (I removed unnecessary auto generated settings for brevity):

"dataSource": {
     "type": "aspnetmvc-ajax",
     "transport": {
         "read": {
             "url": "/aspnet-mvc/Grid/EditingInline_Read"
         },
         "update": {
             "url": "/aspnet-mvc/Grid/EditingInline_Update"
         },
         "create": {
             "url": "/aspnet-mvc/Grid/EditingInline_Create"
         },
         "destroy": {
             "url": "/aspnet-mvc/Grid/EditingInline_Destroy"
         }
     },
     "pageSize": 20,
     "serverPaging": true,
     "serverSorting": true,
     "serverFiltering": true,
     "serverGrouping": true,
     "serverAggregates": true,
     "schema": {
         "data": "Data",
         "total": "Total",
         "errors": "Errors",
         "model": {
           "id": "ProductID",
           "fields": {
              "ProductID": {
                 "type": "number"
               }
             /* other model fields*/
             }
           }
        }
      }

Let us know in case further questions arise.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Frank
Top achievements
Rank 1
commented on 11 May 2019, 02:00 AM

Thank you so much Alex!! that was brilliant.

I was so close to having this working myself and in the end it was the fact I still had the batch parameter set to true in the grid properties.  As soon as I commented this out the model was being passed correctly to the controller.

Without your attached demonstration I probably wouldn't have noticed it.   Thanks again for taking the time to give the complete solution. 

//batch: true,   --Comment out.  This was causing the model to be passed as null
pageSize: 20,
serverPaging: true,
Frank
Top achievements
Rank 1
commented on 11 May 2019, 02:36 AM

Oh and can I also say that tip about translating the grid declaration to see what the wrappers have generated is awesome.  That tip alone would have saved me a week of pain trying to replicate the MVC grid functionality to Jquery. Thanks again 
Alex Hajigeorgieva
Telerik team
commented on 14 May 2019, 11:12 AM

Hi, Frank,

Thank you very much for your kind comments.

I am very pleased to hear that the tip to use the serialized settings and sample project were helpful to you. I hope that with this communication being in a forum thread would help others find answers quicker.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
R.D. Henry and Co.
Top achievements
Rank 2
Iron
Iron
Iron
commented on 24 Feb 2020, 10:58 PM

I know this is an old post but can someone please assist me.  I have a grid formatted as:

   @(Html.Kendo().Grid<Core.Models.Page1ViewModel>()
             .Name("grid")
             .Columns(columns =>
             {
                 columns.Bound(c => c.WO).Width(140);
                 columns.Bound(c => c.ProdDate).Width(190);
                 columns.Bound(c => c.FinishDate).Width(190);
                 columns.Bound(c => c.Lines).Width(100);
                  columns.Bound(c => c.WWComp).Width(140);
                 columns.Bound(c => c.FinComp).Width(140);
                 columns.Bound(c => c.Wood).Width(110);
                 columns.Bound(c => c.Finish).Width(110);
                  columns.Bound(c => c.Notes).Width(110);
             })
             .HtmlAttributes(new { style = "height: 380px;" })
             .Scrollable()
             .Groupable()
             .Sortable()
             .Pageable(pageable => pageable
                 .Refresh(true)
                 .PageSizes(true)
                 .ButtonCount(5))
             .DataSource(dataSource => dataSource
                 .Ajax()
                 .Read(read => read.Action("Page1_Read", "Home"))
             )

My controller is:

[AcceptVerbs("Post")]
        public IActionResult Page1_Read([DataSourceRequest] DataSourceRequest request)
        {          
            return Json(GetPage1().ToDataSourceResult(request));
        }
        private static IEnumerable<Page1ViewModel> GetPage1()
        {
           using (var sqlPage1 = new MyContext())
            {
                

                return sqlPage1.Page1.ToList().Select(myPage1 => new Page1ViewModel
                {
                    WO = myPage1.Wo,
                    ProdDate = Convert.ToDateTime(myPage1.WwprodDate),
                    FinishDate = Convert.ToDateTime(myPage1.FinishProdDate),
                    Lines = Convert.ToInt32(myPage1.Lines),
                    WWComp = Convert.ToInt32(myPage1.LinesComp),
                    FinComp = Convert.ToInt32(myPage1.LinesCompFin),
                    Wood = myPage1.Wood,
                    Finish = myPage1.Finish,
                    Notes = myPage1.Notes
                }).ToList();
                
            }
        }

and my model is:

public class Page1ViewModel
    {       
        public string WO { get; set; }
        public DateTime ProdDate { get; set; }
        public DateTime FinishDate { get; set; }
        public int Lines { get; set; }
        public int WWComp { get; set; }
        public int FinComp { get; set; }
        public string Wood { get; set; }
        public string Finish { get; set; }
        public string Notes { get; set; }
    }

Also I am using aspnetcore 2.2, I can see data being return from the return Json(GetPage1().ToDataSourceResult(request)), I see it it debug mode however the data never gets displayed to the Grid's UI.  Please help.

 

R.D. Henry and Co.
Top achievements
Rank 2
Iron
Iron
Iron
commented on 24 Feb 2020, 11:05 PM

I solved my issue by adding the following line to my startup.cs file:

services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

 

Tags
Grid
Asked by
Frank
Top achievements
Rank 1
Answers by
Tsvetomir
Telerik team
Alex Hajigeorgieva
Telerik team
Share this question
or