Passing Javascript variables to Rails partials

2019-04-13 19:12发布

I am new in Rails and I am struggling on an apparently easy task. I have a (stripped down) form:

<%= form_for @order, html: { :class => 'form-inline' } do |f| %>
  <fieldset>
  <legend><%= params[:action].capitalize %> Order</legend>

  <table class="table">
    <thead>
      <tr>
        <th><%= f.label :symbol %></th>
        <th><%= f.label :price %></th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td><%= f.text_field :symbol, class: 'input-small' %></td>
        <td><%= f.text_field :price, class: 'input-small' %></td>
      </tr>
    </tbody>
  </table>

  <div id='here'></div>

  <%= f.submit "Submit", class: "btn btn-primary" %>

  </fieldset>
<% end %>

<%= link_to 'Get quote', view_quote_orders_path, remote: true %>

I want to render the quotation in google finance in the div $(#here) when I click on 'Get quote' and when the symbol text field loses focus. I have already written the code to extract the quotation in Ruby.

In routes.rb I added:

  resources :orders do
    get 'view_quote', on: :collection
  end

In order_controller.rb I added:

def view_quote
  respond_to do |format|
    format.js { render :layout => false }
  end
end

and in view_quote.js.erb:

sym = $('.orders #order_symbol').val();
$('#quotes').html("<%=j render 'googlequote', symbol: sym %>");

and in _googlequote.html.erb (where I will put the logic to extract the quotation):

<%= symbol %>

The error is in view_quote.js.erb, because sym is undefined. If I replace the second line with:

$('#quotes').html("<%=j render 'googlequote', symbol: 'just_a_test' %>");

the partial is rendered, but of course I don't need it. How can I pass the javascript variable sym to the partial _googlequote.html.erb? Otherwise, is there a better way to accomplish my objective?

3条回答
乱世女痞
2楼-- · 2019-04-13 20:02

Thank you @ben-taitelbaum and @ajcodez, in the end I used a different approach, suggested in example 4 of this excellent article and the comment therein of RyanonRails.

In this way, after capturing the symbol field change event, the symbol is passed to the controller where the logic (scraping the quotation from google finance) is implemented. The result is passed again to javascript in json format to insert in the layout.

查看更多
爷的心禁止访问
3楼-- · 2019-04-13 20:07

You are making a GET request on the Orders collection. Which means all of them. If you want to use the symbol from the order model, make the request on a member.

Otherwise you can pass it as a parameter (what I think you're trying to do). If you want to pass it to the server every time it changes, I would suggest the jQuery change method. Then you could make an ajax request:

$.get('/orders', { sym: $('.orders #order_symbol').val() }, function(response) {
   $('#here').html(response);
});

And in the controller:

def view_quote
  @sym = params[:sym]
  # use @sym in rendering partial
end
查看更多
做个烂人
4楼-- · 2019-04-13 20:10

You can't put it in erb, because erb is rendered on the server. One way to accomplish this would be to use the symbol as a param to view_quote, so you could have something like:

$('#quotes').html("<%=j render 'googlequote', symbol: params[:sym] %>");

(of course, you can wire up that param more RESTfully, but this is a good starting point).

查看更多
登录 后发表回答