yii2 ajax form submission: validation response handling - yii2

When the data are sent to the server to be save it is important to perform check up again even if the clientside validation is done but at that time if the model is not valid the response returned is in json format(from getErrors/ActiveForm::validate($model)) containing the messages and attributes that have errors.
When receiving how can I affect it to the form on the client side; each error from the reponse to it field on the form?
Is there any function on client side(js) that I can call passing the response to it?

Use
$.each(data, function(key, val) {
$("#"+key).after("<div class=\"help-block\">"+val+"</div>");
$("#"+key).closest(".form-group").addClass("has-error");
});
This will append error to corresponding field.

Related

How do I call a URL returning JSON in a loop

The Keys array contains 1000 project key's.
for (var i = 0; i < Keys.length; i++){
httpRequest("https://hostname/api/issues/projectKeys="+Keys[i]+"?format=jSON",
function (err, res, body) {
var jsonObj = JSON.parse(body);
issue.push(jsonObj.total);
// console.log(issue.length);
}).auth(global.username, global.password);
}
The URL in the httpRequest returns a JSON.
While I run this program, after 50-60 keys data is retrieved.
My program is stopped due to an error.
SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse ()
Is it due to the asynchronous nature of NodeJS ?
Please help How can I call the URL for 1000 times in a loop.
Is it due to the asynchronous nature of NodeJS ?
Not directly. It's probably due to your application flooding whatever API you're hitting, and you're getting rate limited or some other error.
You should be looking at the response status code to decide if your response is okay. You should log these responses if there's an error. There's probably some text error message in the response.
Check this, how you can make API calls in node properly.
Then always do the null/undefined or blank response check once you get the response back from the server before doing any processing.

Send both JSON response and model in Grails

I'm new to Grails and I'm stuck up with a problem. I want to know if there is a way to send both JSON and view and model through "render" in Grails.
I'm using a jQuery Datatable to display data returned from server which is read from JSON returned by the controller. I also need to display error messages on the same view in case of validation failure in form fields. But I'm able to return either only the JSON or model and view using render. I also tried sending the JSON through model itself but it didn't work.
This is my code:-
def hierarchyBreakInstance = new HierarchyBreak(params);
String json = "{\"sEcho\":\"1\",\"iTotalRecords\":0,\"iTotalDisplayRecords\":0,\"aaData\":[]}";
hierarchyBreakInstance.errors.reject(message(code: 'hierarchyBreak.error.division.blank'));
render(view: "hierarchyBreak", model: [hierarchyBreakInstance: hierarchyBreakInstance]);
//render json;
The gsp code:-
<g:hasErrors bean="${hierarchyBreakInstance}">
<div class="errorMessage" role="alert">
<g:eachError bean="${hierarchyBreakInstance}" var="error">
<g:if test="${error in org.springframework.validation.FieldError}" > data-field-id="${error.field}"</g:if>
<g:message error="${error}"/>
</g:eachError>
</div>
</g:hasErrors>
Could you please let me know if there is a way to do this. Thanks!
You can use like this.
def hierarchyBreakInstance = new HierarchyBreak(params);
String json = "{\"sEcho\":\"1\",\"iTotalRecords\":0,\"iTotalDisplayRecords\":0,\"aaData\":[]}";
hierarchyBreakInstance.errors.reject(message(code: 'hierarchyBreak.error.division.blank'));
render(view: "hierarchyBreak", model: [hierarchyBreakInstance: hierarchyBreakInstance,json:json]);
//render json;
Assuming that you are doing a request with some parameters, and need to return if was succesfull or not, and the data to fill the table with ajax.
I will do on that way, use the statuses of the HTTP to mark if it was a problem with the validation(normally we return 400 Bad Request and the message)
Example :
return ErrorSender.sendBadRequest("error validating field $field with value $value")
And the errorsender has a sendBadRequest method
[response: ['message': message, error: "bad_request", status: 400, cause: []], status: 400]
If the request was OK, you only need to respond the data with something like
return [response: results, status: 200]
In the client side you have to have one function if the request was OK to parse result, and one function if request have some validated data problem, database problem or whatever that caused that the request didnĀ“t return a 200(in the example),there are more status codes, you can check on
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
PD: Initial validation should be done on client side.

json response callback load store extjs

