Use modal in place of 'show' views - javascript

I am trying to use modals in place of the traditional 'show' views in Ruby. When a user clicks on a item in the index view, a modal popup shows instead of redirecting the user to a new 'show' page.
How can I accomplish this?
Let's assume that the controller looks something like this:
#list = Items.all
I want the modal to show the characteristics of each item on the #list object. For instance, one modal would show #list[0] and another would be #list[1]. How can I pass the index values to the modal?

An approach I might take would be, assuming that on your index there is a dropdown and a submit button ...
jQuery
$('#submit').click(function(){
$.ajax({
url: "items/get_item",
type: "GET",
data: { item: $('#select').val() },
success: function (data) {
//Populate modal in here with item details
$('#myModal modal-body').html(data)
}
});
});
Item Controller
def get_item
return :json => Item.where({:name => params[:item]}).to_json
end
View
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<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">Save changes</button>
</div>
</div>
</div>
</div>

You need to render a javascript template from the show action
def show
#list = Items.all
respond_to do |format|
format.js { render 'your_js_template' }
end
end
Then in your template you can use the #list instance variable to create the jQuery for the modal

Related

Flask add modal to ask before deleting. How to get working?

In my Flask APP i have a page with a link to delete:
Is inside a table each row have this id, here I am sending the ID (that normaly I use to delete):
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" id="submits" onclick="send_to_modal('{{post.id}}')">
Borrar
</button>
Here is my javascript:
function send_to_modal(id){
document.getElementById("exampleModalLabel").innerHTML = id;
};
The modal:
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"> </button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" onclick="modal_a_funccion()">SI</button>
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">NO</button>
</div>
</div>
</div>
</div>
I don´t know how to send the ID to another function that is charged to delete the specified data:
This is my function that works correcty and delete the data giving the ID:
function modal_a_funccion(id){
console.log("Solicitando un report para: "+id);
//fetch('/report/' + olt_hostname).then(function(response) {
fetch('/task/report_celery/' + id).then(function(response) {
response.json().then(function(data) {
for (var x of data.ip) {
console.log("REPORT_fetch recibe (IP): " +x.ip_oob)
console.log("REPORT_fetch recibe (ESTADO): " +x.estado)
};
});
});
};
I would like to know how to to it.
What I intend to do is add a modal to ask the user for confirmation whether or not to delete. I can't find a way to pass the Id to the function that is in charge of doing the deletion. I would like to know how to do it. Thank you so much.
A possible solution (in a different way)
When user clicks on delete for a row, add a class e.g. to_delete. Then display the modal popup asking if user wants to go ahead with the delete or not.
If user says no, close the modal and remove the class again
If user says yes, call the delete function
For 3, you do something like
// Find the element that user has marked for delete
const element = document.querySelect(".to_delete")
const id = element.id;
For 2, you do something like
// Find the element that user has marked for delete and remove the delete mark
document.querySelect(".to_delete").classList.remove("to_delete")

modal iteration in foreach loop using ajax

I got a problem with foreach loop. What am i trying to do is get data (JsonResult) from action in controller. Get get songs for each album.
public JsonResult SongListByAlbum(int albumID)
{
var songs = (from song in Song.GetSongList()
join album in Album.GetAlbumList()
on song.AlbumID equals album.AlbumID
where (albumID == album.AlbumID)
select song).ToList();
return Json(songs,JsonRequestBehavior.AllowGet);
}
Then put them into view, for album get list of songs and show them as modals
There is my view:
#foreach (var item in Model.Albums){
<button id="#item.AlbumID" type="button" class="btn btn-primary myModals" data-toggle="modal" data-target="#exampleModal-#item.AlbumID">
Show
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal-#item.AlbumID" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel-#item.AlbumID" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel-#item.AlbumID">#item.AlbumName #item.Year, #item.BandName</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div id="parent" class="modal-body">
</div>
<div class="modal-footer">
<button id="closeModal"type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
}
And there is a script, where I get songs for each album.
<script>
$(".myModals").on("click", function () {
var Id = $(this).attr('id');
alert(Id);
$.ajax({
type: "GET",
url: '#Url.RouteUrl(new{ action= "SongListByAlbum", controller="Default"})',
data: {albumID:Id},
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (result) {
for (var i in result) {
$('#parent').append('<p class="toRemove">' + result[i].SongName + '</p>');
}
},
error: function (response) {
alert('error');
}
});
});
</script>
The problem is : when i click on the first modal button everything is fine, i get what i want to. But when i click on the second one i got empty modal. Then when i click again on the first one i got data from previous click and penultimate. Image: enter image description here
To avoid multiple <div id="parent"> elements, you should probably assign the Id the same way you do for the buttons. Like <div id="parent-#item.AlbumID">. Then in your ajax call reference the correct div. $('#parent-' + Id).
Not sure if that is your only probably, but might get you closer.

