I am using Rails 4 and bootstrap. When the user clicks the link, I want modal to appear, the controller action corresponding to the remote-url to be invoked, and the response to be loaded in the modal. The four data attributes I need are: data-toggle and data-target for the modal and remote: true and data-url for the rails.js ajax.
I construct the link and modal in a helper as so:
def modal(title, &block)
options = { 'data-url' => tasks_path, remote: true, 'data-toggle' => "modal", 'data-target' => '#unresolvedTasks' }
link = link_to '#', options do
content_tag(:span, nil, class: 'dom_class') + title
end
modal = render layout: "shared_resources/modal", locals: { options: options}, &block
link + modal
end
The resulting html:
<a class="" data-remote="true" data-target="#unresolvedTasks" data-toggle="modal" data-url="/tasks/1" href="#" style=""><span class="glyphicon glyphicon-plus"></span>sdfdsf sdfdsfds</a>
<div class="modal fade in" id="unresolvedTasks" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false" style="display: block;">
<div class="modal-dialog modal-sizer">
<div class="modal-content">
<div class="modal-header" style="overflow: auto;">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
</div>
<div class="loading" style="display: none;">
<img alt="Spinner" src="/assets/spinner.gif">
</div>
<div class="modal-target">
</div>
</div>
</div>
</div>
Unfortunately, when I click the link, it does not go to '/tasks/1'. Instead it goes to '/'. Why is the data-url being ignored?
You have this code in your question: link = link_to '#'
Which means that it does, in fact, link to / and not /tasks/1
In the first code block, change the link = link_to '#' to link = link_to '/tasks/1'
Related
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.
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' %>
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">
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>
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.