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

How to show server validation message like local validation?

3 Answers 428 Views
Editor
This is a migrated thread and some comments may be shown as answers.
Paddy
Top achievements
Rank 1
Paddy asked on 18 Aug 2015, 03:31 AM

Hi, 

 I'm using a template for grid popup edit. There are validations for the text input such as pattern="[a-zA-Z0-9_-]{20390}" and they work fine. However, I also want to make validation on  the server side, and I can only use error event of data source:

     error: function (e) {
                alert(e.xhr.responseJSON.error.message);
            }

 

This approach works but its style is not consistent with the former validation message. How can I show the message from remote below the input box, just as they are validated locally?

 Thanks.

3 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 19 Aug 2015, 02:21 PM
Hi,

You can use the approach demonstrated in this code-library project.

Regards,
Daniel
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Paddy
Top achievements
Rank 1
answered on 26 Aug 2015, 09:18 AM
Hi Daniel, thank you much for your reply.

I tried the as the example but it does not work. My project is a little different from the example.  My project uses WEB API and the example uses ASP.NET MVC.  Unlike the example which bounds error handling function to the error event:
 .DataSource(dataSource => dataSource
       .Ajax()
       .Batch(false)
       .ServerOperation(false)
       .Model(model => model.Id(p => p.Id))
       .Read("_Read", "Home")
       .Update("_Update", "Home")
       .Create("_Create", "Home")
       .Events(events => events.Error("error"))

and the validatioin code:

   var validationMessageTmpl = kendo.template($("#message").html());    

    function error(args) {        
        if (args.errors) {
            var grid = $("#Grid").data("kendoGrid");
            grid.one("dataBinding", function (e) {   
                e.preventDefault();   // cancel grid rebind if error occurs                             
                
                for (var error in args.errors) {
                    showMessage(grid.editable.element, error, args.errors[error].errors);
                }                    
            });
        }
    }

    function showMessage(container, name, errors) {
        //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] }))
    }

----------------------    
In my case I handle error in the event of data source:

            error: function (e) {
                alert(e.xhr.responseJSON.error.message);

                //to be implmented: showing error message without using alert 
                //....
            }​

When there is a local validation message for a field, username for example, the HTML would be:
    <div class="k-widget k-tooltip k-tooltip-validation k-invalid-msg" style="margin: 0.5em; display: block;" data-for="username" role="alert"><span class="k-icon k-warning"> </span>Username is required.<div class="k-callout k-callout-n"></div></div>

If I adopt the approach showed in the example, will the code for showing error message be like this ---
   container.find("[data-for=" + username + "]).replaceWith(validationMessageTmpl({ field: name, message: errors[0] }))

However, it does not work when there is an error from server side.

I also noticed that if no local validation message showed, the HTML code below cannot be found on the page.
  <div class="k-widget k-tooltip k-tooltip-validation k-invalid-msg" style="margin: 0.5em; display: block;" data-for="username"  role="alert"><span class="k-icon k-warning"> </span>Username is required.<div class="k-callout k-callout-n"></div></div>

Is that the reason that my approach does not work?

The example you provide seems out of date, can you provide more recent code example for latest kendo ui component? Thanks a lot!
0
Daniel
Telerik team
answered on 28 Aug 2015, 08:22 AM
Hi again,

The approach with the latest version will be the same but there will be a few differences if you are using the Web API. Assuming that you are currently using the logic demonstrated in the Web API demo you should:
  • Change the logic on the server so that the errors include the field name:
    var errors = new Dictionary<string, object>();
    foreach (var key in ModelState.Keys)
    {
        var item = ModelState[key];
        if (item.Errors.Any())
        {
            errors[key] = new
            {
                errors = item.Errors.Select(error => error.ErrorMessage)
            };
        }
    }
     
    return Request.CreateResponse(HttpStatusCode.BadRequest, errors);
  • Change the error handler to show the messages without using the dataBinding event. The grid will not be rebound by default if the response status is not success.

    function error_handler(e) {
        var errors = $.parseJSON(e.xhr.responseText);
     
        if (errors) {
            var grid = $("#grid").data("kendoGrid");                                
            for (var error in errors) {
                showMessage(grid.editable.element, error, errors[error].errors);
            }
        }
    }

As for the HTML element not being found if there were no errors on the client - this will occur if you are using custom editor and a message placeholder is not added for the inputs:
@Html.EditorFor(m => m.Foo)
@Html.ValidationMessageFor(m => m.Foo)


Regards,
Daniel
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Editor
Asked by
Paddy
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Paddy
Top achievements
Rank 1
Share this question
or