Asan
Asan

Reputation: 151

Rails 4 Bootstrap Modal

This is a shopping cart to sell vitamins and supplements. I have a shelf model serving as a placeholder to display products. The products are grouped by Serving groups "30 servings, 60 servings etc..."

Using a link, I'm trying to open a modal with the supplement facts picture of the product.

I'm trying to pass the id of the product in the link like this:

<%= link_to " Supplement Facts", "#pictureModal", "data-toggle" => "modal", :id => @product %>

Also tried this:

<%= link_to " Supplement Facts", "#pictureModal", "data-toggle" => "modal", :product_id => @product %>

The problem is that the picture opening in the modal belongs to the Shelf and not the product. I'm guessing that the product id is not being passed to the modal. To confirm that this is happening I've included this line in the modal to check the product id, but instead I'm getting the shelf id:

<%= @product.id  if @product.present? %>

Is this a better approach?: How to add bootstrap modal with link_to so the link content open in modal ? I also followed the answer in that question without success.

Thanks!

routes.rb

Myapp::Application.routes.draw do

  resources :servings
  resources :brands
  resources :categories
  resources :charges
  resources :shipping_addresses, only: [:update, :create, :edit, :destroy, :new, :index]
  resources :subproducts

  get 'order_items/create'

  get 'order_items/update'

  get 'order_items/destroy'

  get 'check_shipping_address' => 'orders#check_shipping_address'

  get 'my_account' => 'users#my_account'

  resources :orders
  resources :purchases, only: [:show, :destroy, :update]

  # get 'orders/checkout' => 'orders/#checkout'

  resources :products, only: [:show, :destroy, :update]
  resources :shelves, only: [:show, :destroy, :update]
  resource :cart, only: [:show]
  resources :order_items, only: [:create, :update, :destroy]

  get "admin" => "admin#index"
  get "admin_products" => "admin#admin_products"
  get "admin_edit_shelf" => "admin#edit_shelf"

  scope '/admin' do
    resources :products, only: [:create, :edit, :destroy, :new, :index]
    resources :shelves, only: [:create, :edit, :destroy, :new, :index]
    resources :attachments
    resources :users
    resources :zip_code_validations
  end


  resources :locations
  scope do
   get "locations_landing" => "locations#landing"
   get "locations_invalid" => "locations#invalid"
  end

  get "user_location" => "locations#user_location"


  devise_for :users, :controllers => {:registrations => 'registrations'}

  # devise_for :users, controllers: { sessions: "users/sessions" }




  root to: 'landing#hsnow_index'

    get "commerce/store"
    get "search_products" => "commerce#search_products" 
    get "search_shelves" => "commerce#search_shelves"

end

Serving.rb

class Serving < ActiveRecord::Base
    has_many :products
    belongs_to :shelf
end

Shelf.rb

class Shelf < ActiveRecord::Base
  belongs_to :brand
  has_many :attachments, dependent: :destroy
  has_many :products
  has_many :servings, dependent: :destroy
  has_and_belongs_to_many :categories
  belongs_to :category
  has_attached_file :main_image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/product/factss/no-image-available"
  validates_attachment :main_image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }  

  has_attached_file :facts, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/product/factss/no-image-available"
  validates_attachment :facts, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } 

#array of picture attachments    
    def attachments_array=(array)
       array.each do |file|
           attachments.build(:attachment => file)
       end
    end  
# Search for shelves by name        
    def self.search_by_shelf_name(search)
        where("LOWER(name) LIKE ?", "%#{search.downcase}%") 
    end  
end

Product.rb

class Product < ActiveRecord::Base
  has_many :order_items
  has_many :attachments, dependent: :destroy
  has_many :subproducts
  has_and_belongs_to_many :categories
  belongs_to :brand
  belongs_to :shelf
  belongs_to :serving
  has_attached_file :main_image, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/product/factss/no-image-available"
  validates_attachment :main_image, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }  

  has_attached_file :facts, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/product/factss/no-image-available"
  validates_attachment :facts, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }    

  default_scope { where(active: true) }

#array of picture attachments  
    def attachments_array=(array)
       array.each do |file|
           attachments.build(:attachment => file)
       end
    end 
# Search for products by name    
    def self.search_by_product_name(search)
        where("LOWER(name) LIKE ?", "%#{search.downcase}%") 
    end

end

Shelves Controller

  def show
    @order_item = current_order.order_items.new

    @serving = Serving.new
    @product = Product.find(params[:id])    
    @shelf = Shelf.find(params[:id])
    @servings = @shelf.servings 
  end

shelves/show.html.erb

