Bootstrap 4 - .modal is not a function - javascript

I'm using plain Javascript along with Bootstrap, and am getting this error. I've looked at many different questions and none seem to work for me. I downloaded Jquery, Popper, and Bootstrap with npm, and have added the min scripts at the bottom of my body:
<div id="success-delete" 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">Success!</h4>
</div>
<div class="modal-body">
<p>Template successfully deleted.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="/js/jquery.min.js" defer></script>
<script src="/js/popper.min.js" defer></script>
<script src="/js/bootstrap.min.js" defer></script>
<script src="/js/template-section.js" defer></script>
As you can see, I'm loading the jquery before bootstrap. When a function is called in my Javascript, I want the modal to appear:
/* template-section.js */
class TemplateSection {
constructor(...) {
...
this.successModal = document.querySelector('#success-delete');
}
_removeTemplate(e) {
const success = this.deleteCallback(e.currentTarget.previousSibling.getAttribute('src'));
if (success) {
this.container.removeChild(e.currentTarget.parentNode);
this.successModal.modal('show');
} else {
// do something
}
}
}
I've also tried changing the modal options to {show : true}, but that's not working. Printing out this.successModal gives me the correct element, but it doesn't appear to have the function modal.
Edit: I also know for a fact that the bootstrap.min.js file I have has modals included - I tried activating the modal by a button click and it works fine. It's getting the javascript to recognize the modal that's the problem.
Edit 2: Fixed! See answer below.

Fixed by using $('#success-delete') instead of the object declared from documentSelector. Not really sure why, but it's working!

Related

Modal pop-up non showing in asp.net core mvc web app

I have an ASP.NET CORE MVC based app. I am having a strange behavior when trying to show a modal popup with JQuery.
I have following div:
<div class="modal fade" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false" id="form-modal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</div>
</div>
</div>
</div>
I have a button to show this div modal popup. When I click the button Javascript adds «in» to class so it becomes class="modal fade in", normally it should add «show». As a result the modal is not showing. So in the browser I enter dev mode and removed «in» and added «show» and it worked.
But I am wondering why my JQuery is adding «in» instead of «show».
Here is my JQuery:
jQueryModalGet = (url, title) => {
try {
$.ajax({
type: 'GET',
url: url,
contentType: false,
processData: false,
success: function (res) {
$('#form-modal .modal-body').html(res.html);
$('#form-modal .modal-title').html(title);
$('#form-modal').modal('show');
console.log(res);
},
error: function (err) {
console.log(err)
}
})
return false;
} catch (ex) {
console.log(ex)
}
}
Any idea ?
Finally, I solved the issue.
For some strange reason I included two different versions of Bootstrap and JQuery at the same time so the conflict was happening in the modal show process.
I had:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
After removing:
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
And using only the local binded libs I resolved it!
Now it works like a charm.

Bootbox Dialog Modal Bootstrap 4