Boostrap modal not loading when wired using jquery

I have the following link and I'm trying to load a bootstrap modal when its clicked but the javascript function doesnt seem to be firing. Instead of the view loading inside a modal, its loading as a new page?
#*this is the modal definition*#
<div class="modal hide fade in" id="report-summary">
<div id="report-summary-container"></div>
</div>
<script >
$('a.js-report-summary').click(function (e) {
var url = $(this).attr('href'); // the url to the controller
e.preventDefault();
$.get(url, function (data) {
$('#report-summary-container').html(data);
$('#report-summary').modal('show');
});
});
</script>
public ActionResult ReportSummary()
{
// some actions
return PartialView("ReportSummary", viewmodel)
}
// Report summary view which contains modal
<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">#ViewBag.FormName - Analysis</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">
Close</button>
</div>
</div>
</div>
There are no errors showing in the console either so why isn't the jquery function firing?
in your click function, add parameter e this will stand for event
then in the function itself add e.preventDefault() This will stop the refreshing effect.
on your controller method try
public ViewResult ReportSummary()
{
// some actions
if(Request.IsAjaxRequest())
return PartialView("ReportSummary", viewmodel);
else
return View("ReportSummary", viewmodel);
}
on your view
$('#exampleModal').on('show.bs.modal', function (event) {//give your model wrapper an id
//do some ajax and get html
$.ajax({
url:'',
success:function(data){
$('#report-summary-container').html(data);
}
});
})
on your anchor tag, add data-toggle="modal" data-target="#exampleModal"
if you dont want to use bootstrap events trigger your modal with
$('#myModal').modal('show')

fullcalendar bootstrap modal with external event data

