Uploading the profile pic using modal - ruby-on-rails

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.

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 %>

How to pass data-attribute from a button to it's corresponding modal

In my rails app, I have a view with some images.
<div class="item-images">
<div class="row">
<% #user_item.user_item_images.each_with_index do |image, index| %>
<% if (index + 1) % 5 == 0 %>
</div><div class="row">
<% end %>
<div class="image-container">
<a class="fancybox" rel="group" href="<%= image.picture.large.url %>"><img class="img-thumbnail img-circle" src="<%= image.picture.thumb.url %>" alt="" /></a>
<% if #user.eql?(current_user) && #user_item.primary_image_id != image.id %>
<button class="btn btn-xs btn-danger delete-image" data-id="<%= image.id %>" data-toggle="modal" data-target="#delete-image-modal">
<i class="fa fa-trash-o fa-lg"></i>
</button>
<% if #user_item.primary_image_id != image.id %>
<button class="btn btn-xs btn-info make-primary" data-id="<%= image.id %>" data-toggle="modal" data-target="#make-primary-modal">
<i class="fa fa-thumb-tack fa-lg"></i>
</button>
<% end %>
<% end %>
</div>
<% end %>
As you can see I have two buttons associated with each image. The corresponding modals:
<!-- Delete Image Modal -->
<div id="delete-image-modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete-image" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 id="delete-image">Are you sure you want to delete this image?</h4>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Cancel</button>
<%= link_to 'Delete', '', method: :delete, :class => 'btn btn-danger' %>
</div>
</div>
</div>
</div>
<!-- Make Primary Modal -->
<div id="make-primary-modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="make-primary" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 id="make-primary">Are you sure you want to make this the primary image for your item?</h4>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Cancel</button>
<%= link_to 'Make Primary', make_primary_path(????), :class => 'btn btn-info' %>
</div>
</div>
</div>
</div>
The make_primary_path brings us to a controller action which changes an attribute of the modal's associated image:
def make_primary
#user_item = UserItemImage.find(params[:user_item_image_id]).user_item
#user_item.update_attributes(primary_image_id: params[:id])
flash[:notice] = "primary image set"
redirect_to :back
end
The route for this action:
get 'user_item_images/:user_item_image_id/make_primary', to: 'user_item_images#make_primary', as: :make_primary
My problem is generating the link in the "Make Primary Modal". How do I get the data-id from the button and use that in the link_to helper?
One option would be to use ajax and tie it to a click event to that link. Something like:
$('.btn-info').on('click', function(e){
e.preventDefault()
var imageId = $('make-primary').data('id');
$.ajax({
type: 'GET', // either
url: '/user_items/make_primary',
data: {
image_id: imageId
}
}).done(function(ajax_success){
// use jquery to update whatever you need to on the page
// close modal
})
})
You can also use rails like:
<%= button_to '>Are you sure you want to make this the primary image for your item?', make_primary_path(image_id: image.id), :remote=>true, :method=>:post %>
I ended up doing this:
$('.make-primary').on('click', function() {
$('#make-primary-modal').find('a').attr('href', '/user_item_images/' + $(this).data('id') + '/make_primary');
});
and changing the link_to helper:
<%= link_to 'Make Primary', '', method: :post, :class => 'btn btn-info' %>

Render show page in Bootstrap modal from index

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">

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>

Rails+Bootstrap Modal renders but doesn't show

I can get the modal to render in the DOM, but I can't get it to show, I get it to flash for an instant, but it doesn't stay. Here is the relevant code.
tasks_controller.rb
def edit
#task = Task.find(params[:id])
respond_to do |format|
format.html
format.js
end
end
edit.js.erb
$(document).ready( function() {
$("#edit_task_modal").html("<%= escape_javascript(render 'tasks/edit_task_modal') %>");
$("#edit_task_modal").modal('show');
});
_edit_task_modal.html.erb
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button id="close_edit_task_modal" type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="edit_task_modal_label">Edit Task</h4>
</div>
<%= form_for(:task, url: {action: 'update', id: #task.id},:html => {:class => 'form-horizontal'}) do |f| %>
<div class="modal-body">
<%= render(partial: 'form', locals: {f: f}) %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<%= f.submit 'Save Changes', class: 'btn btn-primary' %>
</div>
<% end %>
</div>
</div>
_task_div.html.erb
<div class="task well">
<a>Title: <%= "#{task.title}" %></a><br/>
Description: <%= "#{task.description}" %> <br>
Status: <%= "#{task.status}" %> <br>
Due Date: <%= "#{task.due_date}" %> <br>
Completed Date: <%= "#{task.completed_date}" %> <br>
<div style='text-align:right;'>
<%= link_to 'Edit', {controller: 'tasks', action: 'edit', id: task.id}, {:remote => true, 'data-toggle' => "modal", 'data-target' => '#edit_task_modal'} %>
</div>
</div>
show.html.erb
<div id="edit_task_modal" class="modal fade" role="dialog" aria-labelledby="edit_task_modal_label" aria-hidden="true" tabindex="-1"></div>
EDIT: Added modal code
Turns out all I had to do was remove 'data-toggle'='modal' from the link to the modal. The javascript was showing it, then the html would toggle it making it hidden again.

Resources