Rails - How To Transfer Data With Button Press - ruby-on-rails

I'm very new to Rails, so this has been tough for me to understand. The front end guy in my group for a school project designed this so that when I tap the "More Info" button on a displayed product, a pop up box shows up on the screen with more information about the product.
How do I make the selected product's info accessible to me so I could display it in the pop up box? I've tried button_to with an :action but I apparently needs a view template, but I don't want that. I simply want to display the selected product's info in the pop up box that shows up when the user taps the "More Info" button.
This is the code I'm working with:
<!-- Container for the Catalog Content -->
<div class="Catalog_page">
<!-- List all products -->
<% #products.each do |product| %>
<div class="product_item">
<span class="img"><%= image_tag product.image, size: "200x100" %></span>
<h1><%= product.name %></h1>
<!--<%= product.description %> Saved this just incase we needed it-->
<%= number_to_currency(product.price) %>
<!-- Button that creates light box -->
<button class="lightbox" id="button">More Info</button>
</div>
<%end%>
<!-- backdrop is the black background of lightbox -->
<div class="backdrop"></div>
<!-- the box that we need to plug information to -->
<div class="box"><div class="close"></div>
I DON'T KNOW HOW TO PULL THIS INFORMATION FROM DATA BASE
</div>
</div>

There are two ways to do your task:
You can render these "more info" and keep it hidden, and then you show the modal these info.
<% #products.each do |product| %>
<div class="product_item">
<span class="img"><%= image_tag product.image, size: "200x100" %></span>
<h1><%= product.name %></h1>
<!--<%= product.description %> Saved this just incase we needed it-->
<%= number_to_currency(product.price) %>
<!-- Button that creates light box -->
<!-- here is the link for each product to open its modal -->
<a data-toggle="modal" data-target="#more-info-<%= product.id %>" class="lightbox">More Info</a>
<!-- here is the modal content -->
<div id="more-info-<%= product.id %>" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">More Info</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
</div>
<% end %>
Or you can fetch these info by ajax and then show it on the modal
<% #products.each do |product| %>
<div class="product_item">
<span class="img"><%= image_tag product.image, size: "200x100" %></span>
<h1><%= product.name %></h1>
<!--<%= product.description %> Saved this just incase we needed it-->
<%= number_to_currency(product.price) %>
<!-- Button that creates light box -->
<button class="lightbox fetch-info" data-product-id="<%= product.id %>">More Info</button>
</div>
<%end%>
<!-- backdrop is the black background of lightbox -->
<div class="backdrop"></div>
<!-- the box that we need to plug information to -->
<div class="box"><div class="close"></div>
<div id="fetch-result"></div>
</div>
and then, create a JS to fetch the data:
$(".fetch-info").click(function() {
var $input = $(this);
$.ajax({
type: "GET",
url: "/product_info",
data: {
id: $input.data("product-id")
},
success: function(response) {
$("#fetch-result").html(response);
}
});
});
Then, create an action to provide the product info:
def product_info
#product = Product.find(params[:id])
render layout: false
end
and create your view with your custom product info...
That's it!
Tip: if you choose the second option, you can improve by calling the action as JSON (fetch just the product info, and then in your success callback, you add the html there)

This is an index page, www.example.com/products. It is showing a list of the products and when clicked they will open a lightbox. What you are going to have to do is pass the id of each individual product into the button so that when the lightbox is opened it is showing the correct information for that product. Alessandro's code is not going to help you because product.attribute1 will not be defined.

Related

Is it possible to put a modal inside a card?

