Render show page in Bootstrap modal from index - ruby-on-rails

In Rails 4 I'm trying to render show.html.erb on my index page inside a bootstrap modal.
index.html.erb:
<% #links.each do |item| %>
<h4><%= link_to (item.title), '#myModal', 'data-toggle' => 'modal' %>
Submitted <%= time_ago_in_words(item.created_at) %> ago
</h4>
<div class="modal fade" id="myModal" tabindex="-1" role="document" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<%= render :partial => 'show_modal', :locals => { :item => item } %>
</div>
</div>
</div>
</div>
</div>
<% end %>
_show_modal.html.erb:
<div class="col-md-offset-2 col-md-4" id="telegraph">
<h1><%= item.title %></h1>
<p><%= item.content %></p>
</div>
Currently, the modal is showing nicely, but no matter which link I click, the modal only ever displays the data for the very first link inside #links
Any help would be great.

You need to name each modal differently.
Try setting each modals id to myModal-id where id is the id of the item
For example:
<h4><%= link_to (item.title), "#myModal-#{item.id}", 'data-toggle' => 'modal' %>
Submitted <%= time_ago_in_words(item.created_at) %> ago
</h4>
and
<div class="modal fade" id="myModal-<%= item.id %>" tabindex="-1" role="document" aria-labelledby="myModalLabel">

Related

How to create and edit a book review in bootstrap modal

