Rohan Mayya
Rohan Mayya

Reputation: 206

rails search bar not working

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

Answers (1)

Victor Alexandre
Victor Alexandre

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

Related Questions