On my page, I have a table. Inside one of the cells of that table is a link. I am performing jQuery scripts if that link is clicked. For instance if the link is clicked I want to show a Bootstrap Dialog. This can be done easily with Bootbox.js. However, bootbox is not updated with support of Bootstrap 4.
Originally, the bootbox wouldn't even show because in Bootstrap 3, the class name to show something was in, but in Bootstrap 4 it is show. I have fixed that, but here is how it looks currently.
The HTML that is generated by calling bootbox.js for this is:
<div tabindex="-1" class="bootbox modal fade show in" role="dialog" style="display: block;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="bootbox-close-button close" aria-hidden="true" type="button" data-dismiss="modal">×</button>
<h4 class="modal-title">Test Title?</h4>
</div>
<div class="modal-body">
<div class="bootbox-body">Test Message</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button" data-bb-handler="cancel"><i class="fa fa-times"></i> Cancel</button>
<button class="btn btn-primary" type="button" data-bb-handler="confirm"><i class="fa fa-check"></i> Confirm</button>
</div>
</div>
</div>
</div>
The problem is that in the div where the class is modal-header, the button comes before the h4 element. If those were switched, then this problem would be solved, but that is what I need help with. How would I do that via the bootbox syntax? I know I could just remove the title for now until bootbox becomes updated to support bootstrap 4, but I'm curious if this can be done.
Here is what I have so far:
bootbox.confirm({
className: "show", // where I had to manually add the class name
title: "Test Title?",
message: "Test Message",
buttons: {
cancel: {
label: "<i class='fa fa-times'></i> Cancel"
},
confirm: {
label: "<i class='fa fa-check'></i> Confirm"
}
},
callback: function (result) {
// my callback function
}
});
You can just resolve it by css:
.bootbox .modal-header{
display: block;
}
it can be fixed with:
.bootbox .modal-header {
flex-direction: row-reverse;
}
To fix this, you just reverse the positions (in the HTML) of the headline and the x like so:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div tabindex="-1" class="bootbox modal fade show in" role="dialog" style="display: block;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Test Title?</h4>
<button class="bootbox-close-button close" aria-hidden="true" type="button" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="bootbox-body">Test Message</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button" data-bb-handler="cancel"><i class="fa fa-times"></i> Cancel</button>
<button class="btn btn-primary" type="button" data-bb-handler="confirm"><i class="fa fa-check"></i> Confirm</button>
</div>
</div>
</div>
</div>
When searching for closeButton here: https://raw.githubusercontent.com/makeusabrew/bootbox/master/bootbox.js things do a little bit hard-coded to me.
However, if you change
dialog.find(".modal-header").prepend(closeButton);
to:
dialog.find(".modal-header").append(closeButton);
in that file, the problem should be fixed.
EDIT:
Actually, there's also dialog.find(".modal-title").html(options.title);
So, you need to append the closeButton to the title. Then it's gonna work as expected.
If people stumble upon this there is a now a version of bootbox 5 which supports bootstrap 4. You can find it here https://www.nuget.org/packages/Bootbox.JS/5.0.0-beta
Perhaps you can re-order the dom in the bootbox callback function, like:
bootbox.confirm({
...
callback: function () {
$('.modal-header').prepend('.modal-title');
}
});
here is what i've done and it worked:
go to your js file (mine is bootbox.min.js), find this line :
var m=b(n.closeButton);a.title?d.find(".modal-header").prepend(m)
and change it for:
var m=b(n.closeButton);a.title?d.find(".modal-header").append(m)
So you just need to change it for "append" and the closebutton should normally be on the right side.

Set focus on a input control contained in a second level bootstrap modal

