Changing display text of submit button without changing value passed to controller

Please have a look at this form:

<%= form_for @data, url: data_path do |f| %>     ...     <%= f.submit("accept", name:"judgement") %>     <%= f.submit("reject", name:"judgement") %> <% end %>

These buttons display "accept" and "reject". Clicking on the first button would pass

   "judgement" => "accept"

to the application. This is exactly what I want, but I want to be able to change the text which is visible on the button (for example, when displaying the page in a different language).

Can this be done?

Ronald

Please have a look at this form:

<%= form_for @data, url: data_path do |f| %>    ...    <%= f.submit("accept", name:"judgement") %>    <%= f.submit("reject", name:"judgement") %> <% end %>

These buttons display "accept" and "reject". Clicking on the first button would pass

  "judgement" => "accept"

to the application. This is exactly what I want, but I want to be able to change the text which is visible on the button (for example, when displaying the page in a different language).

Can this be done?

Probably, through the i18n framework, but if you do that, you'll have to pass any recognition of the button value (in your controller) through the same framework. That's because the value will be changed, so judgement: [accept in another language] rather than accept.

You could possibly do this in JavaScript, such that your form submit behavior was to translate the language back when the button was clicked and before the form was sent to the server. Maybe something like this (leaving out the Rails generators at the moment):

  <input type="submit" value="[accept in dutch]" data-value="accept">

  // Prototype-flavored JavaScript   $('my_form').observe('submit', function(evt){     evt.stop();     this.select('input[data-value]').each(function(elm){       elm.setValue(elm.readAttribute('data-value'));     });     this.submit();   });

That should allow you to have the internationalized cake and eat it too.

Walter

Thanks for the suggestion. I had not expected, that there is no *simple* solution for the problem, since it seems to me such an obvious issue.

If I do it with JavaScript, wouldn't the following strategy be simpler?

- I set up a hidden text field and a hidden button inside the form.

- My two (visible) buttons don't "belong" to the form, but have a JavaScript function attached.

- Hence, the form has only one submit button, not two (and this button is not visible)

- When the user clicks on one of the visible buttons, the Javascript function places some value (according to which button has been clicked) into the hidden text field, and calls form.submit()

- My controller doesn't do a check on the button, but on the hidden textfield, to determine which button has been clicked.

What do you think about this way of doing it?

Ronald

Thanks for the suggestion. I had not expected, that there is no *simple* solution for the problem, since it seems to me such an obvious issue.

If I do it with JavaScript, wouldn't the following strategy be simpler?

- I set up a hidden text field and a hidden button inside the form.

- My two (visible) buttons don't "belong" to the form, but have a JavaScript function attached.

- Hence, the form has only one submit button, not two (and this button is not visible)

- When the user clicks on one of the visible buttons, the Javascript function places some value (according to which button has been clicked) into the hidden text field, and calls form.submit()

- My controller doesn't do a check on the button, but on the hidden textfield, to determine which button has been clicked.

What do you think about this way of doing it?

That would probably work just as well. The issue here is that you are switching on an internationalized value.

It occurs to me now that you could solve this another way, too. Simply give the two buttons different names, and test for the presence of the name, not its value. That way you could avoid the whole JavaScript thing entirely.

  if params[:accept].present?     # do your thing   end   if params[:reject].present?     # do the other thing   end

In this case, params[:accept] => 'Accept in Hungarian', but it doesn't matter one bit what that value is, as long as it is present in the form. If you are using an <input type="submit"> field, then only the button that got pushed will be sent along with the params; similar to checkboxes, those submit fields that are not interacted with are never sent with the form body. Example here: Button, Button

Walter

That would probably work just as well. The issue here is that you are

switching on an internationalized value.

No, that's exactly not the case. The switching is done based on the value of the hidden field. The JavaScript function called from clicking the "internationalized" buttons places some code into this field (say, 0 for reject and 1 for accept) and then calls form.submit(). My controller only checks for the 0 or 1, and is never aware of the actualy value of the buttons. Actually, the controller doesn't need to check any button in this solution.

Ronald

It occurs to me now that you could solve this another way, too. Simply give the two buttons different names, and test for the presence of the name, not its value.

I thought of this too (and actually used this solution in a related project, just to verify that it works). I didn't like it so much from a viewpoint of style, if we check for presence of the keys instead of the value of a field. Of course, this is a matter of taste, and at least it is much simpler to understand on the HTML side, compared to having two extra hidden fields.

I think there is no solution which I would *really* find satisfying, so maybe I will just go for the one which is least ugly. :smiley:

Thank you a lot for providing such an elaborate example!!!!

Ronald