Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Hidden input for multiple selects in 1.2-stable #802

Merged
merged 4 commits into from

5 participants

@kchien

This incorporates the code from @fbuenemann; I simply wrote a spec to check for the new hidden input.

My 'hidden_input' branch is based off of 1.2-stable and I rebased @fbuenemann's branch on top of mine.

@justinfrench

Shouldn't the hidden tag come before the select?

if html_options[:multiple]
  create_hidden_field_for_multiple_select(input_name) << select_html
end

?

@felixbuenemann

@justinfrench given that the code worked fine for me in production, I don't think that it matters.

@kchien

I too, thought that the hidden tag should appear before the select, but I just tried it and it worked for me as well.

@justinfrench

The approach we've taken elsewhere in the code is to put them first, so I'd like to see this switched around and tested pretty please :)

@felixbuenemann

@kchien you can merge/cherry-pick a096d4b from my branch. This puts the input after the label, but before the select.

@kchien

@fbuenemann - Thanks; I cherry-picked that commit , and edited my spec by making the check more specific.
@justinfrench - Please take a look at the modifications and let us know what you think. Thank you!

@justinfrench justinfrench merged commit 5459c19 into justinfrench:1.2-stable
@justinfrench
Owner

merged in, thanks!

@sailor

I can't figure out why do we need hidden fields before each multi-selects? In my application, i systematically get 2 hidden fields before the select, which gives something like that in my controller foo: ["", "", "bar"].

@justinfrench
Owner

@sailor can you please open a new issue with example code to repeat the issue?

@dmitry

I have the same problem as @sailor have. And I also don't understand why do we need hidden fields.

Thank you.

@justinfrench

@dmitry we need hidden inputs because browsers do not post the attribute if none of the checkboxes or multi-select options were chosen. Mass assignment and ActiveRecord's update_attributes no longer knows if you wanted to unselect all options, or to not update that attribute at all. This is the same problem we have with unchecked checkboxes, and Rails "solved" this with a hidden field. We do the same here. If the choices we've made don't make sense to you, you can quickly change this with a custom input.

The issue of having two hidden fields instead of one is definitely a bug (please, someone, give me a test case!), but I don't want to continually debate the idea that we should have none :)

@dmitry

@justinfrench Thank you for the explanation. I though about that case, actually.

FYI, I just want to describe case, when there are no need for the hidden input. An example is, when using meta_search with scopes. As scopes invoked with the params from the search, and params have empty strings (because of multiselect). To fix that, you should check params for presence in every scope that uses multiselect.

@justinfrench

@dmitry would love to see a pull request if you've got ideas, thanks!

@dmitry

@justinfrench Investigated that problem a bit.

Hidden input addition was introduced in nashby/rails@9eb6cd6

Then include_hidden was introduced in new rails 4.0: nashby/rails@54a75e1

So hopefully, hidden logic can be removed in the next minor version: 1.3
And after that in new rails it will be possible to use multiple select without hidden field, just including an option: include_hidden: false

What do you think @justinfrench? When the new minor version of formtastic is planned?

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 16, 2012
  1. @kchien
  2. @felixbuenemann @kchien

    Insert hidden field for multiple selects to allow clearing.

    felixbuenemann authored kchien committed
    This approach is similar to what's needed to clear multiple
    checkboxes.
Commits on Feb 18, 2012
  1. @felixbuenemann @kchien

    Prepend hidden field instead of appending

    felixbuenemann authored kchien committed
  2. @kchien
This page is out of date. Refresh to see the latest.
Showing with 19 additions and 0 deletions.
  1. +10 −0 lib/formtastic.rb
  2. +9 −0 spec/inputs/select_input_spec.rb
View
10 lib/formtastic.rb
@@ -843,11 +843,21 @@ def select_input(method, options)
select(input_name, collection, strip_formtastic_options(options), html_options)
end
+ if html_options[:multiple]
+ select_html = create_hidden_field_for_multiple_select(input_name) << select_html
+ end
+
label_options = options_for_label(options).merge(:input_name => input_name)
label_options[:for] ||= html_options[:id]
label(method, label_options) << select_html
end
+ # Outputs a custom hidden field for multiple selects
+ def create_hidden_field_for_multiple_select(method) #:nodoc:
+ input_name = "#{object_name}[#{method.to_s}][]"
+ template.hidden_field_tag(input_name, '')
+ end
+
# Outputs a timezone select input as Rails' time_zone_select helper. You
# can give priority zones as option.
#
View
9 spec/inputs/select_input_spec.rb
@@ -370,6 +370,15 @@
output_buffer.concat(@form) if Formtastic::Util.rails3?
output_buffer.should have_tag('form li select option[@selected]', :count => 1)
end
+
+ it 'should have a hidden input for multiple selects' do
+ @form = semantic_form_for(@fred) do |builder|
+ concat(builder.input(:posts, :as => :select, :multiple => true, :include_blank => true))
+ end
+
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
+ output_buffer.should have_tag("form li input[@type='hidden'][@name='author[post_ids][]']")
+ end
end
describe 'for a has_and_belongs_to_many association' do
Something went wrong with that request. Please try again.