I am using bootstrap-datepicker and would like to show the date-picker on the modal of bootstrap 2. The problem I got is the date-picker is not scrolling accordingly when scrolling the modal, it is still remained.
The code:
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">Launch Modal</button>
<div id="myModal" class="modal hide fade" style="height: 400px; overflow: scroll">
<div style="height:300px"></div>
<div>Choose Date:
<input class="calendar" />
</div>
<div style="height:300px"></div>
</div>
and javascript:
var datePicker = $(".calendar").datepicker({});
The jsfiddler: http://jsfiddle.net/csrA5/
Is there any solution to make it scroll when scrolling the modal?
There is option datepicker('place') to update position . I have updated jsfiddle
var datePicker = $(".calendar").datepicker({});
var t ;
$( document ).on(
'DOMMouseScroll mousewheel scroll',
'#myModal',
function(){
window.clearTimeout( t );
t = window.setTimeout( function(){
$('.calendar').datepicker('place')
}, 100 );
}
);
Here is another way using jQuery
var checkout = $(".calendar").datepicker({});
$( "#myModal" ).scroll(function() {
$('.calendar').datepicker('place')
});
Try to add the event scroll in bootstrap-datepicker.js, in function "Datepicker.prototype"
[$(window), {
resize: $.proxy(this.place, this),
scroll: $.proxy(this.place, this)
}]
I dont know why, but positioning is based on scrolling so you need to find this code in bootstrap-datepicker.js
scrollTop = $(this.o.container).scrollTop();
and rewrite it to
scrollTop = 0;
This helped me, i hope it will help another people.
Solution provided by rab works but still not perfect as the datepicker flickers on scroll of bootstrap modal. So I used the jquery's scroll event to achieve smooth position change of datepicker.
Here's my code:
$( document ).scroll(function(){
$('#modal .datepicker').datepicker('place'); //#modal is the id of the modal
});
I too faced the same issue while using bootstrap datepicker in my project. I used an alternate method where in i created a hidden transparent layer inside the datepicker template inside bootstrap-datepicker.js (with classname 'hidden-layer-datepicker') and gave fixed position and occupying full height and width of the html.
DPGlobal.template = '<div class="datepicker">'+ '<span class="hidden-layer-datepicker"></span><div class="datepicker-days">
Now when the datepicker modal pops up, the newly created layer will occupy the entire page width and height and when the user scrolls since the modal is appended to body, the datepicker modal too scrolls with it. With the introduction of the new layer, the inner scroll of the container in which the datepicker input field is present, will be negated while the modal is open.
One more thing to do is to update the datepicker modal closing event when clicking on the hidden layer and that is done using the below code inside bootstrap-datepicker.js.
// Clicked outside the datepicker, hide it
if (!(
this.element.is(e.target) ||
(this.picker.find(e.target).length && e.target.className != "hidden-layer-datepicker") ||
this.picker.is(e.target) ||
this.picker.find(e.target).length
)){
this.hide();
}
I ran into this problem aswell with Stefan Petre's version of Bootstrap-datepicker (https://www.eyecon.ro/bootstrap-datepicker), the issue is the Datepicker element is attached to the body which means it will scroll with the body, fine in most cases but when you have a scrollable modal you need to attach the Datepicker to the scrollable modal's div instead, so my fix was to change Stefan's bootstrap-datepicker.js as follows -
line 28, change
.appendTo('body')
to
.appendTo(element.offsetParent)
and line 153, change
var offset = this.component ? this.component.offset() : this.element.offset();
to
var offset = this.component ? this.component.position() : this.element.position();
Early tests shows it scrolls perfectly.
In addition you may need to change the z-order of the Datepicker element to make it sit above the modal (this was my initial fix which did not deal with scrolling, I have not backed this change out yet so dont know if its still needed)
I haven'y checked but I suspect the Github version of Bootstrap-datepicker.js is doing the same thing (the sourcecode is much different to what I have from Stefan though)
Related
Need advice on this weird bug. I can't really explain it well, but here's an image.
What is supposed to happen is that when the calendar is shown, those stripes denote that the user is unable to add any events unless they fill in the Location and Practitioner fields first.
FullCalendar is able to get the events but I have to resize the page to a smaller width for the events to show up correctly. After you resize the calendar works fine.
The cause of this seems to be because the parent div is hidden initially and after a button is pressed the calendar is shown.
The code looks like this:
HTML:
<button v-on:click="renderCalendar('new')">Show Calendar</button>
<div v-show="calendar_mode !== null">
<FullCalendar ref="fullCalendar" defaultView="timeGridWeek" ....></FullCalendar>
</div>
JS:
renderCalendar(type) {
this.calendar_mode = type;
this.$nextTick(() => {
console.log("rerendering")
let calendarApi = this.$refs.fullCalendar.getApi()
calendarApi.render();
calendarApi.rerenderEvents()
});
},
I've thought of using 'visibility' instead but the parent of this component also uses display:none;
Any help with this would be much appreciated!
I have implemented bootstrap dialog in my project. I have some delete functionality in that dialog, and the delete confirmation message opens another bootstrap dialog. But when the second confirmation dialog is open, the first dialog is not disabled and all the events work.
Is there any solution to disable the original dialog when another dialog opens?
Here's my code:
function OpenDialogForSelectionAdmItem(title, content, callback) {
var dlg = new BootstrapDialog({
title: title,
content: content,
buttons: [{
label: 'Save',
cssClass: 'btn-primary',
id: 'btnSave',
onclick: function (dialog) {
}
},
{
label: 'Close',
cssClass: 'btn',
id: 'btnClose',
onclick: function (dialog) {
if (callback != "") {
callback(true);
}
dialog.close();
}
}]
});
dlg.open();`
}
Screenshot:
When the dialog for delete confirmation is open, I want to disable the first dialog.
The Problem:
In order to understand the intricacies of modal dialogs in web development, you'll need to understand a bit more about the z-index property and stacking contexts.
In short, the dialog works by adding two principal components to the DOM: a background that takes up the entire screen, and a div comprising your dialog. Each of those stand out from the rest of the page because they are put at the the root level of the DOM and given a high value for their z-index property. How high? Well, try adding a blank modal to a blank page and you'll see the following DOM elements:
<div class="modal-backdrop fade in"></div> <!-- z-index: 1030; -->
<div class="modal bootstrap-dialog"> <!-- z-index: 1040; -->
<div class="modal-dialog"> <!-- z-index: 1050; -->
The modal-backdrop gives the illusion of a true modal process because it renders above all the other content which prevents clicks from firing anywhere below. The only reason the modal-dialog is allowed to receive clicks is because it is stacked on top of the background, by providing a higher z-index.
That's it! That's the whole bag of tricks. So when bootstrap cautions against use multiple dialogs, they're doing so because stacking becomes tricky. If you add another element, it gets rendered with the same exact z-index, meaning that it will be above the regular page content, but on the same plane as the original dialog. If it doesn't completely cover the original, then the original will still be clickable because there is no backdrop above it.
The Solution:
In order to resolve this, you need to come up with your own way of disabling clicks on background modals. This issue appears to have been (partially) resolved. See the following example:
Demo in jsFiddle
Bootstrap Dialog made it so that clicking off of a dialog simply closes the last dialog in the DOM and marks the event as handled so it won't fire anything else. If the second modal is up and you click off of it, the only thing that will happen is the second modal will close.
More Advanced Handling:
If you want the second modal to look like it's over the first one, you'll have to do that manually.
When the new modal is created, it comes with it's own modal-backdrop. When the second modal is shown, you can have it appear above the original by incrementing its z-index relative to the first modal. In the onshown event, we just have to grab the current modal and it's overlay and modify the z-index using the .CSS method. We want this to appear above any existing modals, so first we'll count the number of modals in the DOM ($('.bootstrap-dialog').length) and then increment the z-index so it's higher than the next highest dialog.
Call like this:
function OpenDialogForSelectionAdmItem(title, content, callback) {
var dlg = new BootstrapDialog({
title: title,
message: content,
onshown: function(dialog) {
var tier = $('.bootstrap-dialog').length - 1;
dialog.$modal.prev(".modal-backdrop")
.css("z-index", 1030 + tier * 30);
dialog.$modal
.css("z-index", 1040 + tier * 30);
}
// More Settings
}).open();
}
Working Demo in jsFiddle
Screenshot:
As a proof of concept, here's a Demo that allows you to continually add dialogs on top of other dialogs
Infinite Dialogs Fiddle
UX Caution:
While this is technically possible to achieve, modals within modals can create a confusing UX, so the right answer if you have the problem might be to try to avoid it altogether by taking the original workflow and promoting it to a full page design with a url and state.
First add class to primary modal so:<div class="modal-content kk">
I simply use:
$('#myModal1').on('shown.bs.modal', function () {
$('.kk').addClass('magla');
$('#myModal').modal('hide');
});
$('#myModal1').on('hidden.bs.modal', function () {
$('.kk').removeClass('magla');
$('#myModal').modal('show');
});
where .magla css is:
.magla {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-o-filter: blur(5px);
-ms-filter: blur(5px);
filter: blur(5px);
}
Try looks good for me.
Just hide the actual modal using the onclick method
<button data-toggle="modal" data-target="#modal-to-show-id" onclick="$('#actual-modal-id').modal('hide');">
Text Button
</button>
My humble solution: Generate a new ID for each new modal. Then just manage everything through one variable.
It's working for my purposes, btw.
var _MODAL_LAST;
$( document ).on( 'show.bs.modal' , '.modal' , function(){
_MODAL_LAST = $(this);
});
$( document ).on( 'hide.bs.modal' , '.modal' , function(){
if( _MODAL_LAST.attr('id') !== $(this).attr('id') ){
return false;
}else{
_MODAL_LAST = $(this).prevAll('.modal:first');
}
});
Having this issue with multiple items (e.g. a color picker, date picker, and a time picker) where when they pop out and are thus positioned absolute relative to the input, if a user scrolls the newly spawned element also moves with it.
Based on the nature of most plugins (all major bootstrap plugins I've noticed do this) I'm trying to think of a way to target and keep these elements fixed relative to their original location without hacking every plugin if possible.
Below is an example of the issue in which I utilized the bootstrap datepicker. Click on input to spawn datepicker and then scroll and notice the datepicker staying relative to the screen not the input.
Link to JSFiddle: http://jsfiddle.net/GuJR6/1/
Thanks!
.container {
margin-top: 15px;
height:400px;
overflow-y: scroll;
}
.scrolling-content {
height:1000px;
}
<div class="container">
<div class="scrolling-content">
<div class="well text-center">
<input type="text" class="datetimepicker" readonly>
</div>
</div>
</div>
$(".datetimepicker").datetimepicker({format: 'yyyy-mm-dd hh:ii'});
I just forked bootstrap-datetimepicker and added the container option mention by Jan Peapke. You can use it like this:
$(selector).datetimepicker({ container: nativeDOMElement });
$(selector).datetimepicker({ container: jQueryObject });
$(selector).datetimepicker({ container: jQuerySelector });
This allows you to solve your problem:
In your css:
.scrolling-content {
position: relative;
}
Compare: CSS-Tricks
js
$(".datetimepicker").datetimepicker({
format: 'yyyy-mm-dd hh:ii',
container: '.scrolling-content'
});
Fiddle
http://jsfiddle.net/marionebl/GuJR6/2/
The first input in the fiddle applies the explained fix for your issue. The second should behave like before.
Related pull request
https://github.com/smalot/bootstrap-datetimepicker/pull/215
I'm afraid the problem lies with the bootstrap datetimepicker itself.
Instead of attaching it to the same container as the input, it is attached to the body.
I looked up the documentation to see if there is an option to set the parent, but I'm afraid there is not.
As a solution you could try another framework, like jQueryUI or this plugin.
You could also try to correct the position of the picker manually by attaching a click handler to the input field that removes the datepicker from the body, adds it to the content of the scrollcontainer and uses the events mouse coordinates to position it correctly inside the container. Seems like a lot of hassle though. :)
regards,
J
$('YOURCLASSNAME').on('scroll', function () {
var $this = $('.input-group.date');
$this.datepicker('place');
});
Add above code before
Datepicker.prototype = {...}
This is the solution. and works fine on all devices and screen sizes
Even i have been facing this issue.
Found out a solution to this By adding var t;
$('YOURCLASSNAME').on('scroll', function () {
var $this = $('.input-group.date');
window.clearTimeout(t);
t = window.setTimeout(function () {
$this.datepicker('place');
}, 50)
});
Add above code after if (showFocus) this.show();
in this block
var Datepicker = function (element, options) {....} of bootstrap-datepicker.js plugin
I have a complex search form that I want to hide by default on mobile browsers, instead displaying an icon in the navbar that toggles its display.
The div containing the search form is hidden by default on mobiles using class="hidden-xs"
What I wanted to do was have $("#search").fadeToggle() but this doesn't do the trick, in fact it doesn't appear to do anything.
Instead I am partly there by using $("#search").removeClass('hidden-xs') but this obviously doesn't toggle, or give a fade effect. Am I missing something obvious? The search form is quite complex and I do not want it to be displayed in the navbar even on large screens.
jsfiddle - http://jsfiddle.net/ZNUBx/1/
You can do it with this :
fiddle : http://jsfiddle.net/ZNUBx/2/
JS :
$("#search-button").click( function(){
$("#search").removeClass('hidden-xs').stop().hide().fadeIn();
});
Update: [asker demand][see comment] with hide event
jsfiddle : http://jsfiddle.net/ZNUBx/3
Js:
$("#search-button").on('click', function(){
if( $("#search").hasClass('hidden-xs') )
{
$("#search").removeClass('hidden-xs').hide().fadeToggle();
} else {
$("#search").addClass('hidden-xs');
}
});
I have a button that has been binded to a popover. I would like to hide the popover when someone clicks on one of the smilies in the popover. However, $("#smiley").popover('hide') does not work.
Unfortunately I haven't been able to reproduce this with barebones code - it only happens on the live site, which is https://coinchat.org
Relevant code:
$("#smiley").popover({html: true, trigger: 'click', placement: 'top', content: smileyContent, title: 'Smilies'});
Later in a function..
$("#smiley").popover('hide'); // not working
In https://inputs.io/js/buttons.js the jQuery plugin jQuery.fn.popover is overwritten on a load event of some kind, so $("#smiley").popover("hide") at that point is no longer calling into bootstrap but the plugin provided by inputs.io.
A snippet of the code:
Inputsio.load = function(){
(function(){(function(e){return e.fn.popover=function(t)
The usage of jQuery plugin namespace for application specific code is extremely distasteful indeed.
A temporary fix could be $("#smiley").click()
here is a working fiddle that is "similar" to your code
http://jsfiddle.net/6hkkk/7/
HTML
<div style="margin-top:100px">
<span id="smiley" data-title="smile" data-toggle="clickover">
<i class="icon-comment"></i>
</span>
</div>
javascript
ClosePop = function () {
$('#smiley').popover('hide');
}
var elem = '<button data-toggle="clickover" class="btn" onclick="ClosePop();"><i class="icon-off"></i></button>';
$('#smiley').popover({
animation: true,
content: elem,
html: true
});
Replace
$("#smiley").popover('hide');
with
$("#smiley").click();
Works for me in the console.
try to move id="smiley" from
<span class="btn tenpx smileypopover popover-trigger" id="smiley" data-original-title="" title="">
to
<div class="popover fade top in" style="top: 430px; left: 308.5px; display: block;">
Is something like this out of the question?
$('#smileylist a').click(function(){
if($('.popover').css('display','block')){
$(this).css('display','none');
}
});
$('.smileypopover').click(function(){
if ($('.popover').css('display','none')){
$(this).css('display','block');
}
});
When I click on the smiley face it closes the popover, then I can't open it again until I run the 2nd block of code. It's very close but I'm not sure exactly what I'm missing.
If you have a selector property (e.g., usually required for dynamic HTML content) in your popover options, be sure to use the same selector when calling the 'hide' method.
The following fails to hide popovers (for new content added to the DOM).
//enable popover
$(document).popover({
html: true,
selector: "[data-popover]"
});
//attempt to hide popover
$(document).popover('hide');
Instead, use this:
//enable popover
$(document).popover({
html: true,
selector: "[data-popover]"
});
// hide popover
$('[data-popover]').popover('hide');
Bootstrap cannot reach indepentently popover id's. We have to read aria-describedby attribute related with the element.
Code below is solves your issue:
$("#"+$(relatedElementId).attr("aria-describedby")).remove();
relatedElementId: popover's associated element
In the addSmiley function you could replace the
$("#smiley").popover('hide');
with
$(".popover").hide();
It would work , but don't know if it is ok for you.