santhosh kumar
santhosh kumar

Reputation: 2019

How to do async call in Rails and show the result in current view?

I am working on a rails application, which based on the user input from selection drop down[call it as query page], hits the db backend and returns the result in a new page. Basically the page reloads and shows the result page[call it as result page].

I need to show the result page appended below the current elements of the query page. I have been trying for a while and not able to achieve this.

My query page:(rtes/r4d.html.haml)

= form_tag({:controller=>"r4d", :action=>"result"}, method: :get) do
  = label_tag(:q, "Trip Type: ")
  = select_tag(:q, options_for_select([["a",1],["b",2]),include_blank: 'Select one', required: true, class:"select")
  = submit_tag("Get Test Details")

My controller page which handles the db querying:(controllers/r4d_controller.rb)

class R4dController < ApplicationController
@@client=DynamoDBModel.new
def result

  result= case params[:q]
  when "1"
    @@client.1
  end

  @answer = result.value
  render "r4d/result" 
end
end

As you can see i am rendering the result to "r4d/result"

My result file: (r4d/result.html.haml)

%table{:id => "secondary"}
  %tr
    %th Key
    %th Value
%tr
  %td Trip ID
  %td #{answer}

How i can make this render to the same query page itself? One the user selects the drop down and submit a call needs to be made async and the result should be updated in the same page. If user makes another call, the existing result should be updated with the new one.

Your help is highly appreciated. Thanks.

Upvotes: 1

Views: 1972

Answers (1)

Toby 1 Kenobi
Toby 1 Kenobi

Reputation: 5037

Without the HAML this is what I'd do:

In the query page change the form_tag line to include remote: true so that the form submits with ajax. Like this:

<%= form_tag({controller: "r4d", action: "result"}, method: :get, remote: true) do %>

Also put an empty div at the bottom of the page to receive the results in and give it an ID:

<div id="query-results"></div>

In the controller action specify that it responds to an ajax query by replacing the render call with a responds_to call like this:

@answer = result.value
respond_to :js

Then make the appropriate javascript file to put the response onto the page. It should be under /app/views/r4d/ and in my case (no HAML) the file would be called result.js.erb to match the action name. This would be the contents (I'm making use of jQuery here):

$('#query-results').html("<%= j render(partial: 'answer_table', locals: {answer: @answer}) %>");

This will render the HTML partial /app/views/r4d/_answer_table.html.erb passing it the answer as a local, then it will make the rendering into a javascript safe string (that's what the j does) then, when the js runs, it will replace any content in that div we made with the new rendering.

Now we just need the partial (`/app/views/r4d/_answer_table.html.erb):

<table id="secondary">
  <tr>
    <th>Key</th>
    <th>Value</th>
  </tr><tr>
    <td>Trip ID</td>
    <td><%= answer %></td>
  </tr>
</table>

You'll have to do the converting to HAML yourself (or just put it through an online converting tool).

Upvotes: 3

Related Questions