MiningSam
MiningSam

Reputation: 603

Rails form_tag remote example

I have this incredible simple form:

<%= form_tag("/portal/search", method: 'get', remote: true ) do %>

  <%= label_tag(:query, 'Search for:') %>
  <%= text_field_tag(:query) %>
  <%= submit_tag("Find") %>

<% end %>
<div id="results"></div> 

I know from the documentation, I can use AJAX through the remote option:

<%= form_tag("/portal/search", method: 'get', remote: true ) do %>

Then I get stuck. I know how to generate results in a view/partial, but how do I get that partial inside the div element? I know a bit of JQuery, so I can select the element. I found a lot of results, but they seem to miss that lightbulb moment for me. I am using Rails 4.1.6

My results are just simple records from a model, like Book (title, author)

Thank you for helping!

EDIT

I've won the cup for missing the point by a long shot. I had to add the search.js.erb inside the view folder instead of assets.

Upvotes: 10

Views: 24318

Answers (3)

Paulo Abreu
Paulo Abreu

Reputation: 1786

When you add remote: true jquery-ujs will provide you the ajax request (by default this javascript lib is required in app/assets/javascripts/application.js).

The ajax call will request a 'text/javascript' response. for that reason your server code should reply with:

# action
def search_query
  respond_to do |format|
    format.js { 
      # additional code
    }
  end
end

If in your view (search_query.js.erb) you provide javascript, it will be executed. That is why everyone is replying you with a $('#my_div_id').html('my html text') suggestion, which when executed will replace your div content with the new HTML.

If for some reason you want to return a json data structure, then you should provide a different data-type:

form_tag("/jquery_ujs/search_query", remote: true, 'data-type' => :json) do
  # ....
end

And you should reply with:

# action
def search_query
  respond_to do |format|
    format.json { render json:  @my_object }
  end
end

And handle the success event:

<script>
  $(document).ready(function(){
    $("form#my_form").on('ajax:success', function(event, data, status, xhr) {
      console.log("Great!");

      // use data to access to your json data structure
    });

    $("form#my_form").on('ajax:error', function(event, xhr, status, error) {
      console.log("sorry mate!");
    });

    // ....
  })
</script>

You can also request a html response (in case you want to return a table, for instance), with :'data-type' => :html and format.html { render layout: false }

Upvotes: 5

Richard Peck
Richard Peck

Reputation: 76784

Ajax

Firstly, the Rails UJS (unobtrusive javascript) driver just gives you a "canned" way to send an ajax request to your browser. To avoid confusion, it's best to appreciate that you will be sending Ajax requests regardless of whether you use Rails UJS or the standard Ajax method

This means that the process of capturing the response from your Ajax is still the same - you need to make sure you have to catch the response from the system

Either :-

#app/assets/javascripts/application.js
$(document).on("ajax:success", ".element", function(status, data, xhr) {
   // do something here
});

or

#app/controllers/portal_controller.rb
class PortalController < ApplicationController 
  def search
     respond_to do |format|
        format.js #-> app/views/portal/search.js.erb
        format.html
     end
  end
end

#app/views/portal/search.js.erb
//something here

Fix

how do I get that partial inside the div element

You'll be able to use JS:

#app/controllers/portal_controller.rb
class PortalController < ApplicationController
   def search
      @results = ...
      respond_to do |format|
         format.js
         format.html
      end
   end
end

#app/views/portal/search.js.erb
$(".div").html("<%=j render @results %>");

Upvotes: 1

NicoFerna
NicoFerna

Reputation: 613

Let's say you get @results out of your search method.

In the controller, search method:

respond_to do |format|
  format.html {render or redirect_to wherever you need it}
  format.js 
end

Then all you need is a file named search.js.erb to run the required js at the end of your request. It might look something like:

$('#results_div').html("<%= j @results.pluck(:title).join('<br/>') %>")

Upvotes: 9

Related Questions