Add and Update still show entry even when model errors are returned

6 posts, 2 answers
  1. Answer
    Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 30 Apr 2013 Link to this post

    I am having problems with InLine add and update. If I enter a item that fails the server side validation then the item is still shown as entered/updated. I have followed your examples and looked for threads on this issue, but only found things on PopUp which don't seem to apply here:

    The code for add in MVC4 is given below (note: it fails on the ModelState.IsValid, which is correct
    [Authorize]
    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult AjaxServiceCreate([DataSourceRequest] DataSourceRequest request, ISmServiceDto newItem, ICreateSmService service)
    {
        if (newItem != null && ModelState.IsValid)
        {
            var response = service.Create(newItem);
            if (!response.IsValid)
                response.CopyErrorsToModelState(ModelState);
        }
     
        return Json(new[] { newItem }.ToDataSourceResult(request, ModelState));
    }
    My razor view is:
    @model bool
     
    @{
        ViewBag.Title = "Services";
    }
     
    <h2>Services</h2>
     
    @*<div id="message" class="Message"></div>*@
    @Html.AntiForgeryToken()
     
    @(Html.Kendo().Grid<ServiceLayer.Models.DTOs.SmServiceDto>()
          .Name("Services")
          .Columns(columns =>
                       {
                           columns.Bound(p => p.SmServiceId).Hidden();
                           columns.Bound(p => p.ShortName);
                           columns.Bound(p => p.FullName);
                           columns.Bound(p => p.Locked);
                           if (@Model)
                           {
                               columns.Command(command => { command.Edit(); command.Destroy(); }).Width(172);
                           }
                       })
          .ToolBar(toolbar =>
                       {
                           if (@Model)
                           {
                               toolbar.Create();
                           }
                       })
          .Editable(editable => editable.Mode(GridEditMode.InLine))
          .Pageable()
          .Sortable()
          //.Scrollable()
          //.HtmlAttributes(new {style = "height:430px;"})
          .DataSource(dataSource => dataSource
                                        .Ajax()                                 
                                        .PageSize(10)
                                        .Events(events => events.Error("error_handler"))
                                        .Model(model =>
                                                   {
                                                       model.Id(p => p.SmServiceId);
                                                       model.Field(x => x.SmServiceId).Editable(false);
                                                       model.Field(x => x.Locked).Editable(false);
                                                   })
                                        .Create(x => x.Action("AjaxServiceCreate", "Model").Type( HttpVerbs.Post).Data("sendAntiForgery"))
                                        .Read(read => read.Action("AjaxServiceRead", "Model"))
                                        .Update(x => x.Action("AjaxServiceUpdate", "Model").Type( HttpVerbs.Post).Data("sendAntiForgery"))
                                        .Destroy(x => x.Action("AjaxServiceDelete", "Model").Type( HttpVerbs.Post).Data("sendAntiForgery"))
          ))
           
    @section scripts {
    <script type="text/javascript">
        function error_handler(e) {
            if (e.errors) {
                e.preventDefault();   // cancel grid rebind if error occurs  
                var message = "Errors:\n";
                $.each(e.errors, function (key, value) {
                    if ('errors' in value) {
                        $.each(value.errors, function () {
                            message += this + "\n";
                        });
                    }
                });
                alert(message);
            }
        
     
        function sendAntiForgery() {
            return { "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val() };
        }
     
    </script>
    }
    Your help on this matter would be appreciated.
  2. Answer
    Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 30 Apr 2013 Link to this post

    Further study also shows that there is an additional problem:
    1.  If I ADD an item with no errors then this works and the grid exits edit mode
    2.  If I DELETE an item with no errors then this works and the grid updates.
    3.  If I UPDATE an row with no errors then it works, but the grid does NOT exit edit mode

    In the third case, update, I notice that nothing is returned in the response to the POST, while in the first case the new item, with its data is returned. I thought this was significant but I see that Delete does not return anything on success either.

    Overall I am a little perplexed as to how the grid works with MVC. Your advice would be appreciated, especially as I am having a lot more difficulties than I expected in this trial period. 

    Thank you in advance.

  3. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 02 May 2013 Link to this post

    Hello Jon,

    First to the empty response when the delete and the update requests are executed - with the 1.9.* version of jQuery empty result is no longer a valid json response and this causes the error event of the dataSource to be triggered.

    There is a sticky thread on the forums about this case:

    http://www.kendoui.com/forums/mvc/general-discussions/update-destroy-operations-trigger-the-error-event-of-the-datasource-after-updating-to-q1-2013-(v-2013-1-319).aspx

    Regarding the Server Side Errors - how to handle them is covered in this code library article:

    http://www.kendoui.com/code-library/mvc/grid/handling-server-side-validation-errors-during-pop-up-editing.aspx

    The approach used there could also be applied when using InLine editing mode.

    Kind Regards,
    Petur Subev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  4. Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 06 May 2013 Link to this post

    Hi Petur,

    Thank you for your reply. Yes, I had missed the sticky post about JQuery 1.9.*. Your link to this sorted my update/delete problems and I have marked that part of the post as answered.

    However on the server side errors I still have a problem. I had already downloaded and looked at the software on the link http://www.kendoui.com/code-library/mvc/grid/handling-server-side-validation-errors-during-pop-up-editing.aspx. That is an elegant solution, but this works by referring to the properties of the fields in the popup template which don't exist in this form when doing an inline edit.

    Could you please supply code that would allow me to target the row and field in a grid so that I can place the error message in the right place.  I study of the built HTML shows that the columns have an id equal to the property name, but I still need to find the correct row.

    I also note that the HTML has validation information in it. I find not documentation relating to this so assume I cannot do client-side validation during inline update. Is that correct?

    Thank you for your help.

  5. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 08 May 2013 Link to this post

    Hello Jon,

    I am not sure I understand your question:

    Could you please supply code that would allow me to target the row 

    The row is actually the container variable from the code library or grid.editable.element - it is the same element.
    To find the element you can use the name variable. i.e. $('#'+name) - will give you the input element.

    function showMessage(container, name, errors) {
            debugger;
            //add the validation message to the form
            container.find("[data-valmsg-for=" + name + "],[data-val-msg-for=" + name + "]")
            .replaceWith(validationMessageTmpl({ field: name, message: errors[0] }))
        }

    To find the span element which is actually the validation message element. you can use the approach there:
    container.find("[data-valmsg-for=" + name + "],[data-val-msg-for=" + name + "]")

    There is still client side validation, you can see that in the code library article the Name field is still required.

    Kind Regards,
    Petur Subev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Jon Smith
    Jon Smith avatar
    2 posts
    Member since:
    Mar 2011

    Posted 09 May 2013 Link to this post

    Hi Petur,

    Thank you. This problem is now fixed. Your explanation showed me I had misunderstood the code and it now works find. I just need to add code to handle a server error with no variable name, which is an option for ModelErrors.

    Thank you for your patience.
Back to Top