Dynamically Load Bootstrap Modal Content and Open It Using Angular.js - javascript

I am trying to load modal content dynamically and open it when the user clicks a button. I have managed to dynamically load the content using ngInclude, but I cannot open it afterwards. My code:
<div class="modal-container" id="modal-container" ng-include="modal_template"></div>
and my controller.js
function set_modal_template(templateName, callback) {
$scope.modal_template = templateName;
callback();
}
$scope.load_modal_sms = function () {
set_modal_template("/static/partials/modal_template.html", function() {
$('#modal').modal('show');
});
};
and my modal_template.html:
<div class="modal fade" id="modal" role="dialog">
<div class="modal-dialog" modal-sm>
<div class="modal-content">
<div class="modal-header">
<h4>Pop-up head. Email</h4>
</div>
<div class="modal-body">
<h4>Pop-up body.</h4>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
What is happening is that the content of the modal_content.html loads perfectly, but the modal does not show up. If I click again, I only see the transparent black layer that is behind the modal, blacking out the screen, but not the modal itself.
Thanks!

You can solve this problem using a number of techniques. There are a few modules out there that provide modal service, including angular-ui, and I think these could solve your problems better (and more).
angular-modal-service
angular-modal-service is a module dedicated to creating modals. It allows providing either a template or a template service, and supports defining a scope for your modal (useful for abstraction).
Your sample code above would be
<div class="modal fade" id="modal" role="dialog">
<div class="modal-dialog" modal-sm>
<div class="modal-content">
<div class="modal-header">
<h4>Pop-up head. Email</h4>
</div>
<div class="modal-body">
<h4>Pop-up body.</h4>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
// Do not forget to include the module dependency: var myApp = angular.module('myApp', ['angularModalService']);
myApp.controller('MyController', ['ModalService', function (ModalService) {
$scope.load_modal_sms = function () {
var modal = ModalService.showModal({
templateUrl: "/static/partials/modal_template.html",
controller: function () { /* controller code */ }
}).then(function (modal) {
// Modal has been loaded...
modal.element.modal();
});
};
}]);
angular-ui-bootstrap
angular-ui-bootstrap (bower install angular-ui-bootstrap) has a $modal service that is extremely easy to use:
<div class="modal fade" id="modal" role="dialog">
<div class="modal-dialog" modal-sm>
<div class="modal-content">
<div class="modal-header">
<h4>Pop-up head. Email</h4>
</div>
<div class="modal-body">
<h4>Pop-up body.</h4>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
// Do not forget to include the module dependency: var myApp = angular.module('myApp', ['ui.bootstrap.modal']);
myApp.controller('MyController', ['$modal', function ($modal) {
$scope.load_modal_sms = function () {
var modal = $modal.open({
templateUrl: "/static/partials/modal_template.html",
scope: { /* custom scope */ }
});
};
}]);
Using your method
You may want to give angular some time to load and render the loaded template first before trying to .modal() it. If you haven't noticed, your callback is not doing anything special. You can as well run the code without any callback.
<div class="modal fade" id="modal" role="dialog" ng-if="detectLoaded()">
<div class="modal-dialog" modal-sm>
<div class="modal-content">
<div class="modal-header">
<h4>Pop-up head. Email</h4>
</div>
<div class="modal-body">
<h4>Pop-up body.</h4>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
function set_modal_template(templateName) {
$scope.modal_template = templateName;
}
$scope.load_modal_sms = function () {
set_modal_template("/static/partials/modal_template.html");
};
$scope.detectLoaded = function () {
// If this function is called, the template has been loaded...
setTimeout(function () { // Give some time for the template to be fully rendered
$('#modal').modal('show');
}, 10);
return true;
};
You can also remove the timeout by changing the position of the ng-if, or creating a stub element after the div. You can return false from the detectLoaded function to make the stub element not show. I have not tested this last option and don't know if it will work, you have to check.
<div class="modal fade" id="modal" role="dialog">
<div class="modal-dialog" modal-sm>
<div class="modal-content">
<div class="modal-header">
<h4>Pop-up head. Email</h4>
</div>
<div class="modal-body">
<h4>Pop-up body.</h4>
</div>
<div class="modal-footer">
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
<div ng-if="detectLoaded()"></div>
$scope.detectLoaded = function () {
$('#modal').modal('show');
return false;
};

Related

Two Angular router-oulets in bootstrap modal

