I have a route like this:
match '/:search/:page', :to => 'search#create'
and in my form:
<%= form_for :search, :url => {:controller => 'search', :action => 'create', :page => 1, :search => ???} do |f| %>
I need to pass something to :search
but I want it to be the value that is submit开发者_StackOverflowted with the form. What do I do?
There is no straight way to do that as form with url (action) must be rendered before user types anything into search. So you need initial value, but it may not make sense when you don't know what user wants to type in. GET form with parameters would solve it but I suppose you want "nice" search urls.
Generally there are two options:
You can't change URL path by simple form submittion - only params (?x=1&y=2...) may be added. But you can modify whole URL by JavaScript when user types something to search input (onchange) or submits form (onsubmit).
Use another action which will receive standard form input values then redirect it to proper url. E.g.
/searchforward?search=Query&page=1
should forward to/Query/1
.
routes.rb:
match 'searchforward', :to => 'search#searchforward'
match '/:search/:page, :to => 'search#create', :as => :search
controller:
def searchforward
redirect_to search_path(params[:search],params[:page]
end
If you set a value in form_for
, where you have it now, it will be part of the address the form is sent to, therefore you will be able to get it in the controller through params[:search]
.
You can also make a text field (text area, select box, etc.) for the user to fill the value, as e.g. described in APIDock. You can even have a hidden field, which will not be displayed to the user, but still submitted with the form. In any case, it will be available through params[:search]
.
Edit Another way of understanding your question is that you want the search
parameter in form_for :url
to be passed dynamically based on whatever user typed. In this case I can think of three solutions:
Option 1. Submit the form to somewhere independent of :search
and redirect from there:
Form: form_for :search, :url=>{:controller=>"search", :action=>"handle"}
SearchController
:
def handle
case params[:search] of
when :foo then redirect_to some_path(params[:search], ...)
when :bar then redirect_to other_path(params[:search], ...)
end
end
The disadvantage is that you cannot make a POST-redirect, only GET. The advantage is that the form is processed in one place. Since it is - why not including the whole handling there and skip redirecting? That would be an option I would consider.
Option 2. Use some JavaScript to alter the action
parameter of the form
HTML element before submission.
Option 3. Use some JavaScript to generate a form based on an earlier selection.
In this scenario there are two forms, only one of which is user-submittable through a button. The first form contains only a drop-down box (text box, radio buttons) and a JavaScript form observer. Based on the value this observer displays the proper form - note that the :search
value entered by the user is known at this point when the form is rendered.
Of course, insead of the first form you can use a collection of links if the choice of :search
options available to the user is limited. Option 3 is probably not ideal in terms of performance, but should be nice enough to extend, understand and reuse it later.
There might be some other ways to do it, though.
精彩评论