Bootstrap Accordion collapse with Ruby hash - ruby-on-rails

Collapse is only working on the first button, and I know it's because only the first div id is being set for all buttons. How do I iterate and make new div id's for each element when using hash.each?
Here's my erb:
<% #contacts.each do |category, hash| %>
<div class="panel-group" id=accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><%= category %></h3>
</div>
<div class="panel-body">
<ul class="list-group">
<% hash.each do |contact| %>
<li class="list-group-item" style="border: none">
<button type="button" class="btn btn-info" data-toggle="collapse" data-parent="#accordion" data-target="#demo"><%= contact['name'] %></button>
<div id="demo" class="panel-collapse collapse">
<div class="panel-body"><%= contact['email'] %></br><%= contact['ext'] %>
</div>
</div>
</li>
<% end %>
</ul>
</div>
</div>
</div>
<% end %>
Here's the corresponding code from my .rb:
get '/contact' do
contact = Contacts.new
#contacts = contact.getContacts
#contacts.each { |s| puts "get /contact found contact #{s.last.first['name']}" }
erb :contact

try
<% hash.each_with_index do |contact, index| %>
<li class="list-group-item" style="border: none">
<button type="button" class="btn btn-info" data-toggle="collapse" data-parent="#accordion" data-target="#collapse<%= index %>"><%= contact['name'] %></button>
<div id="collapse<%= index %>" class="panel-collapse collapse">
<div class="panel-body"><%= contact['email'] %></br><%= contact['ext'] %>
</div>
</div>
</li>
<% end %>

Related

Trouble with displaying information with Bootstrap Cards (Decks)

