Bootstrap 4 load modal-Content from other page [duplicate] - javascript

I can't make the Modal work in the remote mode with the new Twitter Bootstrap release : Bootstrap 4 alpha. It works perfectly fine with Bootstrap 3. With bootstrap 4 I am getting the popup window, but the model body is not getting loaded. There is no remote call being made to myRemoteURL.do to load the model body.
Code:
<button type="button" data-toggle="modal" data-remote="myRemoteURL.do" data-target="#myModel">Open Model</button>
<!-- Model -->
<div class="modal fade" id="myModel" 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>
<h3 class="modal-title" id="myModalLabel">Model Title</h3>
</div>
<div class="modal-body">
<p>
<img alt="loading" src="resources/img/ajax-loader.gif">
</p>
</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>

Found the problem: They have removed the remote option in bootstrap 4
remote : This option is deprecated since v3.3.0 and will be removed in v4. We recommend instead using client-side templating or a data binding framework, or calling jQuery.load yourself.
I used JQuery to implement this removed feature.
$('body').on('click', '[data-toggle="modal"]', function(){
$($(this).data("target")+' .modal-body').load($(this).data("remote"));
});

According to official documentation, we can do the follow(https://getbootstrap.com/docs/4.1/components/modal):
$('#exampleModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('whatever') // Extract info from data-* attributes
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this)
modal.find('.modal-title').text('New message to ' + recipient)
modal.find('.modal-body input').val(recipient)
})
So, I believe this is the best approach (works for BS 5 too):
<!-- Button trigger modal -->
<a data-bs-toggle="modal" data-bs-target="#modal_frame" href="/otherpage/goes-here">link</a>
<!-- Modal -->
<div class="modal fade" id="modal_frame" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<!-- Completes the modal component here -->
</div>
<script>
$('#modal_frame').on('show.bs.modal', function (e) {
$(this).find('.modal-body').load(e.relatedTarget.href);
});
</script>
e.relatedTarget is the anchor() that triggers the modal.
Adapt to your needs

As some of the other answers and Bootstrap docs indicate, Bootstrap 4 requires handling the show.bs.modal event to load content into the modal. This can be used to either load content from an HTML string, or from a remote url. Here's a working example...
$('#theModal').on('show.bs.modal', function (e) {
var button = $(e.relatedTarget);
var modal = $(this);
// load content from HTML string
//modal.find('.modal-body').html("Nice modal body baby...");
// or, load content from value of data-remote url
modal.find('.modal-body').load(button.data("remote"));
});
Bootstrap 4 Remote URL Demo
Another option is to open the modal once data is returned from an Ajax call...
$.ajax({
url: "http://someapiurl",
dataType: 'json',
success: function(res) {
// get the ajax response data
var data = res.body;
// update modal content
$('.modal-body').text(data.someval);
// show modal
$('#myModal').modal('show');
},
error:function(request, status, error) {
console.log("ajax call went wrong:" + request.responseText);
}
});
Bootstrap 4 Load Modal from Ajax Demo

In Asp.NET MVC, this works for me
html
Edit item
<div class="modal" id="modalPartialView" />
jquery
<script type="text/javascript">
function Edit(id)
{
$.ajax({
url: "#Url.Action("ActionName","ControllerName")",
type: 'GET',
cache: false,
data: {id: id},
}).done(function(result){
$('#modalPartialView').html(result)
$('#modalPartialView').modal('show') //part of bootstrap.min.js
});
}
<script>
Action
public PartialViewResult ActionName(int id)
{
// var model = ...
return PartialView("_Modal", model);
}

If you use the Jquery slim version (as in all the Bootstrap 4 docs and examples) the load function will fail
You need to use the full version of Jquery

This process is loading the current dynamic. data remote = "remoteContent.html"
<!-- Link trigger modal -->
<a href="javascript:void(0);" data-remote="remoteContent.html" data-toggle="modal" data-target="#myModal" data-remote="true" class="btn btn-default">
Launch Modal
</a>
This trick : data-remote="remoteContent.html"
<!-- Default bootstrap modal example -->
<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>

Related

Modal won't close and prevent default on no click, and won't execute func on yes click

