0

In my view, I want to create one single search field with two buttons. Once I click the first one I want to use the string in the search field for searching for Users. When I click the second button I want to use the string in the field for searching for posts.

I think a solution whould look something like this:

<%= form_tag([users_path, posts_path], method: 'get', id: 'search-form') do %>
  <%= text_field_tag(:search, params[:search], id: 'search-field', placeholder: "Search") %>
  <%= button_tag(:id => "search-user-btn", :controller => :users) do %>
    <i class="icon-search-user"></i>
  <% end %>
  <%= button_tag(:id => "search-post-btn", :controller => :posts) do %>
    <i class="icon-search-post"></i>
  <% end %>
<% end %>

Is it possible to have one text_field and share it for two buttons routed each for a different controller (users and posts in this case)?

How can I do this?

1
  • I think you should be able to build a form with no action and then use JavaScript to submit to the correct controller. Should work. What I've done in the pass is make generic Search controller and then use the button to figure out what to search in the search controller. Commented Oct 30, 2015 at 0:34

2 Answers 2

3

In the view:

<%= form_tag([users_path, posts_path], method: 'get', id: 'search-form') do %>
  <%= text_field_tag(:search, params[:search], id: 'search-field', placeholder: "Search") %>
  <%= submit_tag 'Option1' %>
  <%= submit_tag 'Option2' %>
<% end %>

You can add the code in the current controller for each Submit button like this:

  def create
    @user = User.new(user_params)
          if params[:commit] == 'Option1'
            # code for Option1
          elsif params[:commit] == 'Option2'
            # code for Option2
          end

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
Sign up to request clarification or add additional context in comments.

Comments

2

If you want a direct answer, you'll be able to use the following:

<%= text_field_tag :search, params[:search], id: 'search-field', placeholder: "Search" %>
<% %w(posts users).each do |option| %>
   <%= button_to "Search #{option.titleize}", eval("#{option}_path"), id: "search-#{option}-btn", method: :get, params: { search: "" } %>
<% end %>

You'd then be able to use some JS to fill out the button_to hidden search fields whenever you change the "main" search:

#app/assets/javascripts/application.js
$(document).on("keyup", "#search-field", function(){
   val = $(this).val();
   $("#search-posts-btn").val(val);
   $("#search-users-btn").val(val);
});

When submitted, each button_to will yield the respective search value.

--

An alertnative method, as mentioned by hugo is to send all the requests to a single controller action, processing the data as required.

Hugo's answer is pretty epic, but there's a small change I would make:

#config/routes.rb
get "search(/:search)", to: "application#search"

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   def search
      if params[:search]
        case params[:search][:commit]
          when "option1"
             # Search users
          when "option2"
             # Search posts
        end
      end
   end
end

This will allow you to use the form that Hugo provided, sending the entire form data to /search for processing.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.