How to use grails withForm through ajax call - ajax

I am using grails 2.5.2 version. I have a form submit event by ajax call where sometimes form is submitted multiple times. I have goggled for it and see about grails withForm topic. I tried to implement it but it stops the request for the first time and show invalid token message. How can I use useToken for withForm or other way to stop multiple time form submit via ajax call in grails.
My code attempts are below.
My ajax call:
jQuery.ajax({
type: 'POST',
dataType:'JSON',
data: $("#createFormModal").serialize(),
url: "${g.createLink(controller: 'studentCollection', action: 'save')}",
success: function (data) {
if(data.isError==true){
showAlertModal(data.message);
}else {
$('#createModal').modal('hide');
$('#list-table').DataTable().ajax.reload();
showSuccessMsg(data.message);
$("#createFormModal").find("input[type=text], textarea").val("");
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
My controller method:
def save() {
LinkedHashMap result = new LinkedHashMap()
String outPut
withForm {
result = studentCollectionService.saveCollection(params)
}.invalidToken {
println("### invalidate Token")
result.put(CommonUtils.IS_ERROR, Boolean.TRUE)
result.put(CommonUtils.MESSAGE, "Please press the button once")
}
outPut = result as JSON
render outPut
return
}

Related

How can i get a value from the controller to my gsp page using AJAX

I am new to AJAX and grails so any help is appreciated. on my GSP page, on button click I am trying to retrieve a variable from the controller:
$.ajax({
url:'${createLink(controller: 'store', action: 'getNum')}',
type: 'GET',
dataType: 'json',
data: {num: num}, // the num is defined before and access properly
error: function() {
alert("error");
},
success: function(data) {
alert(data);
}
});
this is my controller function:
def getNum(){
String num = params.num
Long locnum = num as Long
int result = storeService.getNum(locnum)
String json = JsonOutput.toJson([count: result])
return json
}
I am going into the error and getting an "error" alert. I was wondering how I could utilize AJAX to get the number I need for my GSP page?
Thank you.
I would modify your JavaScript code like so:
$.ajax({
url:'store/getNum',
method: 'POST'
data: {'num': num}, // the num is defined before and access properly
error: function() {
alert("error");
},
success: function(data) {
alert(data);
}
});
And then modify your Grails controller code like so:
def getNum() {
Long locnum = = params.long('num')
int result = storeService.getNum(locnum)
return render([count: result] as JSON) // you will need to import grails.converters.JSON
}
A tip for the future is to set a breakpoint in your Grails controller method and run the application in Debug mode to ensure that the controller method is being called. If it is not being called, click on the Network tab on your internet browser's Developer Tools and then press the button on your GSP page to inspect the HTTP request being made by the AJAX call.

Putting a JSON response into a hidden field and retrieving it into a function

I'm retrieving the number of rows contained by a table in my database with the following function using JSON.
function rowCount()
{
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
datatype:"json",
type: "GET",
url: "/wagafashion/ajax/CmsRowCount.htm",
success: function(response)
{
$("#rows").val(response);
},
error: function(e)
{
alert('Error: ' + e);
}
});
}
In the success handler, the response is arriving as expected. There is no problem on the server side.
The response is just mapped with the long type of Java which represents the number of rows in a database table.
I'm putting this response in a hidden field whose id is rows using $("#rows").val(response); in the success handler.
The above function is invoked when the form is submitted using the following jQuery function.
$(function() {
$('#dataForm').submit(function() {
rowCount(); //Invokes the above function that makes a JSON request.
var rows=$("#rows").val();
alert("rows = "+rows);
return false;
});
});
The alert box attempts to alert the value contained by the hidden field (which is the JSON response as described above) but it is empty for the first time. It alerts the actual value only when I press the submit button once again (without a page refresh).
Also tried to replace the preceding function with the following.
$(function() {
$('#dataForm').submit(function() {
rowCount(); //Invokes the first function that makes a JSON request.
var form = $(this),
url = form.attr('action'),
rows = form.find('input[name="rows"]').val();
alert("rows = "+rows);
return false;
});
});
But it didn't work either. Why does this happen? What is the way of retrieving the correct value of that hidden field into the preceding jQuery function?
The alert box attempts to alert the value contained by the hidden field (which is the JSON response as described above) but it is empty for the first time.
Ajax calls are asynchonrous. When you call rowCount, you start the call, but then rowCount returns and your code continues. The call doesn't complete until later (which is why ajax accepts a callback).
If you trigger the next step in what you're doing from the callback, you'll have the value. You typically do this by having rowCount accept a callback of its own, like this:
function rowCount(callback) // <==== Accept the callback
{
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
datatype:"json",
type: "GET",
url: "/wagafashion/ajax/CmsRowCount.htm",
success: function(response)
{
$("#rows").val(response);
callback(); // <==== Call the callback
},
error: function(e)
{
alert('Error: ' + e);
callback(); // <==== Probably want to give it a value telling it things failed
}
});
}
Then using it:
$(function() {
$('#dataForm').submit(function() {
var form = $(this); // <== Grab this outside the callback
rowCount(function() {
var url = form.attr('action'),
rows = form.find('input[name="rows"]').val();
alert("rows = "+rows);
});
return false;
});
});
If you want to decide whether to allow the form to be submitted on the basis of the callback, you'll have to always cancel the submission, and then trigger submitting it programmatically from the callback if you want to allow it.