<!-- Serving groups and Products in servings -->
<!-- ################################ -->
<!-- ################################ -->

        <% if @shelf.multiproduct? %>    
            <% @shelf.servings.each do |serving| %>
            <div class="row">
                 <div class="col-xs-8 col-md-4 text-navy">
                    <h3><%= serving.serving_size %></h3>
                </div>
                 <div class="col-xs-4 col-md-4 text-right">
                    <h3><strong><%= serving.price %></strong></h3>
                </div>                    
            </div>
            <div class="row">
                <div class="col-md-12">
                <% if current_user.role_id == 1 %>
                    <%= link_to "edit", edit_serving_path(serving) %> |
                    <%= link_to "delete", serving, method: :delete, data: { confirm: 'Are you sure?' } %>
                <% end %>
                </div>                            
            </div>
            <div class="row">
                 <div class="col-xs-12 col-md-8 text-left">
                    <%= pluralize serving.products.count,'Flavor' %>
                     <hr style="margin-top: 5px;">   
                </div>
            </div>
        <% serving.products.each do |product| %>
            <div class="row">
                <div class="col-xs-12 col-md-8">
                 <div class="col-xs-6 col-md-4" style="<%= "padding-top: 0.6em;" if product.flavor.split.size <= 2 %> >"
                    <p><strong><%= product.flavor %></strong></p> 
                </div>

                <div class="col-xs-2 col-md-4 " style="<%= "padding-top: 0.6em;" if product.flavor.split.size <= 2 %> >" >

<!-- Link to open modal with supplement facts picture-->
<!-- ################################ -->

                    <i class="fa fa-file-image-o" aria-hidden="true"></i> <%= link_to " Supplement Facts", "#pictureModal", "data-toggle" => "modal", :id => @product, class:""  %>

<!-- ################################ -->
                </div>

                 <div class="col-xs-4 col-md-4 text-right">
                    <%= form_for @order_item, remote: true do |f| %>
                        <%= f.hidden_field :quantity, value: 1, class: "form-control", min: 1 %>
                        <%= f.hidden_field :product_id, value: product.id %>
                        <%= f.submit "ADD", class: "btn btn-secondary" %>
                    <% end %>        
                </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                <% if current_user.role_id == 1 %>
                    <%= link_to "edit", edit_product_path(product) %> |
                    <%= link_to "delete", product, method: :delete, data: { confirm: 'Are you sure?' } %>
                <% end %>
                </div>                            
            </div>
            <br>
        <% end %> <!-- end product block -->
                <hr></hr>
            <% end %>   <!-- end servings block --> 
        <% end %> <!-- end conditional checking if shelf multi product is false -->  


<!-- PRODUCT FACTS MODAL  -->
<!-- ################################ -->
<!-- ################################ -->

<div class="modal inmodal" id="pictureModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content animated bounceInRight">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            </div>
            <div class="modal-body">
                <div class="row">
                    <div class="col-xs-12">
                        <%= image_tag @product.facts.url if @product.present? %>
                        <%= @product.id  if @product.present? %>
                    </div>
                </div>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

Upvotes: 1

Views: 264

Answers (1)

Vitor Mateus
Vitor Mateus

Reputation: 145

Ok, let s start with your link_to:

<% serving.products.each do |product| %>
  ...
    <%= link_to " Supplement Facts", "#pictureModal", "data-toggle" => "modal", :id => @product, class:""  %>
  ...
<% end %>

As you can see from bootstrap docs(http://getbootstrap.com/javascript/#modals-examples) the modal id in your case is "#pictureModal", so you don t need to use :id => @product in your link_to. But, you can have more than 1 product so you need to generate 1 modal for each product. You need to use a unique id in all your modals(ex: "#pictureModal_#{product.id}") so you can do this in your link_to:

<% serving.products.each do |product| %>
  ...
   <%= link_to " Supplement Facts", "#pictureModal_#{product.id}", "data-toggle" => "modal", class:""  %>
  ...
<% end %>

Now looking at your modal

You need to iterate all your products and generate the respective modals like this:

<% @shelf.servings.each do |serving| %>
  <% serving.products.each do |product| %>

<div class="modal inmodal" id="pictureModal_<%= product.id %>" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
    <div class="modal-content animated bounceInRight">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
        </div>
        <div class="modal-body">
            <div class="row">
                <div class="col-xs-12">
                    <%= image_tag product.facts.url if product.present? %>
                    <%= product.id  if product.present? %>
                </div>
            </div>

        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
        </div>
    </div>
</div>

  <% end %>
<% end %>

Hope this helps

Upvotes: 1

Related Questions