I have a modal with two buttons. One is a yes button and one is a no button. If yes button is pressed, I would like the remainder of the function to execute. If no btn clicked, I would like the page to prevent default and not execute. However, it seems that regardless of which button is clicked, nothing happens besides the modal closing. I am using a modal example I found elsewhere, so this may be the issue. After glancing at it for some time I cannot seem to find where the issue is. Am I missing something small? Or perhaps my Jquery is wrong? Below is my code:
Modal:
<!-- Modal for delete-->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content border-primary mb-3 box-shadow-none img-responsive">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="card-body bg-light">
<div id="del" class="center">
<label>Are you sure you want to delete?</label>
</div>
</div>
<div class="modal-footer">
<div id="deleteYes">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteYes">Yes</button>
</div>
<div id="deleteNo">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteNo">No</button>
</div>
</div>
</div>
</div>
</div>
And here is my Jquery:
$(".btnDeleteTerminalCommand").click(function (e) {
$("#deleteModal").modal('toggle');
if ($("#deleteNo").click) {
return e.preventDefault();
}
var rowId = "#" + $(this).data("rowindex");
var row = $(rowId);
var termId = row.find(".tdTermId").html().trim();
var cmdId = row.find(".tdCmdId").html().trim();
var cmdVal = row.find(".tdCmdVal").html().trim();
var cmdID = row.find(".cmdID").html().trim();
var data = {
TerminalID: termId,
CommandID: cmdId,
CommandValue: cmdVal,
ID: cmdID
};
$.ajax({
url: '#Url.Action("DeleteTerminalCommand", "TerminalCommand")',
type: "POST",
data: data,
success: function (response) {
console.log("Success");
window.location.href = response.Url;
}
});
});
Any advice helps! Thank you!
Your click handler will toggle the modal and immediately continue to execute the rest of the function before the user can click anything. If your modal has two buttons, create a click handler for each button. Perhaps the No button just closes the modal. The Yes button handler can execute the actions required to accomplish the task.
$(".btnDeleteTerminalCommand").click(function(e){
$("#deleteModal").modal('toggle');
}
$("#deleteNo").click(function(e){
$("#deleteModal").modal('hide');
}
$("#deleteYes").click(function(e){
// build data object
// ajax post
}

Hide a dynamic element function on.('hide')

I have a problem with the following function. I am dynamically creating a bootstrap modal (regular div), and I want to attach a function I pass trough a variable (witch works fine) and run it on on.("hide"), but instead it fires as soon as the modal is opened ( $(modal).on('hide', windowclose_function ); ). Is there something I`m missing?
Thanks
function openModalFromUrl(modal_url, close_function = function(){}) {
var token = $("meta[name='csrf-token']").attr("content");
$.ajax({
data: {
'_token': token,
},
url: modal_url,
type: 'POST',
success: function(html) {
// create a new modal div
var modal = document.createElement("div");
$(modal).addClass('modal fade');
$(modal).attr( "role", "dialog" );
$('body').append(modal);
// place response in the modal
$(modal).html(html)
// open the modal
$(modal).modal('show');
// THIS FIRES IMMEDIATELY
$(modal).on('hide', window[close_function]() );
},
error: function() {
bootbox.alert('Error');
}
});
}
The issue is in this line :-
$(modal).on('hide', window[close_function]() );
Change it to :-
$(modal).on('hide', window[close_function] );
Explanation :-
In JavaScript when we provide a function as a reference, we use it's name without any parenthesis
i.e. 'my_func' not 'my_func()'
As 'my_func()' give the result of the function as reference not the function itself.
So just remove the parenthesis and your problem is solved.
According to the documentation you should use hidden.bs.modal event. Also no need in checking the window object for the function, just pass it.
$('#myModal').modal('show');
var close_function = function () {
console.log('closed');
}
$('#myModal').on('hidden.bs.modal', close_function);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<div class="modal fade" id='myModal' abindex="-1" role="dialog">
<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">Modal title</h4>
</div>
<div class="modal-body">
<p>One fine body…</p>
</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>
Thank you to all for your answers. I have found the solution.
As the modals were dynamically generated i had to change the call to:
$('body').on('hide.bs.modal', modal, window[close_function] );
Now it works like a charm. Thanks again to everyone!

Load modal box only if API successfully returns data

I have a question about uib-modal box. In my angular app, when we click on button EDIT CONFIGURATION, we call modal box, with configuration info. On click, also, we call function for load data in config from API server. Problem is, if the internet speed is slow and server request needs more than 2 sec for response, modal box will be opened without loaded data. If server response is normal, in this case, data will be loaded normally.
My question is, how to wait with load modal box, or show some spinner, until data is loaded.
This is my function where I make a call to API
$scope.setDataInConfigList = function () {
$scope.parcijalniConfigZaPopUp = "";
$scope.currentKlupaParcijalniConfig = sveKlupeServiceFactoryConfig.get({klupa: $scope.selected.klupe});
$scope.currentKlupaParcijalniConfig.$promise.then(function (configParcijalni) {
$scope.parcijalniConfigZaPopUp = configParcijalni;
$scope.klupaLedconfigVrijemeRada.ledConfigLedSummerTimeMaxTime = $scope.parcijalniConfigZaPopUp.led_band_config.operating_time_schedule.max_operating_hours_summer ? $scope.parcijalniConfigZaPopUp.led_band_config.operating_time_schedule.max_operating_hours_summer : null;
$scope.klupaLedconfigVrijemeRada.hotspot_user_time_unlimited = $scope.parcijalniConfigZaPopUp.hotspot_user_time_unlimited ? $scope.parcijalniConfigZaPopUp.hotspot_user_time_unlimited : null;
});
};
And modal box
<button type="button" id="add_new_bench" class="btn btn-default" style="color:#000;" data-toggle="modal" data-target="#myModal1" data-backdrop="static" data-keyboard="false" ng-click=" setDataInConfigList(currentItemtBench.id)">{{'EDIT_CONFIGURATION'| translate}}</button>
<div class="modal fade" id="myModal1" 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>
<parcijalni-config></parcijalni-config>
</div>
</div>
</div>
</div>

on button click add action url jquery

I have a link like this:
<a class="glyphicon glyphicon-remove glyphicon-color-red btn-delete" data-toggle="modal" data-target="#myModal" user-id="56f52ea551d72027711157d6"></a>
And with jquery, on click I take parameter user-id and I change action URL, this code isn't working cause when I click the delete button modal popup appears, but if I do inspect element I see that action is empty?
$('.btn-delete').click(function () {
var user_id = $(this).attr('user-id');
$('#modal-form').attr('action', "{{ url_for('admin.delete_user', id=" +user_id+" ) }}");
});
The method that I use in route admin.delete_user in python is:
def delete_user(self, id):
mongo.db.users.remove({'_id': ObjectId(id)})
return redirect(url_for('admin.users'))
And the modal popup:
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span></h4>
</div>
<form id="modal-form" action=" " method="POST">
<div class="modal-body">
<p>Are you sure?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default btn-sm btn-style" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-default btn-sm btn-filter-apply btn-style" >Yes</button>
</div>
</form>
</div>
</div>
I don't understand why in jquery the action URL is not added?
Make sure that the DOM has loaded before you make any changes, for which you can use ready():
$(document).ready(function(){ /* your code */ });
I would change your url_for function to to produce part of the url you need, then place it in the action attr. Then, use jquery to append the user_id to the string. Make sure you modify whatever is grabbing the url to parse a parameter. Here's an example:
url_for returns something like: http://www.example.com?delete_user=
Then your form action:
<form id="modal-form" action="{{url_for(delete_user)}}" method="POST">
And your jquery would then:
$('.btn-delete').click(function () {
var user_id = $(this).attr('user-id');
var action = $('#modal-form').attr('action');
$('#modal-form').attr('action', action + user_id);
});
Finally, whatever is parsing your form would look for the url parameter delete_user= and use the user_id you appended to it.

Bootstrap Modal with individual attributes

I would like to use one Bootstrap Modal for several functions, which should be loaded dynamically by clicking on a button / link (see example).
For some reason the attributes (data-mTitle & data-mParams) will not load. With the standard attributes
like href, id, class etc. it works flawlessly.
As I said, I would like to use only one Modal (HTML) and one JS function for all purposes (as an universal solution). Any idea what I am doing wrong?
$(document).ready(function(){
$('#myModal').on('shown.bs.modal', function () {
var $modal = $(this),
modal_title = $(this).data('modal-title'),
modal_params = $(this).data('modal-params');
if(typeof modal_title !== typeof undefined && modal_title !== false) {
title = modal_title;
}
else{
title = 'My Title';
}
$.ajax({
cache: false,
type: 'POST',
url: '/ajax.php',
data: modal_params,
success: function(data) {
$modal.find('.modal-title').html(title);
$modal.find('.modal-body').html(data);
}
});
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
Link 1
Link 2
<div class="modal hide fade" id="myModal">
<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">Loading title...</h4>
</div>
<div class="modal-body">
Loading content...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
You must use only lower-case letters in your attribute names.
You can find the reason in this answer.
Basically, when you write:
$(this).attr('data-mTitle')
jQuery is looking for this:
<a data-m-title="Title"></a>
By the way, even though there's nothing wrong with using .attr() here, instead you should use .data() that is specifically meant for working with data attributes.

Categories