I have a JSON store that load data from a PHP script. This script call a Web Service and sometimes it get some errors and I need to capture them and show them in my app.
In my script I print this line when I get an error:
echo '{"success": "false", "error": "'.$res->state->Description.'"}';
In my app I have this code to load the store
targheStore.load({
params: { targa: searchForm.getValues().targa },
callback: function(records, operation, success) {
Ext.getBody().dom.style.cursor = "default";
if(!success){
$("#message2").slideDown('fast');
setTimeout(function() {
$("#message2").slideUp('medium')
}, 2700);
}
}
});
The jQuery code is to show a message "No record found" from the top, but I want to show the error message that I receive from json.
Inside of the operation argument is a request and response object. Use the response object as you would any Ajax response should allow you to handle your messages the way you'd like.
I suggest declaring a globally available handler for processing operation to look for JSON.parse(response.responseText).hasOwnProperty("error") and doing your custom operation in that way.
If you're not using JSONP for communication you can stuff your message in the raw text returned from an HTTP error code (400+) and the {error:} handler in your ajax would be the best way to route errors.

Codeigniter CSRF response format

I am using a predefined response format for all my ajax calls.
If the request is success then the server will respond :
{"status":true,"data":{"name":"person","age":2}}
Please note data is not necessary.
and if the request failed then i will get
{"status":false,"reason":"You are not authorised."}
SO every response have a status field , if status is FALSE then there will be reason field.
The problem is that now i enables CSRF protection in Codeigniter and if the token expired/failed the system outputs
The action you have requested is not allowed.
this is HTML content.
Is it possible to extend the security class ,so that if the request is through Ajax then it will keep json_encoded format else use the html format.(i do not want to modify the core)
Thanks.
This error message is rendered from the CI_Exceptions::show_error method (located in system/core). You can extend this class by the usual way and override this method in order to catch this error and return whatever you want.
You can get rid of the call inside the CI_Security::csrf_show_error method by overriding it so it won't simply call
show_error('The action you have requested is not allowed.');
This is probably more robust.
Alternatively you can attack this inside CI_Exceptions class. Since this errors doesn't come with specific error code you will have to match for the message which could break between updates (currently hardcoded). The resulting class could look like this:
class MY_Exceptions extends CI_Exceptions {
public function show_error($heading, $message, $template = 'error_general', $status_code = 500) {
if ($message == 'The action you have requested is not allowed.') {
// handle this error your way
} else {
// send every other error to the original handler
parent::show_error($heading, $message, $template, $status_code);
}
}
}

Get custom JQGrid JSON data in gridComplete method

Here is a typical JQGrid JSON response:
{
"page":1,
"records":537,
"rows":[..],
"rowCount":10,
"total":54
}
Along with this, I want to send additional custom data. For example, I'd like to send the database time of the last search so that I can lazy-reload my grid whenever changes have occurred since then. Here is how I would like to send that data:
{
//Custom name-value pairs:
"nameValues":{"lastSearchTime":"2011/09/01:14:14:56"},
//Normal JSON data:
"page":1,
"records":537,
"rows":[..],
"rowCount":10,
"total":54
}
The problem is that JQGrid swallows up the JSON response rather than forwarding it to the gridComplete method. In other words, params is undefined in the following function:
function myGridComplete (params){
//params is undefined!
var JSONResponse = ?;//I need your help here!!!
globalGridVariables.lastSearchTime = JSONResponse.nameValues.lastSearchTime;
//Rest of grid complete method
..
}
Please let me know if there is a way to get access to the JSON response object in the gridComplete method, or if there is another supported way to add custom data to a JSON response.
Thanks much!
Note: I don't want to send this as a hidden column, because that would be inefficient.
You can use loadComplete instead of gridComplete. The loadComplete event has one parameter (for example data) which represent the full data from the server response inclusive all of your extensions.
Alternative you can rename the nameValues to userdata and use $('#list').jqGrid('getGridParam', 'userData') to get the value. See here for more information.
Moreover you can consider to use more HTTP caching (see here and here) for the aims which you described in your question.
You can use beforeProcessing that has the deserialized response and gets active before gridComplete and loadComplete.
For example:
beforeProcessing: function (data, status, xhr) {
myArray = data.rows;
}
And just to make it more clearer from the documentation:
Below is the execution order of the events when a ajax request is made
beforeRequest
loadBeforeSend
serializeGridData
loadError
beforeProcessing
gridComplete
loadComplete