1

I'm working on Ruby-on-Rails. I'm trying to submit a form with JSON request.

HTML

<%= form_tag widgets_user_path(:format => "json"), :id => "testjsonform" do %>
        <input type="checkbox" name="cat[]" value="math" id="sub1" class="left">
        <label for="sub1" class="laa">Math</label>
        <input type="checkbox" name="cat[]" value="history" id="sub2" class="left">
        <label for="sub2" class="laa">History</label>
        <input type="checkbox" name="cat[]" value="science" id="sub3" class="left">
        <label for="sub3" class="laa">Science</label>
        <%= hidden_field_tag 'callback', "?" %>
        <div><%= submit_tag 'JSON', :id => "testjson" %></div>
<% end %>

application.js

$("#testjsonform").live("submit", function() {
    $.getJSON($(this).attr("action"),$(this).serialize(), function(data) {
        alert("success");
    })
    .success(function() {
        alert("success");
    })
    .error(function() {
        alert("error");
    });
    return false;
});

On console it shows the request is completed (200)

Started GET "/widgets/user.json?utf8=%E2%9C%93&authenticity_token=N8WsL3BATQiv9OWX4d29o62GOQgX9mXdt%2BBiVe%2FtzU%3D&cat%5B%5D=history&callback=%3F" for 127.0.0.1 at 2012-04-27 12:52:35 +0530
Processing by WidgetsController#user as JSON
Parameters: {"utf8"=>"✓", "authenticity_token"=>"N8WsL3BATQiv9OWX4d29o62GOQgX9mXdt+BiVe/tzU=", "cat"=>["history"], "callback"=>"?"}
User Load (0.3ms)  SELECT "users".* FROM "users" LIMIT 1
===================================== Categories
Completed 200 OK in 3ms (Views: 0.2ms | ActiveRecord: 0.3ms)

And in Google Chrome is shows the correct JSONP response

?({"user":{"fname":"Test","lname":"User","email":"testuser@testsite.com"}})

Everything seems correct; but still it gives me alert in error block. Why don't I get the success alert? What could possibly be wrong? Any help is appreciated...

Bongs
  • 5,502
  • 4
  • 30
  • 50
  • Try to alert the error, which is given as a parameter to the error handler. – Bergi Apr 27 '12 at 07:47
  • Does jQuery do an ajax or a jsonp call? For the first one, the callback parameter is neither needed nor allowed. – Bergi Apr 27 '12 at 07:48
  • It is making JSON call and the callback parameter '?' is needed to correctly format the JSON response in controller. Can you help to how can I print/check the error type? – Bongs Apr 27 '12 at 07:53
  • Valid JSON neither contains the question mark nor the braces. For getting the error object, see the [docs](http://api.jquery.com/jQuery.ajax/). – Bergi Apr 27 '12 at 08:19
  • It is JSONP response actually. Will make the correction... (ref: http://stackoverflow.com/a/2887214/707636) – Bongs Apr 27 '12 at 09:18

2 Answers2

1

Okay... I found where the problem is and came up with (not so pretty) solution...

The problem seems to be with URL encoding. (The way it is sending the "callback" parameter)

$.getJSON(_form.attr("action"), _form.serialize(), function(data) { /* some code */ } sends the request as follows

Started GET "/widgets/user.json?utf8=%E2%9C%93&cat%5B%5D=4&callback=%3F&user=3" for 127.0.0.1 at 2012-04-27 16:59:40 +0530
Processing by WidgetsController#user as JSON
Parameters: {"utf8"=>"✓", "cat"=>["4"], "callback"=>"?", "user"=>"3"}
User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "3"]]
===================================== Categories
Completed 200 OK in 1ms (Views: 0.1ms | ActiveRecord: 0.1ms)

I made some changes in application.js to decode the parameters.

var _url = _form.attr("action") + "?" + decodeURIComponent(_form.serialize());

$.getJSON(_url, function(data) {
    alert("success");
});

This sends the request as follows and also gave me success alert :) (see the parameters; extra "_" parameter also got added to it.)

Started GET "/widgets/user.json?utf8=%E2%9C%93&cat[]=4&callback=jQuery17203027302643749863_1335526106006&user=3&_=1335526108045" for 127.0.0.1 at 2012-04-27 16:58:28 +0530
Processing by WidgetsController#user as JSON
Parameters: {"utf8"=>"✓", "cat"=>["4"], "callback"=>"jQuery17203027302643749863_1335526106006", "user"=>"3", "_"=>"1335526108045"}
User Load (2.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", "3"]]
===================================== Categories
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 2.6ms)

Also I added :method => "get" to the form

Bongs
  • 5,502
  • 4
  • 30
  • 50
0

Why don't you just set your form as remote? You can respond with javascript instead of JSON which can show on your page some rendered content:

# in your view
<%= form_tag widgets_user_path, :id => "testjsonform", remote: true do %>

# in *.js.erb
alert("<%= j params.to_yaml %>")
$('body').append("<%= j render something %>") # or other stuff for filling your "parent" page
jdoe
  • 15,665
  • 2
  • 46
  • 48
  • The purpose is I'm writing this code to build widget (which can be placed on some user's site/blog). The script will hit a URL and it will return JSON data to populate data in the widget. This will help for my web application but not for others. – Bongs Apr 27 '12 at 08:47