Reputation: 1723
I'm still new to rails and simple_form and have been trying to implement a multiple select option to give a user multiple roles.
Current input looks like this
<%= f.input :secondary_role, :collection => UseridRole::VALUES, :include_blank => false,:label => "Secondary Role(s):", :input_html => { :class => " simple_form_bgcolour simple_form_position overide_selection_field_width", :size => 4, multiple: true } %>
So, this does work, but is including an empty value at the start of my array:
"secondary_role" : [
"",
"admin"
]
I have the same code above which works for my primary_role value which is a string, but my secondary_role can have multiple values so is stored as an array.
Where should I be looking to fix this issue?
Upvotes: 6
Views: 3329
Reputation: 7339
There are several options to get away with empty values for multi-selects.
As with most things in web dev, there's a million ways to skin this cat.
If you choose, you can catch the form in JS, remove the empty strings then call form.submit -- In this case for you, there's no real benefit over the other options
You can use reject the empty ones in your params methods
def object_params
obj_p = params.require(:user).permit(:primary_role, secondary_role: [] )
obj_p[:secondary_role].reject! { |role| role if role == ""}
up
end
#app/models/object_model.rb
before_save :remove_blanks
private
def remove_blanks
self.secondary_role.reject!(&:blank?).to_s
end
If the option might ever be updated outside of your controller, then the DRYer way is in the model.
You can't remove all the blanks if you're trying to catch elements of an array that have been removed, it will work if there is still an item in the array, at least one, but if you remove all the elements, it won't pass the form element to the controller at all.
Instead use the form to dictate to the user to set to nil & use the model method above:
<%= f.input :secondary_role, :collection => UseridRole::VALUES, :include_blank => "Remove All Secondary Role(s)", :label => "Secondary Role(s):", :input_html => { :class => " simple_form_bgcolour simple_form_position overide_selection_field_width", :size => 4, multiple: true } %>
In addition, if that option is selected, I would probably use javascript to unselect everything else, just so that it's obvious to the user what is about to happen.
Something like this js snippet
var el = document.querySelector("#user_secondary_role")
el.addEventListener('change', function() {
if (el.value == "") {
roles = el.querySelectorAll("option")
for (var value of roles) {
(value.value == "") ? value.selected = true : value.selected = false
}
}
});
Then in your model use the remove_blanks method on a before_save call last listed in option 3.
Breakdown. Here's what's happening.
Upvotes: 3
Reputation: 2695
It seems like Rails is adding a hidden field to the collection. Try adding include_hidden: false
to your form input.
Upvotes: 8