Alert is coming before response

I have this ajax function which validates the user provided key. but the alert comes before the ajax response and due to which if the user provide a wrong key even can get access
$(document).ready(function() {
$('#submit').click(function(e) {
e.preventDefault();
var key = $('#downloadkey').val();
var dataString = {KEY:key};
$.ajax({
url: "/mediabox/home/validate_key",
type: 'POST',
data: dataString,
success: function(msg) {
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
});
});
});
What makes you believe the alert is coming before the response? The success handler is only invoked after the response has been successfully received client-side.
To confirm, you can edit your success handler to log the response:
success: function(msg) {
console.log(msg);
if(msg=="true")
{
alert("do something");
}
else
{
alert("Your download key is either wrong or you didn't provide it.");
return false;
}
}
Also, if you're using the return false to deny access to the user by blocking the HTML action that, won't work due to the asynchronous nature of AJAX.
The success function is called when the request completes.
success(data, textStatus, jqXHR)Function, Array
A function to be called if the request succeeds. The function gets passed three
arguments: The data returned from the server, formatted according to
the dataType parameter; a string describing the status; and the jqXHR
(in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the
success setting can accept an array of functions. Each function will
be called in turn. This is an Ajax Event.
The code within the success handler will only execute once the AJAX request is completed. If you are getting an alert before hand then that indicates that the request completed properly.

Returning Json from controller, never a success

I'm successfully posting to my controller with the following code, however, success is never being hit only error. What am I doing wrong?
JS:
$.ajax({
url: '/Home/Subscribe',
type: 'POST',
dataType: 'json',
data: { email: $('#sube').val() },
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
Controller:
[HttpPost]
public JsonResult Subscribe(string email)
{
return Json(new { foo = "bar", baz = "Blech" });
}
In IE, press F12 to open developer tools. Go to Network tab and click on Start Profiler. Send a request to your Subscribe action - in a list below you will see details of sent request and returned status code. Double click on request to see details - you can then see body of your response. If the request failed with a server error, you will see that error in a body of your response.
One wrong thing I see with your code is that you have hardcoded the url:
url: '/Home/Subscribe'
You should never do this. You should always use url helpers when generating urls in an ASP.NET MVC application:
url: '#Url.Action("Subscribe", "Home")'
Also you are saying that the error callback is always hit but you didn't say what you observed in FireBug or Chrome Developer toolbar when you tried to analyze the AJAX request. If you had done this you would have seen the exact cause of failure for the request because you would have seen what request is sent to the server and what response does the server sends back to the client.
The following is my jQuery ajax snippet that works. Your controller looks right. I assume you have verified it is actually getting called by using a breakpoint.
var p = {
email: $('#sube').val()
};
$.ajax({
url: '#Url.Action("Subscribe", "Home")'
type: 'POST',
data: JSON.stringify(p),
dataType: "text json",
contentType: "application/json",
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});

ajax call results in error instead of succes

In my ASP.net mvc3 project, i use a ajax call to send json data to a create actionmethod in the controller Company. But when i debug the ajax call, it always end up in a error result instead of the succes result.
ajax call:
$.ajax({
url: '/Company/Create',
type: 'POST',
data: JSON.stringify(CreateCompany),
dataType: 'Json',
contentType: 'application/json; charset=utf-8',
success: function () {
alert('ajax call successful');
},
error: function () {
alert('ajax call not successful');
}
});
My action method in the Company controller :
[HttpPost]
public ActionResult Create (Company company)
{
try
{
//Create company
CompanyRepo.Create(company);
return null;
}
catch
{
return View("Error");
}
}
I already debugged the actionmethod, but he completes it like he should.
So the data send with the ajax call will be handled and written to the db. (the action method does not use the catch part).
Why is my ajax call still gives the message 'ajax call not succesful'?
I used to got same problem with getting back the JSON result.
What I did is to set the dataType to "text json" :))
If this doesn't help try to get additional info by acquiring details of your error, i.e.:
$.ajax({
url: '/Company/Create',
type: 'POST',
data: JSON.stringify(CreateCompany),
dataType: 'text json',
contentType: 'application/json; charset=utf-8',
success: function () {
alert('ajax call successful');
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("XMLHttpRequest=" + XMLHttpRequest.responseText + "\ntextStatus=" + textStatus + "\nerrorThrown=" + errorThrown);
}
});
BTW: I found this solution somewhere on the StackOverflow
Why are you returning null in case of success in your controller action? Return something to success like for example a JSON object (especially as you indicated in your AJAX request that you expect JSON response from the server - using the dataType: 'json' setting - which should be lowercase j by the way):
return Json(new { success = true });
Wouldn't this just be easier:
$.post("/Company/Create", function (d) {
if (d.Success) {
alert("Yay!");
} else {
alert("Aww...");
}
}, "json");
And in your controller.
[HttpPost]
public JsonResult Create(
[Bind(...)] Company Company) { <- Should be binding
if (this.ModelState.IsValid) { <- Should be checking the model state if its valid
CompanyRepo.Create(Company);
return this.Json(new {
Success = true
});
};
return this.Json(new {
Success = false
});
}

Resources