JavaScript errors when Grouping using similar example to the Custom AJAX Binding sample

15 posts, 1 answers
  1. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 27 Jun 2013 Link to this post

    I'm getting a JavaScript error after I apply grouping.
    Unable to get property 'length' of undefined or null reference kendo.web.min.js, line 10 character 28275
    Step 1. See attached Drag to GroupBy row.png - Load the page and group any column
    Step 2. See attached JavaScript error when GroupBy.png, I get the JavaScript error.

    The code I am using looks to me to be identical to the Custom AJAX Binding sample code included in the examples, but I am getting this error?

    .CSHTML
    @(Html.Kendo().Grid<Fluid>()
        .Name("Grid")
        .Columns(columns => {
            columns.Bound(o => o.FluidID).Groupable(false);
            columns.Bound(o => o.Name);
            columns.Bound(o => o.Code);
            columns.Bound(o => o.Grade);
            columns.Bound(o => o.Manufacturer);
        })
        .Deferred()
        .Pageable()
        .Sortable()
        .Filterable()
        .Scrollable()
        .Groupable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("GetJsonData", "FluidKendo"))
        )
    )


    Controller Code:
    public ActionResult GetJsonData([DataSourceRequest] DataSourceRequest request)
    {
        List<Fluid> allFluids = MockFluids();
        // When drag column header into group by row the following JavaScript error occurs
        // JavaScript error IE: SCRIPT5007: Unable to get property 'length' of undefined or
        // null reference kendo.web.min.js, line 10 character 28275
        // JavaScript error Chrome: Uncaught TypeError: Cannot read property 'length' of undefined
        // --- Example taken from the Custom AJAX Binding example: CustomAjaxBindingController.cs
        var resultThatErrors = new DataSourceResult();
        resultThatErrors.Data = allFluids;
        resultThatErrors.Total = allFluids.Count();
     
        return Json(resultThatErrors);
    }
    If anyone is interested I have a Visual Studio 2012 Sample App to show the error download here: https://skydrive.live.com/redir?resid=3113F9DB92CC84B2!1997&authkey=!Nefhm5WSin4%24

    Refer to the attached Highlighted VS solution items.png for the highlighted items of interest.

    Thanks,
    Beau


  2. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 30 Jun 2013 Link to this post

    I still can't solve this JavaScript error when grouping.

    I have copied line for line the Custom AJAX Binding sample in which Grouping works as expected into a brand new empty MVC4 app and I still get the same error. I have even copied all the Scripts and CSS from the sample to ensure there are no script version issues etc. 

    It should not be this difficult, the example is very simple:

    Models/Fluid.cs
    public class Fluid
    {
        public string FluidGrade { get; set; }
        public string Manufacturer { get; set; }
    }
    Views/Home/Index.cshtml
    @(Html.Kendo().Grid<NEW_MVC_APP.Models.Fluid>()
        .Name("Grid")
        .Columns(columns => {
            columns.Bound(o => o.FluidGrade);
            columns.Bound(o => o.Manufacturer);
        })
        .Groupable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read(read => read.Action("CustomAjaxBinding_Read", "Home"))
        )
    )
    Controllers/HomeController.cs
    public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
     
            public ActionResult CustomAjaxBinding_Read([DataSourceRequest] DataSourceRequest request)
            {
                List<Fluid> allFluids = MockFluids();
     
                var result = new DataSourceResult()
                {
                    Data = allFluids,
                    Total = allFluids.Count
                };
     
                return Json(result);
            }
     
     
            public List<Fluid> MockFluids()
            {
                List<Fluid> fluids = new List<Fluid>();
     
                for (int i = 1; i <= 5; i++)
                {
                    Fluid fluid = new Fluid();
                    fluid.FluidGrade = "Grade " + i.ToString();
                    fluid.Manufacturer = "Manufacturer " + i.ToString();
                    fluids.Add(fluid);
                }
     
                return fluids;
            }
        }
     
    Can someone please help me and sanity check my code. It has to be something simple??? 

    I've created another sample solution NEW MVC APP here: http://sdrv.ms/14HoHli

    Thanks,
    Beau
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 01 Jul 2013 Link to this post

    Hi Beau,

     
    Current behavior is expected with the current configuration - please note that when the ServerOperations are enabled (by default) the PageSize configuration option of the Grid should be defined. In current scenario I would suggest to disable the ServerOperations:

    @(Html.Kendo().Grid<NEW_MVC_APP.Models.Fluid>()
        .Name("Grid")
        .Columns(columns => {
            columns.Bound(o => o.FluidGrade);
            columns.Bound(o => o.Manufacturer);
        })
        .Groupable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .ServerOperation(false)
            .Read(read => read.Action("CustomAjaxBinding_Read", "Home"))
        )
    )

    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 02 Jul 2013 Link to this post

    See below - Connection timeout issue when posting... Sorry
  6. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 02 Jul 2013 Link to this post

    See below - Connection timeout issue when posting... Sorry
  7. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 02 Jul 2013 Link to this post

    Thanks Vladimir,

    That did work but the example I am using is a contrived simplified example to isolate the JavaScript error issue. 

    My full implementation of the Grid includes server side paging, filtering and sorting, therefore I do believe I require the ServerOperation=True.

    Given your explaination above: If I set the PageSize = 10 and ServerOperation = True, I still get the JavaScript error. 

    What other config do I need to change to get Group by to function with ServerOperation=true 

    Updated simplified example:
    @(Html.Kendo().Grid<NEW_MVC_APP.Models.Fluid>()
        .Name("Grid")
        .Columns(columns => {
            columns.Bound(o => o.FluidGrade);
            columns.Bound(o => o.Manufacturer);
        })
        .Groupable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .ServerOperation(true)
            .PageSize(10)
            .Read(read => read.Action("CustomAjaxBinding_Read", "Home"))
        )
    )
    My "full" (real world) implementation that includes server side paging and sorting
    @(Html.Kendo().Grid(Model)
        .Name("Grid")
        .Columns(columns =>
            {
                columns.Bound(f => f.FluidID).Title("ID").Width(50).Hidden(true);
                columns.Bound(f => f.Name).Title("Name");
                columns.Bound(f => f.Code).Title("Code");
                columns.Bound(f => f.Grade).Title("Grade");
                columns.Bound(f => f.Manufacturer).Title("Manufacturer");
                columns.Bound(f => f.RowVersion).Title("RowVersion").Hidden(true).IncludeInMenu(false);
                columns.Command(command => { command.Edit().Text("Edit").UpdateText("Save").CancelText("Cancel"); command.Destroy(); }).Width(182);
            })
        .Deferred()
        .Resizable(resize => resize.Columns(true))
        .Reorderable(reorder => reorder.Columns(true))
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .Sortable()
        .ColumnMenu()
        .Scrollable(s => s.Height("auto"))
        .Navigatable()
        .Groupable()
        .Pageable(pager => pager
            .Numeric(true)
            .Info(true)
            .PreviousNext(true)
            .Refresh(true)
            .PageSizes(true))
        .Filterable(filterable => filterable.Extra(false))
        .Events(e => e
            .DataBound("fluidinline.gridOnDataBound"))
            //.Change("fluidinline.grid.OnChange"))
        .DataSource(dataSource => dataSource
            .Ajax()
            .ServerOperation(false)
            .PageSize(20)
            .Read(read => read.Action("EditingInline_Read", "FluidKendoInline")
                .Data("fluidinline.gridOnDataSourceReadGetAdditionalData"))
            .Create(create => create.Action("EditingInline_Create", "FluidKendoInline"))
            .Update(update => update.Action("EditingInline_Update", "FluidKendoInline"))
            .Destroy(destroy => destroy.Action("EditingInline_Destroy", "FluidKendoInline"))
            .Model(model =>
                {
                    model.Id(f => f.FluidID);
                    model.Field(f => f.FluidID).Editable(false);
                    model.Field(f => f.RowVersion).Editable(false);
                })
            .Events(events =>
                {
                    events.Error("fluidinline.gridOnAjaxError");
                    events.RequestEnd("fluidinline.gridOnRequestEnd");
       
                })
            )
    )
    Thanks again,
    Beau
  8. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 03 Jul 2013 Link to this post

    Hi Beau,

     
    If you need to use ServerOperations then you should modify the Controller to return paged, sorted, filtered and grouped data based on the current request - please check the example below: 

    public ActionResult CustomAjaxBinding_Read([DataSourceRequest] DataSourceRequest request)
    {
        List<Fluid> allFluids = MockFluids();
     
        var result = allFluids.ToDataSourceResult(request);
     
        return Json(result);
    }
    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  9. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 03 Jul 2013 Link to this post

    I think we are almost there.

    Grouping works if I use the following code thanks! 
    MapGridFilterPageOptions(request, searchFilter, resetPageNumber);
    FluidService service = new FluidService();
    List<Fluid> fluids = service.GetAllPaged(ref _GridFilterPagedOptions);
     
    var result = fluids.ToDataSourceResult(request);
    result.Total = _GridFilterPagedOptions.TotalRowsReturned;
     
    return Json(result);

    But... I must be missing something else.

    When Grouping is applied and I page to page 2  results.Data is empty after
    var result = fluids.ToDataSourceResult(request);

    See the attached screen shots:
    page 1 grouping.png shows what the results.data looks like after grouping on the first page = All is good :-)
    page 2 grouping.png shows I am returning 10 results using the ToDataSourceResult() and the result.Data has no data???

    Thanks again for your patience and support Vladimir,
    Beau
  10. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 04 Jul 2013 Link to this post

    So my question is, when using var result = fluids.ToDataSourceResult(request); why is results.Data empty (see screen shots above) after I page and have a grouping?

  11. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 05 Jul 2013 Link to this post

    Hi Beau,

     
    From the provided information we can only guess what the reason is - could you please provide runable sample where the issue is reproduced? This would help us identify the exact reason for this behavior.


    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  12. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 05 Jul 2013 Link to this post

    Will do. I'll send something through over the weekend.

    Thank you,
    Beau
  13. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 07 Jul 2013 Link to this post

    Hi Vladimir,

    New sample application here: SampleApp Download called SampleApp.zip.

    The app requires a small database. To setup the database create a DB called SAM2 and run the attached create.sql script, then modify the web.config SAM2Context connection string data source, initial catalog and userid password etc.

    Please review the following files in /SAM2.Web - MVC 4 app
    /SAM2.Web/Areas/Maintenance/Controllers/FluidKendoInlineController.cs and
    /SAM2.Web/Areas/Maintenance/Views/FluidKendoInline/Views/Index.cshtml

    I have implemented server side paging filtering and sorting and want only to return the required records for the particular page. For example if I have paged to page 3 and show 10 records per page, my database sproc only returns the 10 records for the page offset.

    I have isolated the issue as follows:
    What is the difference between the following ways of returning data?

    METHOD 1: Extension Method
    var result = data.ToDataSourceResult(request);
    result.Total = TotalRowsReturnedByQuery;
    return Json(result);
    METHOD 2: New DataSourceResult()
    var result = new DataSourceResult();
    result.Data = data;
    result.Total = TotalRowsReturnedByQuery;
    return Json(result);

    Method 1: Using the ToDataSourceResult() extension does enable grouping without the JavaScript error but when paging to a new page no data is displayed. Refer to the attached images:
    Method 1 - Extension Method - Page 1.png
    Method 1 - Extension Method - Page 2.png

    It looks like I am expected to return ALL records from page 1 to the current selected page for this to work? For example if I page to page 3 and return all results from page 1 i.e. 30 records instead of 10 records it works.

    Method 2: Creating a new DataSourceResult() paging works as expected but when grouping columns I get the JavaScript error "Unable to get property 'length' of undefined or null reference"

    I have included both approaches in the FluidKendoInlineController.cs, please uncomment as appropriate:
    // Method 1: Extension method
    // Problem: Paging doesn't work unless all data from the first page to the current page is returned?
    // var result = fluids.ToDataSourceResult(request);
    // result.Total = _GridFilterPagedOptions.TotalRowsReturned;
     
    // Method 2: New DataSoureResult
    // Problem: Group by columns causes JavaScript error
    var result = new DataSourceResult();
    result.Data = fluids;
    result.Total = _GridFilterPagedOptions.TotalRowsReturned;

    I would like server side paging to function as expected i.e. return only the required rows and be able to group columns.

    Thanks once again for all your help so far, and let me know if you require anything else.
    Beau
  14. Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 09 Jul 2013 Link to this post

    Hi Vladimir,

    This following stackoverflow post will give you some more context:

    http://stackoverflow.com/questions/14295924/todatasourceresult-extension-not-populating-datasourceresult-object

    It looks like the ToDataSourceResult() method expects all the data from the first page to the current "paged" page. i.e. if I was on page 5, it would expect my database query to return records for page 1 to page 5 even though I should only have to return the page 5 records.

    My alternative approach is to construct a new DataSourceResult() which allows me to return only the page of results but it errors when grouped.

    How can I get "TRUE" server side paging (only return the required page of records) to work with grouping. 

    Thanks,
    Beau
  15. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 10 Jul 2013 Link to this post

    Hi Beau,

     
    Basically the ToDataSourceResult extension method creates the paging, sorting, filtering and grouping of the data automatically for you - you should pass an IQueryable collection (the context) and the extension method will create the query to the DataBase for you. If you need to create custom Ajax binding however you should handle all operations manually - that why you receive error when you try to group the data. Please note that we already provide such example of "Custom Ajax binding" which is available witih KendoUI for ASP.NET MVC installation:

    • ..\Telerik\Kendo UI for ASP.NET MVC %VERSION%\wrappers\aspnetmvc\Examples\Areas\razor\Views\web\grid\customajaxbinding.cshtml

    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  16. Answer
    Beau
    Beau avatar
    19 posts
    Member since:
    Mar 2011

    Posted 10 Jul 2013 Link to this post

    Fixed. 

    Instead of returning a List<Fluid> I should be returning an IEnumerable<AggregateFunctionsGroup> when grouped.

    You mentioned "you should handle all operations manually" so I checked I was applying grouping and wasn't... Needed another set of eyes.

    As you suggested I only had to include the .ApplyGrouping(request.Groups) and extension methods from the "Custom Ajax Binding" sample which I had already used as a base but not called ApplyGrouping...

    Thanks for reading this novel of a post.

    My code now looks like:

    FluidService service = new FluidService();
    List<Fluid> fluids = service.GetAllPaged(ref _GridFilterPagedOptions);
    var fluidsQueryable = fluids.AsQueryable();
    IEnumerable data = fluidsQueryable.ApplyOrdersGrouping(request.Groups);
     
    var result = new DataSourceResult();
    result.Data = data;
    result.Total = _GridFilterPagedOptions.TotalRowsReturned;
     
    return Json(result);
Back to Top
UI for ASP.NET MVC is VS 2017 Ready