Co2
Co2

Reputation: 353

RoR - dynamic dropdown with checkboxes

I am looking to implement a dynamic dropdown with checkboxes in it so the sender of a message can choose multiple receivers.

Currently I just have a list of recipients under the message textarea.

_recipients.html.erb:

<% @recipients.each do |user| %>
  <label for="user<%= user.id %>" >
    <span class="list-group-item"><%= user.full_name %></span>
    <%= check_box_tag "message[user_tokens][]", user.id, @message.users.include?(user), id: "user#(user.id)", class: "form-control" %>
  </label>

User.rb:

class User < ActiveRecord::Base

  rolify
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  validates :full_name, presence:true,
            length: {minimum: 4 }

  has_many :messages, foreign_key: :sender_id
  has_many :notes
  has_many :homeworks
  has_many :hw_comments
  belongs_to :classmodule
  belongs_to :student

recipient.rb:

class Recipient < ActiveRecord::Base
    belongs_to :message
    belongs_to :user

    validates :user_id, presence: true
end

messages_controller.rb:

class MessagesController < ApplicationController
    before_action :authenticate_user!

    def new
        @message = Message.new
        @recipients = User.all 
        @recipients = @recipients.page(params[:page]).per(8)
    end

    def create
        @message = current_user.messages.build(message_params)

        if @message.save
            flash[:success] = "Message sent"
            redirect_to messages_path
        else
            flash[:alert] = "Something went wrong"
            render :new
        end
    end

    def index
        @messages = Recipient.where(:user_id => current_user.id).order('created_at DESC')
    end

    private
    def message_params
        params.require(:message).permit(:title, :body, :sender_id, user_tokens: [])
    end 
end

Is it possible to get the checkboxs and names in to a dropdown with collection_select for example? Happy to provide more code if required. Thanks.

Upvotes: 0

Views: 1190

Answers (2)

Alex.U
Alex.U

Reputation: 1701

There are different approaches, like using bootstrap select with multiple, this way you'd only have one select with the ability to select multiple options. For which you'd have to adapt your message_params.

Another approach is using simple_form and cocoon, as cocoon handle the render of new "views" on associated models. Could be something as simple as having:

(using slim for convenience)

recipient_fields.slim

.nested-fields
  = f.collection_select :user_id, User.all, :id, :name
  = link_to_remove_association 'remove recipient', f

And render a new view each time you want to add a new recipient with:

link_to_add_association, handling rendering and destroying html elements by cocoon.

Upvotes: 0

trh
trh

Reputation: 7339

If you're using bootstrap you can do this with a dropdown , see example http://www.bootply.com/8V6EpWyMO3

(though you might consider some manual overrides in the js for how sensitive the click is about what is clicked)

For the rails part

If you aren't using simple form and you do want the bootstrap solution you'll need to write a custom input.

Upvotes: 0

Related Questions