diff --git a/lib/superform/rails.rb b/lib/superform/rails.rb index b93ede9..844fc5c 100644 --- a/lib/superform/rails.rb +++ b/lib/superform/rails.rb @@ -69,6 +69,10 @@ def select(*collection, **attributes, &) Components::SelectField.new(self, attributes: attributes, collection: collection, &) end + def multiple_select(*collection, **attributes, &) + Components::MultipleSelectField.new(self, attributes: attributes, collection: collection, &) + end + def title key.to_s.titleize end @@ -331,10 +335,33 @@ def false_option(&) end protected + def map_options(collection) OptionMapper.new(collection) end end + + class MultipleSelectField < SelectField + def template(...) + # The HTML specification says when multiple parameter passed to select + # and all options got deselected web browsers do not send any value to + # server. Unfortunately this introduces a gotcha: if a User model has + # many roles and have role_ids accessor, and in the form that edits + # roles of the user the user deselects all roles from role_ids + # multiple select box, no role_ids parameter is sent. + input(type: "hidden", name: dom.name, value: "") + super(...) + end + + protected + + def field_attributes + super.merge( + name: "#{dom.name}[]", + multiple: true + ) + end + end end end end