I have added Other modal in my Angular application both have different
<router-outlet></router-outlet>
Previous one was working fine but after adding 2nd modal with different routes 1st stopped working. i tried with different name attributes on router-outlets nothing seems to be working.
only one is working at a time if i comment out the other one.
<button type="button" data-target="#settings2" data-toggle="modal" routerLink="setup_season">
Season
</button>
<button type="button" data-target="#settings" data-toggle="modal" routerLink="setup_package">
Package
</button>
first modal
<div id="settings" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal -->
<div class="modal fade" id="myModal" 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">Modal Header</h4>
</div>
<div class="modal-body">
<router-outlet></router-outlet> // already tried with name attribute
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
2nd Modal
<div id="settings2" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal -->
<div class="modal fade" id="myModal" 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">Modal Header</h4>
</div>
<div class="modal-body">
<router-outlet></router-outlet> // already tried with name attribute
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
You need to use auxiliary routes, I will paste a similar case of my own code, try to do the same with your code:
<div class="side-panel">
<!-- the auxiliary outlet -->
<router-outlet name="sidePanel"></router-outlet>
</div>
<div class="main-content m-0 p-0">
<!-- the primary outlet -->
<router-outlet></router-outlet>
</div>
The routes configurations should be something similar to this one:
const routes: Routes = [
{
path: '',
redirectTo: '/app/auth/login',
pathMatch: 'full'
},
{
path: 'app',
children: [
{
path: 'main',
component: MainComponent
},
{
path: 'side-menu',
component: SlidePanelComponent,
outlet: 'sidePanel', // You need to mention the name of the auxiliary route
}
]
]
Finally, you need to mention the name of the outlet in the routerLink just like this:
<a [routerLink]="[{ outlets: { sidePanel: 'side-menu'}}]">

map not showing in modal bootstrap

I try showing map in modal bootstrap but I have this dispaly:
enter image description here
code modal:
<div class="modal" tabindex="-1" role="dialog" [ngStyle]="{'display':displaymap}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" (click)="onCloseHandledmap()"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">test</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-12">
<agm-map [scrollwheel]="false" [zoom]="zoom">
<ng-container>
<agm-polyline [strokeColor]="color" [strokeWeight]="weight" >
<agm-polyline-point *ngFor="let test of lines" [latitude]="test.latitude"
[longitude]="test.longitude" >
</agm-polyline-point>
</agm-polyline>
</ng-container>
</agm-map>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" (click)="onCloseHandledmap()" >Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
and in component I add this code:
I try with this code:
ngOnInit() {
$('.modal').on('shown.bs.modal', () => this.agmMap.triggerResize());
}
and with this code also:
ngOnInit() {
this.resizeMap();
}
resizeMap() {
this.map.triggerResize();
}
but also dispaly .. map is not show and in css I try
agm-map{ height:500px;}
Try to set the z-index of both, your Bootstrap modal and your map accordingly, so that the map will appear on top. Ensure that you are applying the z-index of the map container where the Google's init function is set up to act upon.
You may try to preview this change through the developers' console to ensure if this is actually your problem.
$('.modal').css('z-index', '10000');
$('agm-map').css('z-index', '100001');
$('ng-container').css('z-index', '100002');

Display a modal once per session using the sessionstorage function

I have a modal on a page which makes use of javascript to display once the page has loaded, however, on refresh, I would like this modal to not be repeated as it can be a bit of a nuisance.
I have done some research and found a method using 'sessionstorage' but the problem is I don't know how to incorporate it into my code. My java is very poor.
Excerpt of my modal html and Javascript code below.
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p class="text-left-side">
<b>Check out your order now </b><br><br>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><b>Close<b></button>
</div>
</div>
</div>
<!-- sCRIPT FOR THE PAGE LOAD MODAL -->
<script type="text/javascript">
$(window).load(function(){
setTimeout(function(){ $('#myModal').modal('show'); }, 1400);
});
</script>
Few mistakes.
Use $(document).ready() function.
Use localStorage and set a flag. If it is set, don't display modal. Display only when it is not set.
Snippet
$(function() {
if (typeof Storage != "undefined") {
if (!localStorage.getItem("done")) {
setTimeout(function() {
$('#myModal').modal('show');
}, 1400);
}
localStorage.setItem("done", true);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p class="text-left-side">
<b>Check out your order now </b><br><br>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><b>Close<b></button>
</div>
</div>
</div>
</div>
The above code will not execute in Snippets because of sandboxing. Kindly check with your code.
You can check the working demo at JSBin. Be careful. It works only once. :D

Don't load the modal if the the value is empty onload

I want to show modal only after form gets submitted.but It's loading at starting.
Here is my html code
<div class="container">
<!-- Modal -->
<div class="modal fade" id="myModal" 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">Dear User</h4>
</div>
<div class="modal-body">
<p>Please note down your respective ID's</p>
<p id="ucid">Client ID:<s:property value="ucid"/></p>
<p>Broker ID:<s:property value="ubid"/></p>
<p>Developer ID:<s:property value="udid"/></p>
</div>
</div>
</div>
</div>
</div>
and here is Javascript
function myFunction(){
if ($('#ucid').val()=='') {
$("#myModal").modal("hide");
}else{
$('#myModal').modal('show');
}
though i tried above function to hide that.but its not working.please help me out.Thanks in advance
You should use .text() method to get value from p DOM element.
if ($('#ucid').text()=='') {
$("#myModal").modal("hide");
}else{
$('#myModal').modal('show');
}

slimScroll- doesn't work good in the second modal

I have 2 modals (when the first is close the second is open) the code of the first modal in a template (gsp) and the of the second one is in the view page
The code I use for close the first and open the second is:
function openModal(){
if($('.invitePartners').valid()){
$('.invite-contacts-modal').modal('hide')
$('.modal-backdrop').remove();
$('#mySecModal').modal();
}
The html for the second modal:
<div class="modal fade" id="mySecModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog signup-modal">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title light-green"><g:message code="signup.redesign.invitepartners.modal.title"/></h4>
</div>
<div class="modal-body">
<g:message code="signup.redesign.invitepartners.modaldetails.header"/><br><br>
<span>${user?.firstname}</span><span> ${user?.lastname} </span><g:message code="signup.redesign.invitepartners.modaldetails.body"/>
</div>
<div class="modal-footer">
<g:message code="buttons.dontsend"/>
<button name="next" class="signup-button skyblue-btn pull-right pl-pr-36" >${message(code:"buttons.ok")}</button>
</div>
</div>
</div>
</div>
In the first modal the scroll works fine.
I the second modal the user can scroll until he get to the end of the modal (which is cut).
I use scrollSlim plugin

Categories