The controller cannot detect ajax requests

I use the simple_form pearl and generate the form. I specify the remote: true parameter as follows:

<%= simple_form_for @webinar, validate: true, remote:true do |f| %> 

So, the html output for the form is the following snippet:

 <form accept-charset="UTF-8" action="/webinars" class="simple_form new_webinar" data-remote="true" data-validate="true" enctype="multipart/form-data" id="new_webinar" method="post" novalidate="novalidate"> ... </form> 

As I checked, using the standard form_for helper, data-remote = 'true' is added to the form when remote: true is used. And as you can see from the generated html, when I use simple_form pearls, there is such an attribute.

So, in my controller, I:

 def create @webinar = Webinar.new(params[:webinar]) respond_to do |format| if @webinar.save format.html { redirect_to @webinar, notice: 'Webinar was successfully created.' } format.js format.json { render json: @webinar, status: :created, location: @webinar } else format.html { render action: "new" } format.json { render json: @webinar.errors, status: :unprocessable_entity } end end end 

But format.html is always used. What am I doing wrong?

EDIT:

I used logger.debug request.format to check what the actual format for the log file and in its file is:

text / html

So, the problem should be in the generated simple_form form - what could be wrong there when we have "data-remote = true"?

+7
source share
3 answers

I can’t believe that I lost so much time trying to understand why simple_form does not work as expected.

Finally, it looks like I did everything right, and the problem was caused by:

AJAX cannot be used to download files.

To solve my problem, I just have to add the following gem to my Gemfile and run the package installation command:

 gem 'remotipart', '~> 1.0' 

Then add the following line to the application.js file:

// = jquery.remotipart required

Additional information on:

+2
source

You are misleading format.json|format.html with remote: true . Both of them are different. Having remote: true does not mean format.json .

format.json does not indicate that the URL was invoked through javascript. This means that the client is awaiting JSON output. that is, it does not indicate where the input came from, it indicates what result is required.

The general use of remote:true is that instead of reloading the page, you submit the form as an Ajax request and then show the answer in a JQuery popup or something like that. But if you want to display the response as a jQuery popup - do you need HTML output and not JSON output directly?

Some people use remote: true to load HTML content in a popup. Your use case should do remote: true , but you expect formatted JSON data. Rails cannot make these decisions for you. It sends a request to /webinars by default and expects you to process the HTML response. If you really need a JSON response, configure the URL to which the Ajax request was sent:

 simple_form_for @webinar, url: webinar_path(format: :json), ..... 

If you do this above, the webinar controller will now be called using the JSON format.

Generally:

  • remote:true can be used with both format.html and format.json
  • The main use case for the Rails application is to process remote: true as a controller request, as usual, display a partial HTML template (i.e. only the response content without the general page layout / navigation / etc) and send it back the HTML displayed in popup window
  • Most people simply dress-process remote callbacks and display a jQuery popup. Therefore, they do not need to write individual code for each remote form.
  • Thus, by default, Rails calls format.html for remote requests.
  • If you specifically want format.json , and if you really want to handle JSON manually on the client, change it accordingly. But this is not an option for using the majority.
  • Running an Ajax request does not mean that the content type is JSON. This is an HTML request made using Javascript. for example, in the jquery $.ajax check these two parameters: accept and dataType . If you really want to send the Accepts: application/json header, then you need to manually specify that when creating the Ajax request (or you need to complete the URL using .json if it is a Rails application).
  • So, even if you make a normal Ajax request to /webinars , for example $.ajax('/webinars', ...) - it won’t go to format.json ! It will still only be format.html . If you really want the JSON format, you should say $.ajax('/webinars', { accepts: 'application/json' }) , or you should say $.ajax('/webinars.json')

Edit: minor refinement

+4
source

It seems that you are not requesting a directly formatted JSON document in the generated form action. Perhaps one option is to install :format in json in the routes file using this technique: http://guides.rubyonrails.org/routing.html#defining-defaults

You can also specify other default values ​​in the route by providing a hash for the parameter: defaults. This even applies to parameters that you do not specify as dynamic segments. For example:

 match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' } 

Rails will match the photos / 12 for the show PhotosController action and set the [: format] parameters to "jpg".

+2
source

All Articles