Reputation: 206
I ran a scaffold earlier to create a database filled with stocks. They've got a name, a ticker name and a price. What I intend to do now is create a search bar to query these stocks at users will asynchronously. (AJAX) Here is my javascript:
var init_stock_lookup;
init_stock_lookup = function() {
$('#stock-lookup-form').on('ajax:success', function(event, data,
status){
$('#stock-lookup').replaceWith(data);
init_stock_lookup();
});
$('#stock-lookup-form').on('ajax:error', function(event, xhr, status, error){
$('#stock-lookup-results').replaceWith(' ');
$('#stock-lookup-errors').replaceWith('Stock was not found');
});
}
$(document).ready(function() {
init_stock_lookup();
})
My controller
def search
if params[:stock]
@stock=Stock.find_by_ticker(params[:stock])
end
if @stock
render partial: 'lookup'
else
render status: :not_found, nothing: true
end
end
The method I've created in my stock.rb file to use in my controller.
def self.find_by_ticker(ticker_symbol)
where(ticker: ticker_symbol).first
end
And finally, my view file (_lookup.html.erb)
<div id="stock-lookup">
<h3>Search for stocks</h3>
<%= form_tag search_stocks_path, remote: true, method: :get, id:
"stock-lookup-form" do %>
<div class="form-group row no-padding text-center col-md-12">
<div class="col-md-10">
<%= text_field_tag :stock, params[:stock], placeholder: "Stock
ticker symbol", autofocus: true, class: "form-control search-box
input-lg" %>
</div>
<div class="col-md-2">
<%= button_tag(type: :submit, class: "btn btn-lg btn-success")
do %>
<i class="fa fa-search"></i> Look up a stock
<% end %>
</div>
</div>
<% end %>
<%if @stock %>
<div id="stock-lookup-results" class="well results-block">
<strong>Symbol:</strong> <%= @stock.ticker %>
<strong>Name:</strong> <%= @stock.name %>
<strong>Price:</strong> <%= @stock.price %>
</div>
<% end %>
<div id="stock-lookup-errors"></div>
</div>
I have a route to "stocks#search" but when I use this search bar, I don't get any results. The search icon seems to do nothing. However, when I go to my URL/search_stocks?Stock="enter stock name present in your databse here" I get results AND it renders the lookup partial. How do I get my actual search bar to function?
Upvotes: 0
Views: 466
Reputation: 151
Solias, when you use a form with remote option, the Unobtrusive Javascript driver will control the submit behaviour (an AJAX submit by default, see documentation for form_tag method), so the controller action needs to respond with correct content.
First of all, the action must respond correctly to the format specified in the request:
def search
if params[:stock]
@stock = Stock.find_by_ticker(params[:stock])
end
# This will require a JS view by the same name as the action,
# in which we can put javascript logic to display the results.
respond_to(&:js)
end
Then, in app/views/.../search.js.erb (notice the file extension, as a Javascript document):
<% if @stock %>
$("#stock-lookup-results").replaceWith("<%= j render 'stock_lookup_results', stock: @stock %>");
$("#stock-lookup-errors").replaceWith('');
<% else %>
$("#stock-lookup-results").replaceWith("");
$("#stock-lookup-errors").replaceWith('Stock was not found');
<% end %>
You can separate the results as another partial, app/views/.../_stock_lookup_results.html.erb:
<strong>Symbol:</strong> <%= stock.ticker %>
<strong>Name:</strong> <%= stock.name %>
<strong>Price:</strong> <%= stock.price %>
Finally, in app/views/.../_lookup.html.erb, since you're not rendering it anymore on the action, it's possible to just set the divs to be used with stock results.
<div id="stock-lookup">
<h3>Search for stocks</h3>
<%= form_tag search_stocks_path, remote: true, method: :get, id: "stock-lookup-form" do %>
<div class="form-group row no-padding text-center col-md-12">
<div class="col-md-10">
<%= text_field_tag :stock, params[:stock], placeholder: "Stock ticker symbol", autofocus: true, class: "form-control search-box input-lg" %>
</div>
<div class="col-md-2">
<%= button_tag(type: :submit, class: "btn btn-lg btn-success") do %>
<i class="fa fa-search"></i> Look up a stock
<% end %>
</div>
</div>
<% end %>
<div id="stock-lookup-results" class="well results-block"></div>
<div id="stock-lookup-errors"></div>
</div>
With this, the search bar will work nicely with AJAX requests without trying to render the same partial, in which you already have the form.
Upvotes: 1