Reputation: 30404
I am trying to build a custom form builder in simple_form
, which add some hidden fields to a form without using form.hidden_field
. I noticed that the utf8
and authenticity_token
hidden fields are automatically added to every form.
Is there a similar mechanism to add another custom hidden field, but only to forms that are generated by my custom form builder?
Upvotes: 0
Views: 664
Reputation: 30404
The secret ist to use capture, which allows you to get the HTML generated in the template. You can then add hidden fields using the form.hidden_field
method (in fact any method), which returns the generated HTML directly.
def custom_form_for(object, *args, &block)
options = args.extract_options!.merge(builder: CustomFormBuilder)
simple_form_for(object, *(args << options)) do |form|
capture do
block.call(form)
end.tap do |content|
content << form.hidden_field "foo", value: "bar"
content << form.hidden_field "baz", value: "qux"
# ...
end
end
end
Upvotes: 1
Reputation: 4465
You could extend your custom_form_for
mehtod like this
def custom_form_for(object, *args, &block)
options = args.extract_options!
simple_form_for(object, *(args << options.merge(:builder => CustomFormBuilder))) do |form|
block.call(form) << form.input_field(:field, :as => :hidden, :value => 'value')
end
end
The hidden field will be the last element of the form; if you switch the lines it will be the first.
Upvotes: 1
Reputation: 1763
Instead of patching this at FormBuilder level, you can integrate this into a custom input:
class MagicInput < SimpleForm::Inputs::HiddenInput
def input
if object.condition?
@builder.hidden_field(:hidden_field_name, value: "some value").html_safe
# You could also call #super here (instead of the previous call)
# because this extends HiddenInput (might be cleaner, depending on what you
# want to achieve)
end
end
end
This custom input injects a hidden field into your form only if object.condition?
is true.
Obviously you'll need to create the #condition?
method on the object passed to your form (or replace this condition line with wathever floats your boat).
Then in your view you'd call it like:
= f.input :something, as: :magic
And your hidden field will appear only when object.condition?
passes.
Edit: And for the juicy detials - the utf8
and authenticity_token
hidden fields are implemented in form_tag
- not really in the FormBuilder: https://github.com/rails/rails/blob/801e159ce2f4645f6839c94ab0febf97a0d8543d/actionview/lib/action_view/helpers/form_tag_helper.rb#L713
Upvotes: 6