dev404
dev404

Reputation: 1098

How to pass parameters from a form_tag to a routes URL?

I'm not sure if this is possible, feel free to smack me back to reality if it's not.

I have a controller, Reports, that displays a table in the view of a method/action called 'filtered', and I'd like to add a "filtering" property to it. My approach to this was adding an extra route, to keep the URLs tidy.

 reports      GET /reports(.format)                  reports#filtered
 args_reports GET /reports/:concept/:id(.format)     reports#filtered

So, without arguments, I'd get the full table, and if I add the two extra parameters (concept and id), I'd get a filtered table based on the criteria selected. This works well when I do it manually.

Now, I'd like to pick both the :concept and :id from a dropdown menu box. The :concept data is nothing but a selection of two fields (which are hardcoded into the selection to avoid any possible code injection), while the :id data is picked by the user from the dropdown menu. I'm not too sure how to implement this.

I'm using HAML, and I currently have the following:

On the controller:

 @types=Type.all
 @type_current[:selected][email protected]

On the view:

 #rightdiv
   = form_tag(arg_reports_path(:concept => 'type')) do
     %table
       %tr
         %td Type
         %td=collection_select(:type, :id, @types.all, :id, :name, {:selected => @type_current[:selected]})
         %td=submit_tag 'Filter' 

But this tells me that I'm missing a required key, which is :id. I understand that perfectly, but where do I provide that data? I want the user to be able to pick that id, so I do not know before-hand what to include here, or how to tell the form_tag to pick up the id from the collection_select. Is that possible? Or I'm totally wrong in my interpretation?

Also, an small side question. The collection_select tag will provide a hash of "type[id]", is there a way to make it do "type" only instead of a hash?

Thanks in advance.

EDIT:

An example of what I'm trying to achieve is to get the form to send me to:

 /reports/type/9

Or, if we use the other concept:

 /reports/location/7

9 and 7 are the IDs of type and location, respectively. 'type' and 'location' are fields of the model Report, of which there're several and are contained in their respective models.

The dropdown menus would be populated with the names and ids of the tables 'type' and 'location', which are placed one after the other in the view. The user would select one of the two, which would then send them to a filtered table with the criteria picked.

Upvotes: 1

Views: 1553

Answers (1)

jvnill
jvnill

Reputation: 29599

If I understand correctly, /reports and /reports/:concept/:id both go to the same action, right? If this is the case, what you can do is just use /reports as the action for the form, and pass concept as a hidden input. The dropdown will have a name of id. So when the user submits the form, you still get a params[:concept] and a params[:id] in the controller. The downside of this is that the url will only appear as /reports.

What you want to achieve isn't possible without a little javascript. Anything that you need to change in the html that requires user input need javascript. Look at Changing the action of a form with javascript/jquery.

The collection_select tag accepts it's last parameter (7th or 6th) a list of html options. Change your code to the following so you get a

collection_select :type, :id, @types.all, :id, :name, { :selected => @type_current[:selected] }, { :name => 'type' }

Upvotes: 2

Related Questions