I'm using Vue.js 2.1.10 and Bootstrap 3.3.7 to show a modal that opens another modal dialog. Each modal dialog is contained in a distinct component. Inside the 1st component, there is a reference to the 2nd component (select-travler).
According to the Bootsrap documentation, I have to set the focus by listening to the event shown.bs.modal. This works great to set the focus on an input control contained in the 1st modal. Problem: this way doesn't work when the modal is above another modal.
The 1st modal component looks like this:
<template>
<div ref="tripEdit" class="modal fade" role="dialog">
<!-- Inbeded component -->
<select-travler ref="selectTravler"></select-travler>
<!-- /Inbeded component -->
<div class="modal-lg modal-dialog">
<div class="modal-content">
<div class="modal-body container form-horizontal">
<div class="form-group">
<label for="travler_name" class="control-label">
Travler's name
</label>
<input id="travler_name" ref="travler_name"
v-model="travler_name"/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
travler_name: null,
}
},
methods: {
show (operationType) {
$(this.$refs.tripEdit).modal('show');
let that = this;
$(this.$refs.tripEdit).on('shown.bs.modal', function () {
$(that.$refs.travler_name).focus();
});
if (operationType === 'newTravel') {
this.$refs.selectTravler.show();
}
},
},
}
</script>
The 2nd component contains a similar layout with the following show method:
show () {
$(this.$refs.selectTravler).modal('show');
let that = this;
$(this.$refs.selectTravler).on('shown.bs.modal', function () {
$(that.$refs.people_names).focus();
});
},
When the 2nd modal opens, the focus is still on the 1st modal behind the 2nd modal dialog (I can see the caret blinking in travler_name). How can I set the focus on people_names when the 2nd modal is shown?
I think there are really several issues at play here. First, as I mentioned in the comment above, you are not properly adding and removing the shown.bs.modal event handlers.
Second, because your second modal is nested inside the first modal, the shown.bs.modal event will bubble up to the parent modal and it's handler will fire. Initially I thought stopPropagation would be a good way to handle this, but in the end, I simply de-nested the submodal component in the template.
Here is an example of this behavior actually working.
console.clear()
Vue.component("sub-modal", {
template: "#submodal",
methods: {
show() {
$(this.$el).modal("show")
},
onShown(event) {
console.log("submodal onshown")
this.$refs.input.focus()
}
},
mounted() {
$(this.$el).on("shown.bs.modal", this.onShown)
},
beforeDestroy() {
$(this.$el).off("shown.bs.modal", this.onShown)
}
})
Vue.component("modal", {
template: "#modal",
methods: {
show() {
$(this.$refs.modal).modal("show")
},
showSubModal() {
this.$refs.submodal.show()
},
onShown(event) {
console.log("parent")
this.$refs.input.focus()
}
},
mounted() {
$(this.$refs.modal).on("shown.bs.modal", this.onShown)
},
beforeDestroy() {
$(this.$refs.modal).off("shown.bs.modal", this.onShown)
}
})
new Vue({
el: "#app",
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="app">
<modal ref="modal"></modal>
<button #click="$refs.modal.show()" class="btn">Show Modal</button>
</div>
<template id="submodal">
<div class="modal fade" tabindex="-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">
<input ref="input" type="text" class="form-control">
</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><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<template id="modal">
<div>
<div ref="modal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" 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">
Stuff
<input ref="input" type="text" class="form-control">
</div>
<div class="modal-footer">
<button #click="showSubModal" type="button" class="btn btn-primary">Show Sub Modal</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<sub-modal ref="submodal"></sub-modal>
</div>
</template>
Also, for future readers, I got some useful information about how to construct the template for the modal component used above from this answer. Specifically, unless you manually specify a z-index for the modal, the modal that appears last in HTML will have a higher z-index. The implication being the submodal component needs to come second in the template.
I ran into a similar issue. A b-modal forces focus to stay in the modal. You can disable it by adding a no-enforce-focus attribute.
no-enforce-focus Boolean false Disables the enforce focus routine
which maintains focus inside the modal
https://bootstrap-vue.org/docs/components/modal
This means that the element you're trying to focus is not properly referenced.
Trying to console.log(element); the line before focussing people_names. To see if you're getting the right element.
show () {
$(this.$refs.selectTravler).modal('show');
let element = this.$refs.people_names;
$(this.$refs.selectTravler).on('shown.bs.modal', function () {
$(element).focus();
});
},
Have you considered v-show to open and close your modals ?

How to show a modal dialog using bootstrap

Earlier i was using a jquery dialog to show a pop-up message. However I need to use boostarp for my project and I am not able to figure out a way to actually show the pop-up.
The code that i used for my jquery dialog:
showUserWarningMessage: function (title, message, callback, scope, username) {
var $dialog = $("#dialog-move-user-warning");
$dialog.dialog({
resizable: false,
height: 450,
width: 580,
modal: true,
top: 200,
dialogClass: "warning-dialog",
title: title,
position: ["center", 200],
open: function () {
$dialog.find(".btn-default").on("click", function () {
$dialog.dialog("close");
});
$dialog.find(".btn-primary").on("click", function () {
$dialog.dialog("close");
if (callback) {
if (scope) {
callback.call(scope);
} else {
callback();
}
}
});
},
And he code im writing for bootstrap modal:
showAlertMessage: function(options) {
var $dialog = $("#dialog-move-user-warning");
$dialog.modal("show");
}
HTML:
<div class="modal fade" id="dialog-move-user-warning" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">User Info</h4>
</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>
For some reason its not displaying anything on the screen, though the background gets disabled as though there is an overlay popped, but can see it. i tried changing the defaults set for the class="modal", but it didnt help.
What im i doing wrong, or anything additional needed for the overlay to display?
is there any css that i need to change?
Thanks in advance!
Below are multiple ways opening modal dialog using bootstrap
Method 1: Open modal window using javascript
$("#myModal").modal('show');
Method 2:
<button (click)="deleteStudent(item.student_id)" class='btn btn-danger'>Delete</button>
Method 3:
<button class='btn btn-success' data-toggle="modal" data-target="#myModalMore">Open</button>
Method 4:
<button href="#mypop" class="btn btn-success" data-backdrop="false" data-toggle="modal">Open Modal</button>
<div id="mypop" class="modal fade">
//modal code here
</div>
If you want to show a modal using Bootstrap, why don't you use Bootstrap?
1. Add the modal html to your page.
The modal html you've provided is valid, if you are not certain, you can find the exact code and more examples here: http://getbootstrap.com/javascript/#modals-examples
2. Add a trigger to your page.
Data-target should be equal to your modal ID, which is #dialog-move-user-warning in your case.
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
3. Make sure you have bootstrap.js and bootstrap.css included on your website.
The Bootstrap modal relies heavily on bootstrap.js. You don't need everything, what you will find in the JSFiddle below is just enough.
http://jsfiddle.net/fgxmcnd2/3/

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