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

Grid throws an Javascript error on error returned from server

8 Answers 874 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Dragan
Top achievements
Rank 1
Dragan asked on 15 Mar 2013, 10:42 AM
Hello everybody,

I have a Grid placed on a view page in MVC application. The code looks like this:
@{
    ViewBag.Title = "Grid";
}
@section scripts {
    <script type="text/javascript">
        var wnd;
 
        var myModel = kendo.data.Model.define({
            id: "PrimaryKey",
            fields: {
                PrimaryKey: { type: "number", editable: false, nullable: false },
                FirstField: { type: "string" },
                SecondField: { type: "string" }
            }
        });
 
        var myDataSource = new kendo.data.DataSource({
            type: "json",
            transport: {
                read: {
                    url: "@Url.Action("List")",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                create: {
                    url: "@Url.Action("Create")",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                update: {
                    url: "@Url.Action("Update")",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                destroy: {
                    url: "@Url.Action("Delete")",
                    contentType: "application/json; charset=utf-8",
                    type: "POST"
                },
                parameterMap: function (data, type) {
                    if (type == "read") {
 
                        if (data.filter) {
                            data = $.extend({ sort: null, filter: data.filter.filters[0] }, data);
                        } else {
                            data = $.extend({ sort: null, filter: null }, data);
                        }
 
                        return JSON.stringify(data);
                    } else {
                        return JSON.stringify({ model: data });
                    }
                }
            },
            batch: false,
            pageSize: 3,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true,
            schema: {
                errors: function (response) {
                    if (response.Errors) {
                        alert(response.Errors);
                        myDataSource.cancelChanges();
                    }
                },
                aggregates: function (response) {
                    response.Aggregates;
                },
                data: function (response) {
                    return response.Data;
                },
                total: function (response) {
                    return response.TotalRecordCount;
                },
                model: myModel
            }
        });
 
        $(document).ready(function () {
            isCreating = false;
 
            $("#grid").kendoGrid({
                dataSource: myDataSource,
                height: 250,
                selectable: true,
                pageable: true,
                toolbar: [
                    { name: "create", text: "New item" }
                ],
                columns: [
                    {
                        field: "PrimaryKey",
                        title: "Primary Key",
                        attributes: {
                            style: "text-align: center"
                        },
                        width: 100
                    },
                    {
                        field: "FirstField",
                        title: "First Field",
                        attributes: {
                            style: "text-align: center"
                        }
                    },
                    {
                        field: "SecondField",
                        title: "Second Field",
                        attributes: {
                            style: "text-align: center"
                        },
                        width: 180
                    },
                    {
                        command: [
                              {
                                  name: "edit",
                                  text: { // sets the text of the "Edit", "Update" and "Cancel" buttons
                                      edit: "Edit me",
                                      update: "Save",
                                      cancel: "I give up"
                                  }
                              },
                              { text: "Delete", click: ShowConfirmation }
                        ],
                        // sets the title and the width of the commands column
                        title: " ",
                        width: "180px"
                    }
                ],
                editable: {
                    mode: "popup",
                    update: true
                },
                edit: function (e) {
                    if (isCreating) {
                        e.container.kendoWindow("title", "New item");
                        isCreating = false;
                    } else {
                        e.container.kendoWindow("title", "Item updated");
                    }
                }
            });
 
            wnd = $("#confirmationBox")
                        .kendoWindow({
                            title: "Brisanje stavke",
                            animation: false,
                            modal: true,
                            width: "370px"
                        }).data("kendoWindow");
 
            $(".k-grid-add").on("click", function () {
                isCreating = true;
            });
 
            $("#confirmationOKButton").click(function (e) {
                DoAjaxDelete();
 
                return false;
            });
 
            $("#confirmationCancelButton").click(function (e) {
                wnd.close();
 
                return false;
            });
        });
 
        function ShowConfirmation(e) {
            e.preventDefault();
 
            var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
            wnd.center().open();
 
            $("#deleteID").val(dataItem.SIzborID);
        }
 
        function DoAjaxDelete() {
            $.ajax({
                type: "POST",
                url: "@Url.Action("Delete")",
                data: $("#deletePopup").serialize(),
                success: function (response) {
                    if (response == "OK") {
                        //osvježimo grid
                        var first = myDataSource.get($("#deleteID").val());
 
                        myDataSource.remove(first);
                        myDataSource.sync();
 
                        //zatvorimo popup
                        wnd.close();
                    }
                    else {
                        alert('Delete failed for the following reason: ' + response);
                    }
                }
            });
        }
    </script>
    }
 
<h2>Grid</h2>
<p> </p>
 
<div id="grid"></div>
<div id="confirmationBox" style="display:none">
    <form id="deletePopup">
        <input type="hidden" id="deleteID" name="deleteID"/>
         
        <p class="confirmationQuestion" style="padding:10px 0"><span class="exclamationIcon" style="float:left; margin:0 7px 20px 0;"></span>Are you sure you want to delete this?</p>
 
        <a class="k-button" id="confirmationOKButton">Sure</a>
        <a class="k-button" id="confirmationCancelButton">Get me out of here</a>
    </form>
</div>
What I am trying to do here are two things:
1. I am not using standard confirmation box and I want to show a Kendo modal popup with my message. I did this via custom command button that shows Kendo window widget and based on chosen button fires a AJAX call for server to do the processing. If everything is OK, delete the row in data source and sync the datasource.
2. I am doing CRUD operations via JSON POST calls.

For both these things I have set up my server logic to work according to schema specification, i.e. return Data serialized object for Create/Edit/List operations and returning Error object if there is any kind of error. My error definition does this myDataSource.cancelChanges();, as I thought this would cancel any operation that it was trying to perform.

I am experiencing strange behavior. When I am doing the Create operation and fill the form and submit it, if there is a server-side validation that fails, I am returning an Error object which should fire the error event for datasource. It does and it goes OK.

I have noticed a strange behavior in sense that when I click for the second time to create the item and fill the form again with information that would return validation error it shows the alert message again but this time It gets stuck in JavaScript error: TypeError: d is undefined in following part of the unminified kendo.web.js file:
getter: function(expression, safe) {
return getterCache[expression] = getterCache[expression] || new Function("d", "return " + kendo.expr(expression, safe));
},
Any help on this is very welcome. Thanks.

Dragan

8 Answers, 1 is accepted

Sort by
0
Atanas Korchev
Telerik team
answered on 19 Mar 2013, 03:59 PM
Hi Dragan,

 This is indeed a very strange error. Getting "d is undefined" means that the something is trying to get a property of an undefined object. Is there a chance to send us something runnable? Or a jsFiddle/jsbin demo?

Regards,
Atanas Korchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dragan
Top achievements
Rank 1
answered on 20 Mar 2013, 07:41 AM
Hello Atanas,

There is a upload limit but actually it is very easy to set it up. All you have to do is create a new MVC app, grab KendoUI from NuGet, set up controller so it returns an error, and create a view with the code I already posted. Please download an example from here.
0
Accepted
Rosen
Telerik team
answered on 20 Mar 2013, 08:28 AM
Hi Dragan,

Thank you for sending us the sample. The behavior you have described is caused my incorrect handling of the errors. In order to handle errors you should use the error event of the DataSource, not its schema. The schema purpose is to retrieve the errors, if such exists, from the received response. Thus it should return the errors  in order to notify the DataSource that the subsequent response processing should be halted, which did not happen in your setup.

var myDataSource = new kendo.data.DataSource({   
     transport: {
        //..
     },
     //.....
     error: function (e) {
         if (e.errors) {
             alert(e.errors);
             this.cancelChanges();
         }
     },
     schema: {
         errors: "Errors",               
         //.....
    }
 });

Greetings,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dragan
Top achievements
Rank 1
answered on 21 Mar 2013, 07:22 AM
Hello Rosen,

Thank you. Your solution works. I have obviously overlooked this important part.

I have another question related to this and I am going to ask it here. If necessary I can move it to another post.

This way of handling errors works but has a drawback. Say the server returns some server-side validation or any other kind of error. This way it shows an alert window informing user that the error has occurred but once the user clicks OK on that alert box, the popup disappears if user was let's say trying to add a new item. How would I go about keeping that popup after I show the alert box with error?

Thanks.
0
Rosen
Telerik team
answered on 21 Mar 2013, 07:48 AM
Hello Dragan,

In order to achieve this you may handle the dataBinding event of the grid and to cancel it when and error occurs. This will prevent refreshing the grid content and closing the popup form. You may check this code library sample which demonstrates this approach. Although, the sample uses the ASP.NET MVC wrappers, the code is also applicable when using KendoUI Web.

Greetings,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dragan
Top achievements
Rank 1
answered on 22 Mar 2013, 03:56 PM
Rosen,

Thank you for that link, you are hitting the spot. This should be in the main documentation definitely.

I have implemented this and it is working in sense that it keeps the popup. I cannot only get the validation tooltips show right now, since MVC wrappers generate a span element for each field that is used for validation message and usual Kendo Web does not generate this, at least I have no idea on how to tell it to do it. Will I have to create the same span element for every field so it would be replaced with my validation tooltip?
0
Accepted
Rosen
Telerik team
answered on 25 Mar 2013, 08:31 AM
Hello Dragan,

In order to support this you could extend the logic to insert the Validator's message tooltip if such does not exist. Basically you should  insert the tooltip after the actual input element if the message container those not exists.

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dragan
Top achievements
Rank 1
answered on 25 Mar 2013, 09:18 AM
Good morning,

I have managed to make the example that you you provided link for work completely to what I needed. Thank you very much.
Tags
Grid
Asked by
Dragan
Top achievements
Rank 1
Answers by
Atanas Korchev
Telerik team
Dragan
Top achievements
Rank 1
Rosen
Telerik team
Share this question
or