I have a modal that's inside a Bootstrap Card for a confirmation if the user really wants to cancel a booking. The problem is that it doesn't show up when clicked. I see the fade effect and that's about it.
<% if Date.current.strftime('%Y-%m-%d') == data.formatted_date_time_for_comparison %>
<%= f.submit 'Cancel Booking', class: "btn btn-danger" %>
<% else %>
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#myModal">Cancel Booking</button>
<div class="modal fade text-dark" id="myModal">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Confirm Cancellation</h3>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
Are you sure you want to cancel this booking?
</div>
<div class="modal-footer">
<%= f.submit 'Cancel Booking', class: "btn btn-danger" %>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<% end %>
It compares the current date to the date of the booking's departure date and it gives a submit button straight to the controller, which in turn rejects it because cancelling on the same date isn't allowed. If that's not the case it gives a button for a modal to activate.
I'm mostly sure it's because of it buried beneath divs, specifically divs with bootstrap card classes.
Here are its parent divs:
<div class="margin-top" style="width: 600px;">
<div class="bg-dark p-3 rounded">
<h3>Reservations</h3>
</div>
<div id="accordion" class="mt-3 mb-4">
<div class="card bg-dark">
<% #reservations.reverse().each do |data| %>
<a class="btn text-light card-header" data-bs-toggle="collapse" href="#id-<%= data.id %>">
<div class="row" style="text-align: left;">
<div class="col">
<strong>Name: </strong><%= data.name %><br><br>
<!-- other records -->
</div>
<div class="col">
<strong>Departure: </strong><%= data.departure %><br>
<!-- other records -->
</div>
</div>
</a>
<div id="id-<%= data.id %>" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="row">
<div class="col">
<strong>Base Price: </strong><%= data.base_price %><br>
<!-- other records -->
</div>
<div class="col d-flex align-items-end justify-content-end">
<%= form_for #cancellation, url: del_rsrv_path do |f| %>
<%= f.hidden_field :id, value: data.id %>
<%= f.hidden_field :datetime, value: data.formatted_date_time_for_comparison %>
<!-- code posted above here -->
I checked and it does work just below the first div (didn't check on deeper divs), but the problem would be passing the form params there. I'm asking if there's a workaround in either situation.
EDIT: I renamed the data-bs-target name and its respective id name and it somehow works now.

I can only edit my first post

I'm currently facing a strange problem. I'm trying to implement the basics actions into an ajax window. And my problem is that when I'm trying to edit a ranch(like a post), it's always rendering the edit of my first ranch.
This is my code :
(ranch controller)
before_action :set_ranch, only: [:show, :edit, :update, :destroy]
def index
#ranches = current_user.ranches
end
private
# Use callbacks to share common setup or constraints between actions.
def set_ranch
#ranch = Ranch.find(params[:id])
end
(ranch/index)
<%- #ranches.each do |ranch| %>
<div class="box panel panel-default">
<h2><%=link_to ranch.name, ranch%></h2>
<div class="image_wrapper">
<%= link_to (image_tag "ranch.jpg"), ranch %>
</div>
<button type='button' class='btn btn-default' data-toggle='modal' data-target='#MyEditRanch' aria-hidden="true" remote="true" style="float:right; margin-top: 10px;">
<i class="fa fa-cog"></i>
</button>
</div>
<!-- modal Edit -->
<div id='MyEditRanch' class='modal fade' role='dialog' aria-hidden="true">
<div class="modal-dialog">
<div class='content'>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 class="modal-title">Edit <%=ranch.name%></h3>
</div>
<div class="modal-body">
<%= render 'form2', ranch: ranch%>
</div>
</div>
</div>
</div>
<!-- /modal Edit -->
<%end%>
( & my _form2)
<%= simple_form_for(ranch) do |f| %>
<%= f.error_notification %>
<% if ranch.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(ranch.errors.count, "error") %> prohibited this ranch from being saved:</h2>
<ul>
<% ranch.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="col-lg-6">
<div class="input-group" style=" margin-left: 70px;">
<div class="input" style="width: 400px; margin-top: -10px; text-align: center;" >
<%= f.input :name, label: false, style:"margin:0px;", placeholder: "Name of your ranch"%>
</div><!-- /btn-group -->
</div><!-- /input-group -->
<div class="form-actions" style="max-width: 300px">
<%= f.button :submit, style:"text-align:center; margin-left: 70px;" %>
</div>
<%= link_to "Delete", ranch_path(ranch), method: :delete, data: {confirm: "Are you sure that you want to delete this ranch ?"}, class: "btn btn-danger", style:"margin-left: 140px;" %>
<% end %>
</div>
So if you have any advice to solve this shit, you're welcome !!
Thanks in advance
In HTML, ids must be unique on the page.
ie there must be only one of them...
This means there must be only one div that has the id MyEditRanch...
Sometimes the browser lets you get away with it... but if you have JS that uses that id (eg to toggle a modal)... it will still go looking for the first instance of that id on the page to toggle... ie onlyt he first one.
If you want to display multiple ranches - each with their own edit modal... then you really must give each one its own unique id to toggle.
eg append the ranch's id to it in both the button and the edit-modal. eg
<button type='button' data-toggle='modal' data-target='#edit-ranch-<%= ranch.id %>' ...
<!-- and later -->
<div id='#edit-ranch-<%= ranch.id %>'

Submit photo to database from Image Gallery in Rails

I have an images index page which displays an entire album of photos from the User's Facebook profile in a uniform square grid. To get the square grid shape, I had to use some css which crops a little bit of the image from the sides (essentially a thumbnail).
I want the users to be able to click on an image so that a modal comes up that shows the full image, which they can then crop themselves.
Most importantly, I'm wondering how to make it so the modal that pops up is like a form, where you select the part that you want cropped and then click submit, and the photo and crop parameters get saved to the database
Here is what I have so far:
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</div>
<% #profile = #graph.get_object("me") %>
<%= #profile["name"] %><br>
<%= link_to 'Sign Out', sign_out_path, method: :delete %>
<br>
<% #albums = #graph.get_connections("me", "albums?fields=name,photos{name, images{source}}") %>
<% #albums.at(3)["photos"]["data"].each do |data| %>
<div id="<%= data["id"] %>" class="myImages" data-toggle="modal" data-target="#myModal">
<%= image_tag data["images"].first["source"] %>
</div>
<% end %>
<script>
$(document).ready(function() {
$(".myImages").click(function (e){
e.preventDefault();
$(".modal-body").html($(this).html());
});
});
</script>

Trying to create a specific data-target for bootstrap modal through ruby iteration

I am using bootstrap modal on my rails project. On this page I have to iterate through my slides and for each slide I want to create a modal. I came up with this solution:
<% #slides.each do |slide| %>
<div class="row slidecard text-center">
<div class="col-xs-12 ">
<h2><%= slide.name.upcase %></h2>
<p><em><%= slide.description %></em></p>
<a href="#" data-target=<%=slide.id%> data-toggle="modal">
<%= image_tag slide.picture.url(:medium) %>
</a>
<div class="modal fade" id= <%=slide.id%>>
<div class="modal-dialog mymodal">
<div class="modal-content text-center">
<div class="modal-body">
<%= image_tag slide.picture.url(:original) %>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div
</div>
I give to the link containing the image the data-target attr and gives it the value that has the slide.id so I can give a specific id and data target that links image and modal. But the problem is that for the modal to work I need to add "#"in front of slide.id to have something that looks like data-target="#39"
I tried a couple of things such has :
data-target= "#"<%=slide.id%>
and other stuff but nothing gives me the result I want and make the modal work !
licence
try to this

Rails how to make dynamic modal window using twitter bootstrap

Hi every one I'm starting using twitter bootstrap with rails and I would like to make a modal window for each events but the modal window is the same for each component
I've this code :
<% #event.each do |event| %>
<div class="modal hide fade" id="infos">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3><%= event.titre %></h3>
</div>
<div class="modal-body">
<p><%= event.titre %><%= event.dday %><%= event.lieux %> <%= event.commentaire%></p>
</div>
</div>
<div class="timeline_event" data-toggle="modal" data-target="#infos">
<%= link_to (event.titre), event %> <br />
<p>Le <%= event.dday %> à <%= event.lieux %></p>
</div>
<% end %>
You have same id for all divs. So the first modal are always opens.
Try to set unique ids:
<div class="modal hide fade" id="<%= dom_id(event, :infos) %>">
...
<div class="timeline_event" data-toggle="modal" data-target="#<%= dom_id(event, :infos) %>">
upd: http://apidock.com/rails/ActionController/RecordIdentifier/dom_id

Resources