57 votes

Ruby on Rails -- sélection multiple dans f.select

J'ai la boîte de sélection suivante dans mon formulaire :

Related Type: &nbsp; <%= f.select(:TYPE, [['Type A', 'Type A'],
                                  ['Type B', 'Type B'],
                                  ['Type C', 'Type C'],
                                  ['Type D', 'Type D'],
                                  ['Type E', 'Type E']
                                 ],{ :prompt => "Please select"}
                                 ) %>

Je souhaite permettre à l'utilisateur d'effectuer des sélections multiples et de modifier la taille de la boîte de sélection (5).

Comment faire pour le code ci-dessus ?

83voto

mikej Points 30224

Après votre { :prompt => "Please select"} ajouter un autre hash avec des options html, par exemple

<%= f.select(:TYPE, [['Type A', 'Type A'],
                                  ['Type B', 'Type B'],
                                  ['Type C', 'Type C'],
                                  ['Type D', 'Type D'],
                                  ['Type E', 'Type E']
                                 ],{ :prompt => "Please select"},
                                   { :multiple => true, :size => 5 }
                                 ) %>

Une fois que vous avez fait cela, vous pouvez déplacer votre :prompt (conserver l'option {} afin que les attributs html ne soient pas traités comme des options Rails).

Vous devrez également vous assurer que le code de votre contrôleur accepte et gère correctement les valeurs multiples.

7 votes

Pourquoi cela ajoute-t-il "---" et "-" pour chaque option non sélectionnée stockée dans :TYPE ?

3 votes

Lorsque je l'enregistre dans le formulaire, il prend un "" vide supplémentaire à la position 0 "ids" => [ [0] "", [1] "some_id" ]

11voto

Swathi Points 29

En cas de collecte, essayez

    <%= f.select(:TYPE, Categories.collect {|p| [ p.name, p.id ] }, 
                                           { :prompt => "Please select"}, 
                                           { :multiple => true, :size => 5 }) %>

1 votes

Ne devrait-il pas être Category.all.collect ?

9voto

Augustin Riedinger Points 1600

J'ai un exemple qui fonctionne parfaitement (y compris la présélection lors de l'édition de l'objet) :

  • Object est l'objet considéré
  • similar_ids est la clé des relations, et c'est un string

Dans le formulaire :

form_for(@object) do |f|
  = f.select :similar_ids, options_from_collection_for_select(Object.all, :id, :name, {:selected => @object.similar_ids.split(';')}), {}, {:multiple => true, :size => 4, :name => 'object[similar_ids][]'}

Et dans le Object.rb modèle :

class Object < ActiveRecord::Base
  before_save :handle_similars

  def handle_similars
    self.similar_ids = self.similar_ids.select(&:present?).join(';') 
    # .select(&:present?) is necessary to avoid empty objects to be stored
  end

  def similars
    self.class.find(self.similar_ids.split(';'))
  end

end

Ces articles m'ont aidé :

J'espère que cela vous aidera

1 votes

Il est important que le nom se termine par [] afin que rails interprète les params comme un tableau de valeurs

2voto

Sanjay Choudhary Points 136

HTML

<%= form.select(:product_ids, Product.all.collect {|p| [ p.name, p.id ] }, 
                                                   { :prompt => "Please select"}, 
                                                   { :multiple => true, :size => 5  }) %>

Contrôleur

@category = Category.new(category_params) 

def category_params
    params.require(:category).permit(:name, product_ids: [])
end

0voto

FelixOuttaSpace Points 93

Avec un sélecteur bootstrap et des valeurs pré-sélectionnées :

    = simple_form_for [:backend, @user], html: { autocomplete: 'off' } do |f|
      = f.select :role_ids, options_for_select(Role.all.map{|role| [role.name, role.id]}, @user.role_ids), {},  {:multiple => true, inlcude_blank: false, class: "form-control input-sm selectpicker"}

dans le contrôleur :

def user_params
      params.require(:user).permit(:id, role_ids: [])
end

# only if you havent build in new action
def new
  # set user
  @user.roles.any?
end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X