Currently, I have my data displayed like this (and it works fine)
<div class="container-fluid">
<% #entries.reverse.each do |entry| %>
<div class="card">
<div class="card-block">
<p class="card-title"><b><%= entry.title %></b></p>
<p class="card-text"><%= entry.link %></p>
</div>
</div>
<% end %>
</div>
Trying to change the layout to display the data in series of three cards like here: https://v4-alpha.getbootstrap.com/components/card/#card-decks
This is how I rewrote it:
<div class="card-deck">
<% #entries.each_slice(3) do |entry| %>
<div class="card">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-block">
<h4 class="card-title"><%= entry.title %></h4>
<p class="card-text"><%= entry.link %></p>
</div>
<div class="card-footer">
<small class="text-muted">Last updated 3 mins ago</small>
</div>
<% end %>
</div>
<% #entries.each_slice(3) do |entry| %>
<div class="card">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-block">
<h4 class="card-title"><%= entry.title %></h4>
<p class="card-text"><%= entry.link %></p>
</div>
<div class="card-footer">
<small class="text-muted">Last updated 3 mins ago</small>
</div>
<% end %>
</div>
<% #entries.each_slice(3) do |entry| %>
<div class="card">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-block">
<h4 class="card-title"><%= entry.title %></h4>
<p class="card-text"><%= entry.link %></p>
</div>
<div class="card-footer">
<small class="text-muted">Last updated 3 mins ago</small>
</div>
<% end %>
</div>
</div>
This is the error I receive when I try to display the page now:
NoMethodError in Entries#index
undefined method `title' for #<Array:0x007fa6dab11a10>
Why am I receiving this error?
Thank you for your help. Please let me know if this question needs further clarification and/or more information.
Further information:
require 'open-uri'
module RedditScrapper
def self.scrape
doc = Nokogiri::HTML(open("https://www.reddit.com/"))
entries = doc.css('.entry')
entries.each do |entry|
title = entry.css('p.title > a').text
link = entry.css('p.title > a')[0]['href']
category = entry.css('p.tagline > a')[0]['href']
Entry.create!(title: title, link: link, category: category )
end
end
end
<div class="card-columns">
<% #entries.reverse.each do |entry| %>
<div class="card">
<div class="card-block">
<p class="card-title"><b><%= entry.title %></b></p>
<p class="card-text"><%= entry.link %></p>
</div>
</div>
<% end %>
</div>
Scss:
.card-columns {
#include media-breakpoint-only(lg) {
column-count: 3;
}
#include media-breakpoint-only(xl) {
column-count: 3;
}
}
each_slice returns an array, and trying to access title or link on an array will return this error. To access the data, you would have to grab by index in the sliced arrays.

Bootstrap/Rails - String Interpolation inside accordion

I've been struggling with string interpolation inside an HTML accordion. It's more a logic issue that I can't seem to figure out (fairly new to rails). The problem I have is that while the layout is fine, when I click to collapse any of the 3 collapsible panels they all collapse. (Because I only have 1 #collapse).
Outermost ERB
<div class="container-fluid">
<div class="row">
<div class="col-md-2 col-sm-3">
<h2>Categorias</h2>
<div class="panel-group" id="accordion">
<%= render partial: "categories/catalog", collection: #categories, as: :c %>
</div>
</div>
_catalog Partial
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse1">
<%= c.name %>
<span class="badge">4</span>
</a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
<% c.subcategories.each do |sc| %>
<div class="panel-body">
<a href="#">
<%= sc.name %>
</a>
</div>
<% end %>
</div>
</div>
Controller
def catalogo
#categories = Category.where("parent_id IS NULL")
unless params[:cat_id].blank?
#products = Product.where(category_id: params[:cat_id]).paginate(:page => params[:page], :per_page => 50)
else
#products = Product.all.paginate(:page => params[:page], :per_page => 50)
end
#categorieswparent = Category.where("parent_id IS NOT NULL")
end
Your IDs need to be unique. Instead of hard-coding id="collapse1", use the ID of the record:
id="collapse<%= sc.id %>"
Perform the same interpolation for the href of the <a> tag responsible for collapsing and expanding the accordion.
Use category id id="#collapse<%= c.id %>" to interpolate with element id in _catalog Partial.
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<%= c.id %>">
<%= c.name %>
<span class="badge">4</span>
</a>
</h4>
</div>
<div id="collapse<%= c.id %>" class="panel-collapse collapse in">
<% c.subcategories.each do |sc| %>
<div class="panel-body">
<a href="#">
<%= sc.name %>
</a>
</div>
<% end %>
</div>
</div>

Loop through bootstrap accordion rails issue

I have an issue to loop through profile field and values. Bootstrap collapse not working.
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<% #profile.each do |field, value| %>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="collapse_#{field.id}" aria-expanded="false" aria-controls="collapseOne">
<%= field%>
</a>
</h4>
</div>
<div id="collapse_#{field.id}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<%= value %>
</div>
</div>
</div>
<% end %>
</div>
Please check this:
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<% #profile.each do |field, value| %>
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="collapse_<%=field.id%>" aria-expanded="false" aria-controls="collapseOne">
<%= field%>
</a>
</h4>
</div>
<div id="collapse_<%=field.id%>" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<%= value %>
</div>
</div>
</div>
<% end %>
</div>
You can use <%= field.id%> insted of #{field.id}.

To iterate by block in rails

I used Ruby on Rails and I have created more of 40 hiraganas flashcards. In my index view, I do an iteration like this.
Some of Hiraganas cards have different I want to create different columns which host different color cards.
I want to iterate on letter A = green, E = red, I = Pink, etc
enter image description here
I only do that
<% #hiraganas.each do |hiragana| %>
<li>
<%= render 'allhiraganas', hiragana: hiragana %>
</li>
<% end %>
Do you know how to select only few elements to iterate. I see some tutos but I try .select
here is the render flashcards code
<div class="row">
<ul class="list-inline text-center card-frame">
<li>
<div class="card">
<div class="front">
<% if current_user.try(:admin?) %>
<%= link_to hiragana_path(hiragana), class:'trash-hiragana', data: { confirm: 'Are you sure?' }, method: :delete do %>
<%= image_tag("delete-btn.png") %>
<% end %>
<% end %>
<!-- PARAMETRER LE RESPONSIVE BOOTSTRAP -->
<!-- <div class="col-sm- col-xs-4 col-md-3"> -->
<span class="card-question popover-word" data-content="<h4 class='text-center letter-uppercase'><%= hiragana.bigletter.upcase %></h4><p class='text-center'><b><%= hiragana.midletter %></b> comme dans <b><%= hiragana.transcription %></b></p>">
<i class="fa fa-eye fa-lg"></i>
</span>
<!-- son de l'hiragana -->
<span class="audioclick popover-word" data-content="<p class='text-center'><b>le son arrive prochainement !</b></p>">
<i class="fa fa-volume-up fa-lg"></i>
</span>
<!-- image mnémotechnique -->
<span class="idea popover-word" data-content="<p class='text-center'><b>l'image est bientôt prête !</b><%= hiragana.upload %></p>">
<i class="fa fa-lightbulb-o fa-lg"></i>
</span>
<!-- <div class="prononciation">
<i class="fa fa-comment"></i>
</div> -->
<div class="card-hiragana hiragana-<%=hiragana.bigletter.downcase.last%>">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-katakana">
<p><%= hiragana.ideo2 %></p>
</div>
<div id="favorite_<%=hiragana.id%>">
<%= render 'favs/favorites', hiragana: hiragana %>
</div>
</div>
<div class="back">
<div class="col-sm-3 col-xs-4 col-md-3 containerbackcards-<%=hiragana.bigletter.downcase.last%>">
<div class="backcard-hiragana">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-bigletter">
<h4><%= hiragana.bigletter.upcase %></h4>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
Thank you for your answer
which ones do you want? what's the logic for which you'd like to choose? If you simply wanted the first 3 you could say
#hiriganas = Hirigana.first(3)
if you have a condition you'd like to choose them by select is a good choice.
#hiriganas = #hiriganas.select{ |hir| # criteria for selection }
It depends: If you have the color saved in the hiragana model, then you just need to:
greenhiriganas = Hirigana.where(color: "green")
If you just know in your head, which letters have which colors, then for each section you need to write an array containing all the names
#if for example A, Ka and Shi are green
green = [:a, :ka, :shi]
#then select via include?-method
greenhiriganas = Hirigana.select{ |hiri| green.include?(hiri.name) }

Ruby on Rails / Bootstrap : dynamic datas in a modal

I am beginning with Ruby on Rails and have a question about the use of the bootstrap's modal.
So my problem is that i have a table and for each row of this table i make a button to display with the modal some other informations about dependent classes but it displays the right informations only for the first row and the same ones for all other rows. I want to make it dynamic and corresponding to the object it deals with.
<table class="table table-hover table-condensed">
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Priority</th>
<th>State</th>
<th></th>
<th></th>
</tr>
<% #user_stories.each do |user_story| %>
<tr>
<td><%= user_story.id %></td>
<td><%= user_story.name %></td>
<td><%= user_story.description %></td>
<td><%= user_story.priority %></td>
<td><%= user_story.state %></td>
<td>
<div class="btn-group">
<a class="btn btn-primary">Options</a>
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#"><span class="caret"></span></a>
<ul class="dropdown-menu">
<li><%= link_to 'Show', user_story %></li>
<li class="divider"></li>
<li><%= link_to 'Edit', edit_user_story_path(user_story) %></li>
<li class="divider"></li>
<li> <%= link_to 'Destroy', user_story, :confirm => 'Are you sure?', :method => :delete %></li>
</ul>
</div>
</td>
<td> Global View</td>
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Golbal view : <%= user_story.name %></h3>
</div>
<div class="modal-body">
<% us = user_story.functionalities %>
<% us.each do |f| %>
<span class="label label-info"><%= f.name %></span>
<% t = f.tasks%>
<br/>
<% t.each do |y| %>
<%= y.name %>
<% u = User.where(:id => y.user_id) %>
<%= u.collect {|p| ": #{p.first_name} #{p.last_name}"} %>
<br/>
<% end %>
<br/>
<% end %>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
</tr>
<% end %>
</table>
Any ideas how to fix it ?
Routes:
Backlog::Application.routes.draw do
resources :functionalities
resources :user_stories
resources :users
resources :tasks
end
You have added the modal to every row.
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
But here for the every row the id of the modal is same. So you are getting the same dialog for every row. You need to make dynamic id for for the modals and wherever you are using id in the modal div.
Global View
<div id="myModal<%= user_story.id%>" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel<%= user_story.id%>">Golbal view : <%= user_story.name %></h3>
</div>
<div class="modal-body">
<% us = user_story.functionalities %>
<% us.each do |f| %>
<span class="label label-info"><%= f.name %></span>
<% t = f.tasks%>
<br/>
<% t.each do |y| %>
<%= y.name %>
<% u = User.where(:id => y.user_id) %>
<%= u.collect {|p| ": #{p.first_name} #{p.last_name}"} %>
<br/>
<% end %>
<br/>
<% end %>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>

Resources