4 ms·
I've had two related questions about Rails [1] for a few years and never found a good answer. Perhaps you could help me? 1. I'd like several submit buttons on
by Robin_Message 16y ago
I've had two related questions about Rails [1] for a few years and never found a good answer. Perhaps you could help me?
1. I'd like several submit buttons on a form that do different things. I'd also like to input data alongside some of the buttons, e.g. to allocate some % of a resource.
My problem is I can't work out how to sensibly do this without repeating myself, or having a very hacky controller. How can I do this without matching on the value part of the submit buttons (the text on the buttons, since that is bad for i18n and in some cases the text is the same anyway), and without using any javascript?
2. If you have two forms on a page, can you set it up so changes on both forms are saved when any submit button is clicked? Again, without javascript. Obviously you need to override the form tag generator so the page only has one actual form; is there a standard solution to this somewhere?
[1] http://stackoverflow.com/questions/461790/multiple-submit-buttons-forms-in-rails http://stackoverflow.com/questions/461790/multiple-submit-bu...
- epochwolf 16y agoGeneral advice first :) If you can't get stuff working with the rails helpers you can always hand write the html yourself. I need to do this once in awhile. I prefer using formtastic for my current project and I've had to hand write some html to add custom logic to a formtastic form. (I prefer not to abstract one off hacks until I need to do it twice) Rails does a lot of stuff but it doesn't do everything. If the built in tools don't do it, build your own. > 1. I'd like several submit buttons on a form that do different things. The only way to target these is javascript hackery, use the text on the submit button or find an alternative method that doesn't rely on multiple forms. > 2. If you have two forms on a page, can you set it up so changes on both forms are saved when any submit button is clicked? Without javascript, not happening. For a rails solution to combine two forms, look at fields_for. All that said, Without specific details (screenshots, etc.) I can't really figure out what you are trying to do. I assume you have a valid reason for asking the question. Sorry if I wasn't able to help.
- Robin_Message 16y agoThanks, this was helpful, especially fields_for. On the point of building my own, that's what I've done, but these felt like an obvious things to want (I implemented them both in my own PHP framework.) Thinking about it, the standard Rails CRUD index provides delete links instead of buttons; IMHO that is totally wrong, but when all you have is a hammer... Also, button_to is not good enough as it makes its own form, which breaks any solution to question 2. On question 1, what I want is to generate submit buttons like <input type=submit name=some_non_clashing_string_that_identifies_this_button value=ButtonText> and then have this routed to a function nicely. I've not found a standard way of doing that; maybe I should write one? Could you see it being useful?
- epochwolf 16y agoIt definitely sounds like you are doing something wrong. Rails really wants you to do things it's way. You don't have to, rails, especially version 3, is only generated html and routes to functions. It just generates a lot of stuff for you. If you want to work outside of the provided functionality it's just going to be harder. In fact the application I'm using at work right now uses ExtJS for views and half of the data is retrieved through manual queries. Rails is not designed to do this but it can work, if you are willing to put in the effort to work around missing functionality. I do not recommend using rails as a hammer, it's a very bad hammer. It's a chainsaw with diamond teeth and a 50 hp gas-powered engine. If you have a lot of wood to chop through, it's amazing. If you need to pound in a few nails, it's a little awkward. :)
- xentronium 16y agoYep, for something simple just use Sinatra / other microframeworks.
- jules 16y ago1. Use <input type=submit name=submit value=submitbuttonN>. The server side will then get this data submit=submitbuttonN. 2. Yes. Just make the form a single big form with two submit buttons, so they look like two forms.
- Robin_Message 16y agoThanks, but I already ruled out both of these solutions. 1. I know you can look at the value of the submitted button on the server. What you need to use is actually <input type=submit name=some_non_clashing_string_that_identifies_this_button value=ButtonText>, so my question is how do you generate those strings nicely in Rails and have the controller act on them nicely as well. 2. Of course that's what you need to do, as I said in my question. My question was, how do I make Rails do this in a nice way? fields_for helps, but I'd like to know if there is a plugin or something better.
- erikpukinskis 16y agoIn your view you can just do this: - form_for concertgoer do |f| = f.submit "Submit", :name => "music[jazz]" = f.submit "Submit", :name => "music[classical]" That's HAML... let me know if you want to see the ERB. If you want to abstract even further you can do: # In app/helpers/concertgoer_helper.rb def music_submit(form, genre) form.submit "Submit", :name => "music[#{genre}]" end # In app/views/concertgoer/get_ready.html.haml - form_for concertgoer do |f| = music_submit(f, "jazz") = music_submit(f, "classical") Then in your controller you can just do: music = params[:music].keys.first That variable will either be "jazz" or "classical" depending on which button was clicked. If you want to have different behaviors you can use a case statement: case params[:music].keys.first when "jazz" then concertgoer.put_on_turtleneck when "classical" then concertgoer.pour_glass_of_wine end
- erikpukinskis 16y agoAs for (2), yes you can. Let's say you have a form that lets you update the status of your cat and your dog: # config/routes.rb map.resource :pets, :member => [:show, :update] # app/views/pets/status.html.haml - form_tag update_pets_path do .cat_fields - fields_for @cat do |f| = f.text_field :status = submit_tag .dog_fields - fields_for @dog do |f| = f.text_field :status = submit_tag # app/controllers/pets_controller.rb def show @cat = Pet.find_by_species("cat") @dog = Pet.find_by_species("dog") end def update ["cat", "dog"].each do |species| pet = Pet.find_by_species(species) pet.update_attributes(params[species]) end end