Wrong focus after closing a 2nd modal - javascript

I'm using vue.js 2 and bootsrap 3 to open a modal that opens a 2nd modal.
Few days ago, I asked a question on how to set a focus on a control contained in a 2nd modal. I got a great answer that solved the issue.
Problem
When opening the 1st modal, the user is able to scroll through it to see its bottom. But after opening and closing the 2nd modal, the focus moves to the page that contains the 1st modal. and when the user scrolls to see the rest of the 1st modal, he scrolls the page behind that 1st modal.
It is very uncomfortable to use especially when the modal is bigger than the screen height. Is there a way to prevent this?
To reproduce this issue, open the answer and click on "Expand snippet"

That work for me:
$('#my-modal').on('hidden.bs.modal', function () {
$('body').addClass('modal-open');
});

Here is a modified version of the previous answer that sets the focus back to the original modal after the sub modal is closed.
The change is here:
$(this.$refs.submodal.$el).on("hidden.bs.modal", this.onShown)
This is added in the mounted handler. It adds a handler to the hidden.bs.modal event of the sub modal. It also removes the handler when the component is destroyed.
Additionally, because closing a modal removes the modal-open class that is assigned to the body when a modal opens, the code below adds that class to the body whenever onShown is called so that the scroll is not affected for the parent modal.
$("body").addClass("modal-open")
Here is a working example.
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()
// Add the "modal-open" class back to the body in case
// it was removed by the sub modal
$("body").addClass("modal-open")
}
},
mounted() {
$(this.$refs.modal).on("shown.bs.modal", this.onShown)
$(this.$refs.submodal.$el).on("hidden.bs.modal", this.onShown)
},
beforeDestroy() {
$(this.$refs.modal).off("shown.bs.modal", this.onShown)
$(this.$refs.submodal.$el).on("hidden.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" style="height: 80vh">
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>

Related

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');

Add class to the body when modal is open

I'm having a problem with my login modals. One modal open when someone click forgot password link on my sign in the modal. (One modal open in another modal) So I came everything clean by adding all necessary attributes.
Eg:
<span data-toggle="modal" data-target="#forgot-pin-popup" data-dismiss="modal">Forgot password?</span>
But I notice it won't add .modal-open class to the body when my second modal is open(styles are shown weird without this class). So I manually use this js script.
$('.modal').on('hidden.bs.modal', function () {
if($('.modal').hasClass('in')) {
$('body').addClass('modal-open');
}
});
Works perfectly BUT when I try switching models like 6 times. It won't work again. Can't imagine why. I can't show you an example because it's on my production site. Does anyone face the similar problem like this?
Try to do using modal id
On modal show
$('#forgot-pin-popup').on("shown.bs.modal", function() {
$("body").addClass("modal-open");
});
On modal hide
$('#forgot-pin-popup').on("hide.bs.modal", function() {
$("body").addClass("modal-open");
});
what about using a global event listeners:
$(document).on('hidden.bs.modal', '.modal', function () {
$('body').toggleClass('modal-open', $('.modal').hasClass('in'));
});
Try to use body instead of .modal
$('body').on('hidden.bs.modal', function() {
if ($('.modal.in').length) {
$('body').addClass('modal-open');
}
});
Also make sure that your modal should not be nested into .modal class
$('body').on('hidden.bs.modal', function() {
if ($('.modal.in').length) {
$('body').addClass('modal-open');
}
});
$(".btn-primary").on("click", function() {
console.log($("body").attr("class"));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Open modal
</button>
<!-- 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-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-primary btn-lg" data-toggle="modal" data-target="#myModal1" data-dismiss="modal">
Open modal
</button>
</div>
</div>
</div>
</div>
<!-- Modal1 -->
<div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<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">Modal title</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>
</div>

Bootstrap modal from modal not showing

I am launching a modal off a modal and it isn't appearing over the first modal. My modals have events called when they are launched:
$("#noteModal").on("show.bs.modal", function (e) {
var link = $(e.relatedTarget);
$(this).find(".modal-body").load(link.attr("href"));
});
$("#notesModal").on("show.bs.modal", function (e) {
var link = $(e.relatedTarget);
$(this).find(".modal-body").load(link.attr("href"));
});
The modal fires fine but doesn't appear over the first modal. If i click anywhere on screen the second modal acts as if it disappears then the first modal is still shown.
I've tried doing hide / show on the first and second modal but that doesn't seem to work.
You could just use the hidden.bs.modal event on the first modal to show your second modal, while the button inside the first modal will hide the first modal on click.
Sounds stupid, i know, but here is an example.
This will not stack the modal windows on top of each other though.
If you want them to stack i would say you go with what Steve suggested in the comment.
And just for the record:
Modals modal.js
Multiple open modals not supported
Be sure not to open a modal while another is still visible. Showing more than one modal at a time requires custom code.
var $firstModal = $('#first-modal'),
$secondModal = $('#second-modal'),
$innerModalBtn = $firstModal.find('.btn-block');
$firstModal.on('hidden.bs.modal', function (e) {
$secondModal.modal('show');
})
$innerModalBtn.on('click', function() {
$firstModal.modal('hide');
})
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-8 col-md-offset-2">
<button type="button" type="button" class="btn btn-default btn-lg btn-block" data-toggle="modal" data-target="#first-modal">Open Modal</button>
</div>
</div>
</div>
<div id="first-modal" class="modal fade" tabindex="-1" role="dialog">
<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">First Modal</h4>
</div>
<div class="modal-body">
<button type="button" type="button" class="btn btn-default btn-lg btn-block">Open Second Modal</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div id="second-modal" class="modal fade" tabindex="-1" role="dialog">
<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">Second Modal</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>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->

Show/hide modal in Meteor

How can I show a bootstrap modal in Meteor?
From http://meteorpedia.com/read/Modals I can read that the Meteor-way is to use template logic to show/hide the modal.
I have tried adding the modal in my template with
<div class="modal fade">
<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>
<span class="sr-only">Close</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-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
and I have a variable showModal which determines whether the modal should be shown or not. But I don't know how to programmatically show/hide the modal.
Add an id to the modal
<div id="myModal" class="modal fade">
And use modal() to open the modal
$('#myModal').modal('show');
To close the modal
$('#myModal').modal('hide');
Docs
If you want to open the modal in Meteor way
In JS
Session.set('showModal', true); // Show modal
Session.set('showModal', false); // Hide modal
In Template
{{#if showModal}}
<div class="modal fade"> <!-- Use Display block to show the modal by default -->
...
{{/if}}
Make life easy on yourself and use a bootstrap meteor-modal package. I use this one and it works great meteor modal.

Advice on Modal BootStrap

I am working with boostrap latest version finally getting the hang of it and try to add another modal combined with the one i already have. Well no luck and got stuck. is there a way to add another modal that works together with the previous modal?
the reason why i wanted to try to get another modal in there to show off the twitch emotes plus commands they can use to make it easier for the user.
in other words another box on the right side (where its marked with a red box)
Screenshot: http://i.stack.imgur.com/bJduj.png
This is possible with setting a data-target for the same class instead of using href with an ID. You'll have to adjust the position of them depending on where you want to two and how big they are etc.
Open up the example to full-page and you'll see.
data-target=".myModals"
#myModal2 {
top: 40%;
outline: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<a data-toggle="modal" data-target=".myModals" class="btn btn-primary btn-lg">Launch Modals</a>
<div class="modal fade myModals" 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-hidden="true">×</button>
<h4 class="modal-title">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>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
<!-- Modal -->
<div class="modal fade myModals" id="myModal2" 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">Modal title 2</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>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
You can open a modal via JavaScript. Since you already have jQuery loaded, try something like this.
Assuming you have a modals with IDs of videoFeed and textFeed.
$( "#" ).bind( "click", function() {
$('#videoFeed').modal('toggle');
$('#textFeed').modal('toggle');
});

Categories