Jqgrid Server Side Error Message/Validation Handling

JqGrid forms server validations and custom error messages

You are right that errorTextFormat is the correct way to get server response in case of HTTP errors and display the corresponding error message.

First of all your server have to return response with an HTTP error code in the HTTP header. Then you should define your implementation of the errorTextFormat event handle either as a part of prmEdit, prmAdd, prmDel parameters of the navGrid or you can overwrite jqGrid default settings (see here). I personally prefer to set errorTextFormat by modifying of jQuery.jgrid.edit and jQuery.jgrid.del. An example of the corresponding code you can find in the following old answer.

The exact code of errorTextFormat function should depend on the format of the server response. I use ASP.NET MVC with WFC inside of the site and the server can return either JSON encoded string response (if the error come from throw new WebFaultException<string> ("my error text", statusCode); which I thrown explicitly) or sometime HTML response. In my implementation of errorTextFormat I test which kind of error response I received and convert the server response. Here is the code fragment:

my.errorTextFormat = function (data) {
var str = data.responseText.substr(0, 1);
var str1 = data.responseText.substr(0, 6).toLowerCase();
if (str === '"') {
var errorDetail = jQuery.parseJSON(data.responseText);
var s = "Fehler: '";
s += data.statusText;
s += "'. Details: ";
s += errorDetail;
return s;
}
else if (str1 === "<html " || str1 == "<html>" ||
data.responseText.substr(0, 169) === '<?xml version="1.0" encoding="utf-8"?>\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n<html ') {
var bodyHtml = /<body.*?>([\s\S]*)<\/body>/.exec(data.responseText)[1];
return bodyHtml; //bodyContents1;
}
else {
var res = "Status: '";
res += data.statusText;
res += "'. Felhercode: ";
res += data.status;
return res;
}
};
jQuery.extend(jQuery.jgrid.edit, {
...
errorTextFormat: my.errorTextFormat
});
jQuery.extend(jQuery.jgrid.del, {
...
errorTextFormat: Testportal.errorTextFormat
});

The code is not perfect, but you can use it to create your own one.

Displaying field specific validation error messages in jqGrid (server-side validation)

I had to use jQuery to manipulate the HTML of the jqGrid form.

jqGrid settings

The Edit dialogue options: {errorTextFormat:errorTextFormatF, onclickPgButtons:cleanEditForm, recreateForm:true, ...}

The Add dialogue options: {errorTextFormat:errorTextFormatF, recreateForm:true}

jqGrid calls the errorTextFormat callback to create an error message that is displayed at the top of the form when an error occurs. The callback returns the error message. Additionally, I used this callback to highlight erroneous fields in the
form.

The onclickPgButtons callback is called when the user clicks a navigation button (the left and right arrows).
This callback is used to clear field highlighting when the user moves to the next/previous record.

The recreateForm:true is used to make sure that field highlighting disappears when you close the form.

JavaScript

function errorTextFormatF(data) {

// The JSON object that comes from the server contains an array of strings:
// odd elements are field names, and even elements are error messages.
// If your JSON has a different format, the code should be adjusted accordingly.

var validationErrors = data.responseJSON.validationErrors;

if(validationErrors != null) {
for (var i = 0; i < validationErrors.length; i += 2) {
var selector = ".DataTD #" + validationErrors[i];
$(selector).after( "<img title='" + validationErrors[i+1] + "' class='jqgrid-error-icon' src='resources/img/emblem-important-2.png'></img>" );
}
}

return "There are some errors in the entered data. Hover over the error icons for details.";
}

function cleanEditForm() {
$(".jqgrid-error-icon").remove();
}

Screenshot

Sample Image

Using jqgrid, what is the best way to return errors from server side validation when using inline editing?

The recommend way is to use any HTTP error code in the response on the submitting of wrong data and to return the error description in the body of the response. If you need some more specific action like displaying another dialog with the error information, setting of focus on a field, marking some fields with CSS class 'ui-state-error' or something like that you should use errorfunc callback function.

If restoreAfterError is false the inline editing will be continued.

UPDATED: I mention in comments that the server should produce the error message as the response. In case of ASP.NET MVC the default message is HTML text which you posted as the first picture. If you use HandleJsonExceptionAttribute which I described in my old answer the error message will be serialized as JSON, but it contains additional information which you don't need to display (like the StackTrace). So you should use errorfunc parameter of editRow or saveRow to decode the server response. You can either use decodeErrorMessage from the already referenced answer or use the $.parseJSON function directly:

errorfunc: function(rowid, res) {
var errorText = $.parseJSON(res.responseText).Message;
$.jgrid.info_dialog($.jgrid.errors.errcap,
'<div class="ui-state-error">' + errorText + '</div>',
$.jgrid.edit.bClose,
{buttonalign: 'right'});
}

Jqgrid how to add custom custom error to display in table

There loadError callback since a long time. The old answer for example shows how it could be used. The main problem was that it was no default implementation of the callback fill jqGrid 4.12.1 (see here). Thus the user could see some error message if loading failed.

On the other side I see that the usage of new div.ui-jqgrid-errorbar and the SPAN span.ui-jqgrid-error is not yet described. Thus I created the simple demo for you, which demonstrates it. Additionally I use errorDisplayTimeout option set to 3 sec which can be combined with the error div. The corresponding code is

errorDisplayTimeout: 3000,
loadError: function (jqXHR, textStatus, errorThrown) {
var p = $(this).jqGrid("getGridParam"),
$errorDiv = $(this.grid.eDiv),
$errorSpan = $errorDiv.children(".ui-jqgrid-error");

$errorSpan.html("My custom error message");
$errorDiv.show();
if (p.errorDisplayTimeout) {
setTimeout(function () {
$errorSpan.empty();
$errorDiv.hide();
}, p.errorDisplayTimeout);
}
}

In the same way you can display any other error text based on jqXHR, textStatus, errorThrown parameters which are forwarded to loadError from error callback of jQuery.ajax.

If you want to use the same div to display error message on no data you can do this in the same way. It's important to understand that no data will be not interpreted as an error. Thus loadComplete instead of loadError will be called. Inside of the loadComplete callback you still can examine the total number of rows ($(this).jqGrid("getGridParam", "records")) or the number of rows on the current page ($(this).jqGrid("getGridParam", "reccount")) and to display your custom message in the same way like you could display it inside of loadError.

UPDATED: I added new method displayErrorMessage to the latest code on GitHub to simplify working with error div (see the commit). The demo use the new method and the code of loadError are reduced to one line:

errorDisplayTimeout: 3000,
loadError: function (jqXHR, textStatus, errorThrown) {
$(this).jqGrid("displayErrorMessage", "My custom error message");
}

jqgrid how to show server side messages

I suggested in the old answer and in another one to use existing hidden row of grid form (tr.tinfo) to display information which is not error. Because the answers are not well known I repeat the same information here, but I'll try to explain all more detailed.

First of all it's important to understand which elements has the standard Edit/Add form. Using Developer Tools of IE or Chrome, Firebug or many other tool one can easy find out that the Add/Edit form created by jqGrid contains two hidden rows on top of the form:

Sample Image

The first row will be used per default as the place for error message. One can use errorTextFormat to customize the information a little.

If the server response contains error HTTP status code (>=400) then the callback errorTextFormat will be called and you can use

errorTextFormat: function (response) {
return response.responseText;
}

or something like

errorTextFormat: function (response) {
return '<span class="ui-icon ui-icon-alert" ' +
'style="float:left; margin-right:.3em;"></span>' +
response.responseText;
}

to display error message like

Sample Image

In the same way one can use afterSubmit callback to display status message after submitting of edited/added data if the server response contains successful HTTP status code. The implementation of afterSubmit could be about the following

afterSubmit: function (response) {
var myInfo = '<div class="ui-state-highlight ui-corner-all">'+
'<span class="ui-icon ui-icon-info" ' +
'style="float: left; margin-right: .3em;"></span>' +
response.responseText +
'</div>',
$infoTr = $("#TblGrid_" + $.jgrid.jqID(this.id) + ">tbody>tr.tinfo"),
$infoTd = $infoTr.children("td.topinfo");
$infoTd.html(myInfo);
$infoTr.show();

// display status message to 3 sec only
setTimeout(function () {
$infoTr.slideUp("slow");
}, 3000);

return [true, "", ""]; // response should be interpreted as successful
}

The code will display the status message for 3 sec only abd then uses jQuery.slideUp animation to hide it. It will look like

Sample Image

I hope it's what you need.

jqgrid : Validate on serverside for editing a row

I recommend you that the server return allays an error HTTP code in case of validation error or any other errors (see for example here for more information). In the case you should use errorfunc parameter of the editRow function and not the succesfunc. It is the common rule. So I recommend you to define loadError event handler in every jqGrid which get any data from the server. In the same way you should use errorTextFormat in case of form editing and errorCell in case of cell editing.



Related Topics



Leave a reply



Submit