I'm using full calendar with a asp.net MVC 5 application.
When I click a on a empty space I get a modal view for creating a event. This works perfect.
When I click on a event I want to get the event data but also some other data then just the start date end date and description.
I have the following:
eventRender: function (event, element) {
var id = event.id;
element.popover({
placement: 'top',
html: true,
content: '<button id="customers" class="btn btn-default" onclick="KlantenModal(' + id + ')">Klant overzicht</button>',
animation: true
});
}
The function that calls the modal.
function KlantenModal(event) {
$('#klanten #eventId').val(event);
$('#klanten').modal('show');
}
and the bootstrap modal:
<div class="modal fade" id="klanten" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" 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 class="modal-title" id="myModalLabel">Klanten</h4>
</div>
<div class="modal-body">
/* here I want some Data eg. names of customers */
<input type="hidden" id="eventId" name="eventId" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary"></button>
</div>
</div>
</div>
If i understood you well the only thing you have to do is to add fields to the event like this:
Somewhere in your code populate an array with diferent customers and add that array to the event properties
var customers = [];
customers.push("im customer x");
customers.push("im customer y");
...
events:[
{
'start': 2013-12-30,
'end': 2013-12-30,
'allDay': true,
'customers': customers
}
and when you click on the event and access the event fields you will get the customers field wich contains your customers for that day.

How can I trigger a Bootstrap modal programmatically?

If I go here
http://getbootstrap.com/2.3.2/javascript.html#modals
And click 'Launch demo modal' it does the expected thing. I'm using the modal as part of my signup process and there is server side validation involved. If there are problems I want to redirect the user to the same modal with my validation messages displayed. At the moment I can't figure out how to get the modal to display other than a physical click from the user. How can I launch the model programmatically?
In order to manually show the modal pop up you have to do this
$('#myModal').modal('show');
You previously need to initialize it with show: false so it won't show until you manually do it.
$('#myModal').modal({ show: false})
Where myModal is the id of the modal container.
You should't write data-toggle="modal" in the element which triggered the modal (like a button), and you manually can show the modal with:
$('#myModal').modal('show');
and hide with:
$('#myModal').modal('hide');
This is a code for Bootstrap v5 without jQuery.
let myModal = new bootstrap.Modal(document.getElementById('myModal'), {});
myModal.show();
Demo
And this is a codesandbox demo to open modal on page load programmatically.
https://idu6i.csb.app/
Refs
https://getbootstrap.com/docs/5.0/components/modal/#via-javascript
https://getbootstrap.com/docs/5.0/components/modal/#show
If you are looking for a programmatical modal creation, you might love this:
http://nakupanda.github.io/bootstrap3-dialog/
Even though Bootstrap's modal provides a javascript way for modal creation, you still need to write modal's html markups first.
HTML
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<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">
...
</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>
JS
$('button').click(function(){
$('#myModal').modal('show');
});
DEMO JSFIDDLE
you can show the model via jquery (javascript)
$('#yourModalID').modal({
show: true
})
Demo: here
or you can just remove the class "hide"
<div class="modal" id="yourModalID">
# modal content
</div>
​
I wanted to do this the angular (2/4) way, here is what I did:
<div [class.show]="visible" [class.in]="visible" class="modal fade" id="confirm-dialog-modal" role="dialog">
..
</div>`
Important things to note:
visible is a variable (boolean) in the component which governs modal's visibility.
show and in are bootstrap classes.
An example component & html
Component
#ViewChild('rsvpModal', { static: false }) rsvpModal: ElementRef;
..
#HostListener('document:keydown.escape', ['$event'])
onEscapeKey(event: KeyboardEvent) {
this.hideRsvpModal();
}
..
hideRsvpModal(event?: Event) {
if (!event || (event.target as Element).classList.contains('modal')) {
this.renderer.setStyle(this.rsvpModal.nativeElement, 'display', 'none');
this.renderer.removeClass(this.rsvpModal.nativeElement, 'show');
this.renderer.addClass(document.body, 'modal-open');
}
}
showRsvpModal() {
this.renderer.setStyle(this.rsvpModal.nativeElement, 'display', 'block');
this.renderer.addClass(this.rsvpModal.nativeElement, 'show');
this.renderer.removeClass(document.body, 'modal-open');
}
Html
<!--S:RSVP-->
<div class="modal fade" #rsvpModal role="dialog" aria-labelledby="niviteRsvpModalTitle" (click)="hideRsvpModal($event)">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="niviteRsvpModalTitle">
</h5>
<button type="button" class="close" (click)="hideRsvpModal()" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary bg-white text-dark"
(click)="hideRsvpModal()">Close</button>
</div>
</div>
</div>
</div>
<!--E:RSVP-->
The following code useful to open modal on openModal() function and close on closeModal() :
function openModal() {
$(document).ready(function(){
$("#myModal").modal();
});
}
function closeModal () {
$(document).ready(function(){
$("#myModal").modal('hide');
});
}
/* #myModal is the id of modal popup */
The same thing happened to me. I wanted to open the Bootstrap modal by clicking on the table rows and get more details about each row. I used a trick to do this, Which I call the virtual button! Compatible with the latest version of Bootstrap (v5.0.0-alpha2). It might be useful for others as well.
See this code snippet with preview:
https://gist.github.com/alireza-rezaee/c60da1429c36351ef4f071dec0ea9aba
Summary:
let exampleButton = document.createElement("button");
exampleButton.classList.add("d-none");
document.body.appendChild(exampleButton);
exampleButton.dataset.toggle = "modal";
exampleButton.dataset.target = "#exampleModal";
//AddEventListener to all rows
document.querySelectorAll('#exampleTable tr').forEach(row => {
row.addEventListener('click', e => {
//Set parameteres (clone row dataset)
exampleButton.dataset.whatever = e.target.closest('tr').dataset.whatever;
//Button click simulation
//Now we can use relatedTarget
exampleButton.click();
})
});
All this is to use the relatedTarget property. (See Bootstrap docs)
Here's how you do it with ternary operator
$('#myModal').modal( variable === 'someString' ? 'show' : 'hide');

Categories

Resources