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

Cannot read property 'removeClass' error after calling .setOptions

6 Answers 1130 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Alex
Top achievements
Rank 1
Alex asked on 23 Mar 2021, 03:44 PM

I'm having an issue that I need help with.

First, I'll explain what I need to do. I need to set three properties on a Grid

    1.- The "pageSizes" (the options on the "items per page" dropdown).

    2. The "pageSize" (default page size for the grid).

    3.- The "height".

I'm doing this using the "setOptions" method, like this:

        grid.autoBind = false;
        grid.setOptions({
            groupable: true
            , pageable: {
                pageSizes: selPageSizes,
                pageSize: selDefaultPageSize
            }
            , dataSource: { pageSize: selDefaultPageSize }
            , height: selGridHeight
        });       

This is working fine, but I'm getting an error. The grid is refreshed after calling the .setOptions method (I understand that it is the expected behavior) and I get the "Cannot read property 'removeClass' of null" (screenshot attached, along with the screenshot of the code that is triggering this error).

I tried setting the "autoBind" property to "false" before calling the .setOptions method, but I'm still getting the error.

I've checked on the forum, and I found the following post:

   https://www.telerik.com/forums/i-m-sometimes-getting-this-error-ucaught-typeerror-cannot-read-property-%27removeclass%27-of-undefined

I tried what was suggested there, but some things won't apply, and the others won't work (BTW, the first link is broken, which was the most promising one).

So, is there a way that I can prevent the grid to refresh after calling .setOptions? Or there's something that I can do to avoid the error, if the grid is refreshed?

Or is there any other way to set the three properties that I mentioned at the beginning of the post?

 

6 Answers, 1 is accepted

Sort by
0
Georgi Denchev
Telerik team
answered on 26 Mar 2021, 01:39 PM

Hi, Alex,

Using setOptions is the correct approach to modify the grid options.

I don't see anything wrong with the provided code snippet, so my assumption is that the problem comes from another configuration. I am attaching a sample project using the same code, could you modify it so the issue is reproducible and send it back to me? I'll then examine it and come back to you with an appropriate answer.

I'll be looking forward to your reply.

Best Regards,
Georgi Denchev
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Alex
Top achievements
Rank 1
answered on 30 Mar 2021, 11:14 PM

I've modified the code and a zip file with all the file is attached.

I'll try to explain the changes:

I believe that my issue is that I'm calling the SetOptions method on the DataBound event. So, I added that event to the grid on the View. The event is calling the "onDatabound_gridId" JS function, and this function is calling another function named "setKendoGridDataBoundEvents", which also calls the "updatePageSizes" function. I know that is too many function calling, but I tried to mimic the way the code is in my project.

This last function is the one that is actually calling the SetOptions method of the grid (line 106). I also added some log calls to verify the flow of the program.

As you can see in the screen print that I'm also attaching, when the "updatePageSizes" finishes, an error is raised and it interrups the flow of the program.

Again, I believe that the reason for the error is that the SetOptions method is being called in the DataBound event.

Please let me know if this helps.

 

NOTE: I tried to attach the zip file with the code, but I keep getting the error "The selected file(s) cannot be attached because it may exceed the maximum attachment size (2 MB) or is from not allowed type (allowed: .jpg, .jpeg, .gif, .png, .zip)."

0
Alex
Top achievements
Rank 1
answered on 30 Mar 2021, 11:20 PM

I just checked and the zip file that you attached on your reply is also larger than 2MB.

Is there another way that I can upload the zip file with the code? There's no way that I can make it smaller than 2MB.

I'm attaching the error screen. Also, below is the code for the entire "Index.cshtml" file, which is the only file that I modified.

 

<button class="k-button" id="btn">Set Options</button>

