jqgrid server side error message/validation handling
Asked Answered
S

2

11

In my json responses, I have 'STATUS' and 'errors' properties. How can use this errors properties with jqGRid. To parse all errors and show them in a dialog box.

Basically just check, if status:'ERROR' then display all errors.

Thanks!

Service answered 5/8, 2011 at 17:23 Comment(0)
N
14

In the last part of the answer to your previous question I tried already tried to give the answer on your current question. Probably I expressed me not clear enough.

You should not place and information about the error inside of the standard successful response. You should just follow main rules of the HTTP protocol used for communication between the server and the client.

The loading data in the grid, editing of the rows and all Ajax communication with the server are implemented with respect of HTTP protocol. Every HTTP response has the status code in the first line of the response. It's very important to understand the meaning of this.

The typical successful request with JSON data looks as following

HTTP/1.1 200 OK
...
Content-Type: application/json
...

{"page":"1",....}

If the URL which try to load not exist for example the first line of the server response will be

HTTP/1.1 404 Not Found

and jqGrid based on the HTTP status code (404 in the case) *will not try to interpret the the server response as the data which contains data with the grid content.

The demo has the following code

$("#list").jqGrid({
    url: 'Unknown.json', // there are no file with the name
    datatype: 'json',
    // ... some other typical parameters
    loadComplete: function () {
        alert("OK");
    },
    loadError: function (jqXHR, textStatus, errorThrown) {
        alert('HTTP status code: ' + jqXHR.status + '\n' +
              'textStatus: ' + textStatus + '\n' +
              'errorThrown: ' + errorThrown);
        alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText);
    }
});

which display the alert message like the following:

enter image description here

Moreover in the jqXHR.responseText you will find the full body of the server response as as string. The next alert shows the response.

With all above information I wanted to show you that error responses and successful responses will be processed in another way by the whole stack of software which you use (jqGrid, jQuery, XMLHttpRequest object, ...). So you should just use error HTTP status codes in the server responses if the error will be detected. In the answer for example you will see how to do this in case of the usage ASP.NET MVC.

Here you can find another version of the loadError implementation which wait the input in the JSON form: {"Source":"some error source",Message:"Description of the error"}, and the error output will be like here

enter image description here

but the code can display additionally HTML response generated by your web server:

enter image description here

You can easy modify the code to your purpose. The code you can find below

loadComplete: function () {
    // remove error div if exist
    $('#' + this.id + '_err').remove();
},
loadError: function (jqXHR, textStatus, errorThrown) {
    // remove error div if exist
    $('#' + this.id + '_err').remove();

    // insert div with the error description before the grid
    $(this).closest('div.ui-jqgrid').before(
        '<div id="' + this.id + '_err" style="max-width:' + this.style.width +
            ';"><div class="ui-state-error ui-corner-all" style="padding:0.7em;float:left;">' +
            decodeErrorMessage(jqXHR, textStatus, errorThrown) +
            '</div><div style="clear:left"/></div>'
    );
}

where the decodeErrorMessage function defined as

var decodeErrorMessage = function (jqXHR, textStatus, errorThrown) {
        var htmlBody, errorInfo, i, errorText = '',
            errorIconSpan = '<span class="ui-icon ui-icon-alert" style="float:left; display: inline-block; margin-right: .3em;"></span>';
        if (textStatus) {
            errorText = textStatus;
        }
        if (errorThrown) {
            if (errorText.length > 0) {
                errorText += '<hr/>';
            }
            errorText += errorThrown;
        }
        if (typeof (jqXHR.responseText) === "string") {
            if (jqXHR.responseText.charAt(0) === '[') {
                try {
                    errorInfo = $.parseJSON(jqXHR.responseText);
                    errorText = "";
                    for (i = 0; i < errorInfo.length; i += 1) {
                        if (errorText.length !== 0) {
                            errorText += "<hr/>";
                        }
                        errorText += errorInfo[i].Source + ": " + errorInfo[i].Message;
                    }
                } catch (e) { }
                errorText = errorIconSpan + errorText;
            } else {
                htmlBody = /<body.*?>([\s\S]*)<\/body>/i.exec(jqXHR.responseText);
                if (htmlBody !== null && htmlBody.length > 1) {
                    errorText = htmlBody[1];
                }
            }
        } else {
            errorText = errorIconSpan + errorText;
        }
        return '<div style="float:left">' + errorText + '</div>';
    };

UPDATE: Free jqGrid contains default implementation of loadError (see here and here), which generates relatively readable error message in case of the most Ajax errors. It displays the resulting text in the error div, existing above the body of the grid. Thus it's recommended to test, whether the default behavior produce good results before usage of custom loadError. If you really need to create your own loadError then you can place the error message in the error div using displayErrorMessage method of free jqGrid: $("#grid").jqGrid("displayErrorMessage", customErrorMessage);

Neurotic answered 6/8, 2011 at 21:44 Comment(0)
I
0

To do what you're describing, the easiest way is to add custom properties to the data json object that is being retrieved by the jqgrid from the server. Then you can capture those custom properties with the loadComplete(data) event.

jQuery('#grid').jqGrid({
    loadComplete: function (data) {
        //access data.propertyname here
    }
});
Introspection answered 1/3, 2021 at 18:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.