Jquery grid not loading data even though Json is returned

8 posts, 0 answers
  1. Frank
    Frank avatar
    9 posts
    Member since:
    Sep 2016

    Posted 30 Apr Link to this post

    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;
    }

     


  2. Frank
    Frank avatar
    9 posts
    Member since:
    Sep 2016

    Posted 30 Apr in reply to Frank Link to this post

    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;
     }

     

  3. Tsvetomir
    Admin
    Tsvetomir avatar
    259 posts

    Posted 01 May Link to this post

    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.
  4. Frank
    Frank avatar
    9 posts
    Member since:
    Sep 2016

    Posted 08 May in reply to Tsvetomir Link to this post

    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)
                            };
                        }
                    }


  5. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    694 posts

    Posted 10 May Link to this post

    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.
  6. Frank
    Frank avatar
    9 posts
    Member since:
    Sep 2016

    Posted 10 May in reply to Alex Hajigeorgieva Link to this post

    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,
  7. Frank
    Frank avatar
    9 posts
    Member since:
    Sep 2016

    Posted 10 May Link to this post

    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 
  8. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    694 posts

    Posted 14 May Link to this post

    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.
Back to Top