<div class="row">
    <div class="col-12">
        @(Html.Kendo().Grid<GridSetOptionsRemoveClassError.Models.OrderViewModel>()
            .Name("grid")
            .Columns(columns =>
            {
                columns.Bound(p => p.OrderID).Filterable(false);
                columns.Bound(p => p.Freight);
                columns.Bound(p => p.OrderDate).Format("{0:MM/dd/yyyy}");
                columns.Bound(p => p.ShipName);
                columns.Bound(p => p.ShipCity);
            })
            .Pageable()
            .Sortable()
            .Scrollable()
            .Filterable()
            .HtmlAttributes(new { style = "height:550px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .Read(read => read.Action("Orders_Read", "Grid"))
            )
            .Events(e=>e.DataBound("onDataBound_gridId"))
        )
    </div>
</div>

<script>
    $("#btn").click(function (e) {
        var selPageSizes = 5,
            selDefaultPageSize = 10,
            selGridHeight = 800;

        let grid = $("#grid").data("kendoGrid");
        grid.setOptions({
            groupable: true
            , pageable: {
                pageSizes: selPageSizes,
                pageSize: selDefaultPageSize
            }
            , dataSource: { pageSize: selDefaultPageSize }
            , height: selGridHeight
        });
    });

    function onDataBound_gridId(e) {
        console.log("*** ALEX - Entered onDataBound_gridId");
        setKendoGridDataBoundEvents(e, "", "EXPANDED");
    }

    function setKendoGridDataBoundEvents(e, panelNoRecordsFoundMsg) {
        console.log("*** ALEX - Entered setKendoGridDataBoundEvents");
        updatePageSizes(e);
    }

    function updatePageSizes(e) {
        //We'll have three different "types" of grids: BASIC, EXPANDED AND JUMBO.
        //Depending on the type of grid, the following properties will change:
        //For BASIC:    PageSizes (5, 10, 20); PageSize (10); grid height (200px). This is the Kendo default values
        //For EXPANDED: PageSizes (10, 20, 50); PageSize (20); grid height (500px)
        //For JUMBO:    PageSizes (20, 50, 100); PageSize (50); grid height (600px)
        console.log("*** ALEX - Entered updatePageSizes");

        //Now, depending on the gridSize parameter, define which values to use
        var selPageSizes;
        var selDefaultPageSize;
        var selGridHeight;

        //Set the different grid properties
        //We'll use a session variable to check if this code was already executed, to make sure that it runs only one time.
        //Since this is being called from the DataBound event, if we don't do this, then it will loop forever
        var gridId = e.sender.element[0].id;
        var grid = e.sender;

        //Get the session variable
        var gridSize = "JUMBO"
        var gridType = sessionStorage.getItem("gridType");
        console.log("*** gridType var: " + gridType);
        if (gridType !== gridSize) {
            console.log("*** Entered gridType IF");
            //console.log("*** ALEX. gridSize is: " + gridSize);
            var jumboSizes = "20,50,100";
            //Strip the values that I got from the AppSettings as CSV
            var jumboSizes1 = jumboSizes.split(",");
            var pageSizesJumbo1 = [];
            for (i = 0; i < jumboSizes1.length; i++) {
                //First, check if the value is valid (numeric)
                pageSize = jumboSizes1[i].trim();
                pageSizesJumbo1.push(pageSize);
            }
            selPageSizes = pageSizesJumbo1;
            selDefaultPageSize = 20;
            selGridHeight = 400;

            //Set the session variable
            sessionStorage.setItem("gridType", gridSize);
            //sessionStorage.setItem(gridId + "IsDataboundCallback", 1);

            //********** Set the autobind property
            var gridAutoBind = grid.autoBind;
            //Set the default page size and height
            console.log("*** Alex Setting Options: ");
            grid.autoBind = false;
            grid.setOptions({
                groupable: true
                , pageable: {
                    pageSizes: selPageSizes,
                    pageSize: selDefaultPageSize
                }
                , dataSource: { pageSize: selDefaultPageSize }
                , height: selGridHeight
            });

            console.log("*** Alex After Setting Options: ");
        }
    }
</script>

 

0
Georgi Denchev
Telerik team
answered on 02 Apr 2021, 01:20 PM

Hi, Alex,

Thank you for providing additional details.

You are correct, the grid's setOptions method should not be used inside Grid events, nor any functions that may be related to the data binding of the grid.

I'm assuming you want to execute setOptions when the page first loads in which case you can use JQuery's document.ready event which is fired once the page has fully loaded.

<script>
    $(function() {
        let grid = $("#grid").data("kendoGrid");
        grid.setOptions(options);
    });
</script>

Let me know if there are other reasons as to why you want to use the DataBound event and I'll suggest workarounds.

Best Regards,
Georgi Denchev
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Alex
Top achievements
Rank 1
answered on 02 Apr 2021, 09:39 PM

We have a big project, with hundreds or maybe thousands of grids being used in the project.

We need to make sure that we have a standard look and feel for each of the grids. We set some properties of the grid in the DataBound event, since some properties of the grid are not available or displayed on the document.ready event. Since we are already using the DataBound event, I wanted to use it to setup the three properties (PageSizes, pagesize and Height).

I'm not sure if it will work on the document ready, but I will try it. but again, we would like to have all the code centralized in the DataBound event.

0
Georgi Denchev
Telerik team
answered on 07 Apr 2021, 01:48 PM

Hello, Alex,

In the current scenario the document.ready should work as you are setting predefined values to the grid. Document.Ready might not work when you are trying to use the Grid's data or methods related to the data, because it hasn't fully loaded. On page load the Widget itself is fully initialized so setOptions will work.

Additionally you can call setOptions from within a setTimeout function if you need the data to be fully loaded, however calling it from widget events is not possible.

Best Regards,
Georgi Denchev
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Grid
Asked by
Alex
Top achievements
Rank 1
Answers by
Georgi Denchev
Telerik team
Alex
Top achievements
Rank 1
Share this question
or