I was able to create reviews to book in the proper way. But I'm unable to create and edit reviews in modals.
I was able load the new review form in the modal but it only loads if a book already has reviews. If the books has no reviews then modal button won't work.
I get this error which I don't fully understand
First argument in form cannot contain nil or be empty
pointing to the edit form line
<%= form_for([#book, #review], remote: true) do |f| %>
I've tried to implement the modals for the book model which work well but the reviews doesn't.
books_controller.rb
def show
#reviews = #book.reviews
end
books/show.html.erb
<section id="reviews-section">
<div class="review-form">
<% if user_signed_in? %>
<!-- Button trigger modal -->
<button type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#mynewreview">
Write your review
</button>
<% else %>
<p>You need to <%= link_to 'sign in', new_user_session_path, class: "btn btn-warning btn-sm" %> before writing a review buddy :)</p>
<br>
<% end %>
</div>
<br>
<div id="reviews_panel">
<%= render #reviews %>
</div>
</section>
reviews/_review.html.erb
<% if user_signed_in? %>
<% if review.user_id == current_user.id %>
<div class="btn-group mr-2" role="group">
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#editreview_<%= review.id %>">Edit Modal</button>
<%= link_to 'Delete Review', book_review_path(review.book, review), class: "btn btn-sm btn-danger", method: :delete, remote: true, data: { confirm: "Are you sure?" } %>
</div>
<% end %>
<% end %>
<%= render 'reviews/widgets/new_review_modal' %>
<%= render 'reviews/widgets/edit_review_modal' %>
reviews/widgets/_new_review_modal
<%= form_for([#book, #book.reviews.build], remote: true) do |f| %>
<!-- Modal -->
<div class="modal fade" id="mynewreview" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Review</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="rating-form">
<label>Rating:</label>
</div>
<div class="field">
<p><%= f.text_area :comment, placeholder: 'Write comment...', class: "form-control review-text-field" %></p>
</div>
</div>
<div class="modal-footer">
<div class="actions">
<%= f.button "Submit Review", class: "btn btn-success btn-sm", data: {disable_with: "<i class='fa fa-spinner fa-spin'></i> Submitting Review..."} %>
</div>
</div>
</div>
</div>
</div>
<% end %>
<script>
$('#rating-form').raty({
path: '/assets/',
scoreName: 'review[rating]'
});
</script>
reviews/widgets/_edit_review_modal
<%= form_for([#book, #review], remote: true) do |f| %>
<!-- Modal -->
<div class="modal fade" id="editreview_<%= review.id %>" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit your review</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="rating-form">
<label>Rating:</label>
</div>
<div class="field">
<p><%= f.text_area :comment, placeholder: 'Write comment...', class: "form-control review-text-field" %></p>
</div>
</div>
<div class="modal-footer">
<div class="actions">
<%= f.button "Submit Review", class: "btn btn-success btn-sm", data: {disable_with: "<i class='fa fa-spinner fa-spin'></i> Submitting Review..."} %>
</div>
</div>
</div>
</div>
</div>
<% end %>
<script>
$('#rating-form').raty({
path: '/assets/',
scoreName: 'review[rating]',
score: <%= #review.rating %>
});
</script>
in reviews_controller > edit action you must find #book and #review as well.
def edit
#review = #book.reviews.find(params[:id])
end
It looks like you are showing all reviews in show page of book. and you want to do edit with ajax. In that case you must be using some kind of loop and you must be assigning a single review object to any variable. you need to use that variable in form object
<%= #reviewes.each do |review| %>
<% form_for [#book, review] ... do %>
...
<% end %>
<% end %>

Render HTML inside block - Ruby on Rails

I'm trying to render a HTML with a partial inside of a block but the only thing that renders are the last 4 closing </div> elements.
Here is my code:
<%= new_item_modal do |i| %>
<div class="modal fade" id="newItemModal" tabindex="-1" role="dialog" aria-labelledby="newItemModal" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">New Item</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="new-item" style="overflow:scroll;height:500px;">
<%= render partial: "/items/form", locals: { remote: true, item: #item, categories: #categories }%>
</div>
</div>
</div>
</div>
<% end %>
And my new_item_modal function:
def new_item_modal(&block)
if current_location.present? && can_access("create", "items")
#item = Item.new
#categories = current_location.categories
block.call
end
end
Your first line should read <%= new_item_modal do |item, categories| %> and your new_modal_item method should have block.call(#item, #categories). Make sure you rename the variables passed to the partial (for example, from #item to item).

Uploading the profile pic using modal

I have created the rails app that has a gallery. Now i am willing to have gallery cover photo. I want to update the cover photo using modal. to upload the photo i am using paperclip.
This is my model:
class Gallery < ActiveRecord::Base
has_attached_file :cover_url, :styles => { :small => "108x76" }
validates_attachment_content_type :cover_url, :content_type => ['image/jpeg', 'image/jpg', 'image/png']
end
This is my controller:
def update
puts params
respond_to do |format|
if #gallery.update(gallery_params)
format.html { redirect_to galleries_galleryhome_path(id: params[:id]), notice: 'Gallery was successfully updated.' }
format.json { render :show, status: :ok, location: #gallery }
else
format.html { render :edit }
format.json { render json: #gallery.errors, status: :unprocessable_entity }
end
end
end
def gallery_params
params.require(:gallery).permit(:name, :shoot_date, :release_date, :expiration_date, :archive,:gallery_layout_id, :contact_id,:status, :cover_url).merge(brand_id: current_brand.id,user_id: current_user.id)
end
This is my View:
<div class="cover-photo default pull-left">
<% if #find_gallery.cover_url.present?%>
<%=image_tag #find_gallery.cover_url.url(:small)%>
<%end%>
</div>
<div class="icon-cta" data-toggle="modal" data-target="cover_modal">
<% if #find_gallery.cover_url.present? %>
<%=link_to "Add<br>Cover".html_safe, "#profile-change" ,'data-toggle': "modal", class: "change-cover"%>
<% else %>
<%=link_to "Add<br>Cover".html_safe, "#album-title-popup" ,'data-toggle': "modal", class: "change-cover"%>
<% end %>
</div>
<!-- Album Cover Modal -->
<div class="modal fade" id="profile-change" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Album Cover</h4>
</div>
<%= form_for #gallery_cover,html: {multipart: true}, url: {controller: "galleries", action: "update", id: params[:id]}, method: :patch do |f| %>
<%= label_tag "photo"%>
<div class="modal-body">
<%= f.hidden_field :cover_url,id: "hidden_cover_url"%>
<div class="empty stack">
<%= image_tag #find_gallery.cover_url.url,size: "355x237",id: "changecover"%>
</div>
</div>
<div class="modal-footer pull-left">
<button data-toggle="modal" data-target="#album-title-popup" data-dismiss="modal" type="button" class="btn btn-default"><span class="fa fa-trash set-stack"></span>Remove</button>
<button data-toggle="modal" data-target="#album-add-cover" data-dismiss="modal" type="button" class="btn btn-default"><span class="fa fa-picture-o set-stack"></span>Change</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<%= f.submit "Save"%>
</div>
<%end%>
</div>
</div>
</div>
<!-- Add Album Photo Modal -->
<div class="modal fade" id="album-add-cover" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Add Cover</h4>
</div>
<div class="modal-body">
<%= form_for #gallery_cover,html: {id: "Cover-Upload"}, url: {controller: "galleries", action: "update", id: params[:id]}, method: :patch do |f| %>
<ul class="source-links">
<li class="js-cover-flow-upload">
<span class="btn btn-file">
<p>Upload From Computer</p>
<%=f.file_field :cover_url, id: "Computer-Upload", onchange: "document.getElementById('hidden_cover_url').val = window.URL.createObjectURL(this.files[0])" %>
<%= f.hidden_field :id, value: params[:id]%>
</span>
<span class="fa fa-caret-right pull-right"></span>
</li>
<li class="js-cover-flow-random">
<span class="btn btn-file">
<p>Choose From Gallery</p>
</span>
<span class="fa fa-caret-right pull-right"></span>
</li>
</ul>
<%= image_tag "image",id: "sample"%>
<%= f.submit "Save", style: "display:none;",id: "Pc"%>
<% end %>
</div>
</div>
As you can see above there are two modals. On clicking of Add Cover Link #profile-change modal will open. This modal is having the button Change. On clicking this button it will open second modal i.e. #album-add-cover modal. On the second modal i can select the image to upload. As soon as i select the photo i should be redirected to first modal with the value selected on second modal so that i can update the cover photo of gallery on submitting the form on first modal.
This is the script that i have wrote:
function updatecover(input){
if (input.files) {
var reader = new FileReader();
reader.readAsDataURL(input.files[0]);
reader.onload = function (e) {
$("#changecover").attr('src', e.target.result);
}
}
}
$("#Computer-Upload").change(function(){
updatecover(this);
alert($(this).val());
$("#changecover").attr("src",$(this).val());
// $("#Pc").click();
});
The above script is displaying the selected file on the first modal but on saving the photo it gives me error of:
Paperclip::AdapterRegistry::NoHandlerError in GalleriesController#update
It is updating the profile pic without loading the first modal.
Please any one can help me? Thank you in advance.

Pass Variable from View to Model outside of view

How can I pass a variable to my model which is outside the view? The problem is, I had to move the model to application.html.erb because there were z-index conflicts with having the modal code within the products/index.html.erb view.
For example, I'd like to pass the <%= product.id %> variable to the modal popup.
products/index.html.erb
<% products.each do |product| %>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#productDetails" productId="<%= product.id %>">
Launch <%= product.id %>
</button>
<% end %>
layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<%= stylesheet_link_tag 'application' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="page-wrapper">
<%= render 'layouts/header' %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
<!-- Modal -->
<div class="modal fade" id="productDetails" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body product-content">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</body>
</html>
Attempts
I've tried adding javascript to pass the variable, but nothing showed up:
<script>
$('#productDetails').on('show.bs.modal', function(e) {
var $modal = $(this),
productId = e.relatedTarget.productId;
$.ajax({
cache: false,
type: 'POST',
url: 'backend.php',
data: 'EID=' + productId,
success: function(data) {
$modal.find('.product-content').html(productId);
}
});
})
</script>
I've also tried adding a partial within products/index.html, but the modal cannot be called from within products/index.html.erb because of the z-index conflicts.
I don't know what the php part is all about. However, ignoring that part and assuming no one would do something like that, here is how you would handle this in rails:
make the button a remote method call with link_to(something like this):
<% products.each do |product| %>
<%= link_to 'Launch', product, { data: { toggle: 'modal', target: '#productDetails' }, class: 'btn btn-primary btn-lg', remote: true } %>
<% end %>
create js.erb file for show called products/show.js.erb (this assumes #product is defined in controller):
$('#productDetails').html("<%= j render partial: 'show', locals: { product: #product } %>");
move everything from under modal div out into products/_show.html.erb partial:
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body product-content">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>

Gmaps4rails : Using Bootstrap modal with gmaps4rails infowindows

I have managed to apply gmaps4rails in my application
FIRST METHOD
I have a map action like this:
def map
#family = Family.all.to_gmaps4rails do |family,marker|
marker.infowindow render_to_string(:partial => "/layouts/info", :locals => { :family => family})
end
end
in my _info.html.erb:
<h5><%=family.location%></h5>
<%=link_to "View Details","#myModal",class: "btn btn-success",data: {toggle: "modal"} %>
<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" style="color:#9D5641;margin-top:10px;">Family Details</h3>
<h5>Family ID : <%=family.famid%></h5>
</div>
<div class="modal-body">
<%= family.persons.count %>
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Mobile No.</th>
<th>Photo</th>
</tr>
<% family.persons.each do |person| %>
<tr>
<td><%=person.name%></td>
<td><%=person.mobnum%></td>
<td><%=person.photo%></td>
</tr>
<%end%>
</table>
</div>
<div class="modal-footer">
<h5><%=link_to "Veiw Full Details", {controller: :managedb ,action: :details, famid: family.famid} %></h5>
</div>
</div>
The bootstrap's modal is rendered fine but with a glitch. It looks like this:
The modal is supposed to be on top of the grey color layer.
I guess this is happening beacause I'm rendering the modal in the infowindow partial. That is why it's css properties are that of the infowindow. How do I make it work as normal modal.
I can remove the background-color which we get once the modal is activated by adding:
.modal-backdrop {background: none;}
to my css file.
But the **modal is not clickable. I cannot click on the links in it and so on.How to fix this?
ALTERNATE METHOD I TRIED
map action
def map
#family = Family.all.to_gmaps4rails do |family,marker|
#fam=family
marker.infowindow render_to_string(:partial => "/layouts/map", :locals => { :family => family})
end
end
_info.html.erb
<h5><%=family.location%></h5>
<%=link_to "View Details","#myModal",class: "btn btn-success",data: {toggle: "modal"} %>
map.html.erb
<div class="container">
<div class="row">
<%= gmaps4rails(#family) %>
<!-- Modal -->
<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" style="color:#9D5641;margin-top:10px;">Family Details</h3>
<h5>Family ID : <%=#fam.famid%></h5>
</div>
<div class="modal-body">
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Mobile No.</th>
<th>Photo</th>
</tr>
<% #fam.persons.each do |person| %>
<tr>
<td><%=person.name%></td>
<td><%=person.mobnum%></td>
<td><%=person.photo%></td>
</tr>
<%end%>
</table>
</div>
<div class="modal-footer">
<h5><%=link_to "Veiw Full Details", {controller: :managedb ,action: :details, famid: #fam.famid} %></h5>
</div>
</div>
</div>
Now the modal renders properly but it only has the last family in #fam variable.
How can I pass the family id as parameter from the modal's link?
Finally I did it with the first method.
Altered few css properties of modal
.modal-backdrop {background: none;z-index:-1;}
and
#myModal {z-index:1;}
Now all the elements in the modal are clickable like a normal bootstrap-modal.

Resources