Bootstrap-datepicker: Datepicker inside a modal window causes modal to close

Created on 22 Apr 2012  路  27Comments  路  Source: uxsolutions/bootstrap-datepicker

I've got a couple of datepicker input fields inside a form that is displayed within a Bootstrap modal window. When I select a date using the datepicker the modal window closes.

This is happening due to the trigger that gets executed on line 146:

https://github.com/eternicode/bootstrap-datepicker/blob/fd9eb6bb7e9a9785f960b3ff98aac105df5e3d32/js/bootstrap-datepicker.js#L146

When I comment out that trigger the datepicker still works fine.

Any thoughts as to what that trigger is for and how to make it work nice inside a modal window?

Scott

Most helpful comment

I know the post is a bit old but if it can helps, here's what I've done to fix it :

$('.datepicker').datepicker().on('changeDate', function(ev) {
    // YOUR CODE
}).on('hide', function(event) {
    event.preventDefault();
    event.stopPropagation();
});

All 27 comments

Hm, an interesting problem.

If you check out the bootstrap js philosophy, you'll see their policy on events is:

All events should have an infinitive and past participle form. The infinitive is fired just before an action takes place, the past participle on completion of the action.

show | shown
hide | hidden

These events (listed above) are what datepicker uses. Of course, these same events are what bootstrap-modal uses, too. Thus the conflict: datepicker signals that it's closing with the hide event, this event bubbles up the DOM to the modal ancestor, and the modal sees it as a programmatic command to close itself.

Currently, I see this as a bug in bootstrap-modal -- since a modal can have arbitrary DOM content (and thus arbitrary events fired from within it), it should likely be checking that the event is being triggered on it, rather than its contents (for example, with e.currentTarget).

I'll do some more investigation, but I doubt there's a way to fix this from within datepicker. You may be able to fix it by keeping the event from bubbling, if possible, but that may have unwanted side effects -- for example, if you're using .live to listen to the events.

@scottharvey I've looked at it, and can't replicate it. I took a look at the bootstrap-modal v2.0.2 source again, and it looks like it only ever triggers the hide event, it doesn't listen to it. Can you build a jsfiddle to demonstrate what you're seeing?

@eternicode after much stepping through code I finally found that I had defined a custom event listener that was removing the modal when the 'hide' event was triggered.

As that event is bubbling from the datepicker the modal was being removed, argh!

Sorry for the hassle and thanks for the great work on this plugin.

Scott

i have the same problem here. It's because im trapping the "hide" event and do something with it. How have you solved the problem to only trap the "modal hide" event?

here's my code

$('#modalForm').on('show', function (e)
{
    // do something
}).on("hide", function (e)
{
    $(".modal-body", this).empty();
});

adding namespace to events can solve the problem, but it breaks compability.

this.element.trigger({
    type: 'hide.datepicker',
    date: this.date
});

@vitalets does it? I'm under the impression that namespaced events can be listened to with or without the namespace. ie, .on('hide.datepicker', ...) and .on('hide', ...) would both catch the hide.datepicker event when triggered.

I've never actually used namespaced events before, so I don't know for sure.

@eternicode I was also under the same view, but recently checked that it is not.
may be it depends on jquery version, but on current 1.8.2 this works for me (no handler triggered)

$('#submit').on('hide', function(){
      console.log(this);
});

$('#submit').trigger('hide.my');

Huh. Well, that's mildly disappointing.

I see, it's vice-versa -- listening to hide would only catch a hide event, and not hide.my, while listening to hide.my would catch both.

Naturally, though, hide seems to be the one event that bootstrap-modal doesn't namespace.

what i've done to make it work without touching the code in the javascript file is this to check where the event come from. I would prefer to catch events with the namespace hide.modal but for now, i think i will go that way:

$('#modalForm').on('show', function (e)
{
    if (e.target === this)
    {
        // do something
    }
}).on("hide", function (e)
{
    if (e.target === this)
    {
        $(".modal-body", this).empty();
    }
});

For further references there is a discussion on this at bootstrap.

https://github.com/twitter/bootstrap/issues/3936

I know the post is a bit old but if it can helps, here's what I've done to fix it :

$('.datepicker').datepicker().on('changeDate', function(ev) {
    // YOUR CODE
}).on('hide', function(event) {
    event.preventDefault();
    event.stopPropagation();
});

@Kingroys Thank you! That solved my problem.

T
Thanks, It resolved my problem

@Kingroys .. thanks, it works fine. This soultion really makes sense.

@Kingroys Thank you.

@Kingroys Thank you! That solved my problem in 2017!!..

$('.date2').datepicker('show')
$('.date2').datepicker('hide');

this code calling modal bootstrap hide!!

i changed this section in datepicker js file as following (adding .picker before hide() ) :
[$(document), {
mousedown: $.proxy(function(e){
// Clicked outside the datepicker, hide it
if (!(
this.element.is(e.target) ||
this.element.find(e.target).length ||
this.picker.is(e.target) ||
this.picker.find(e.target).length ||
this.isInline
)){
this.picker.hide();
}
}, this)
}]

I was fighting with this big time with a modal and bootstrap datepicker clearing my input fields. Thanks to a friend who pointed me to this issue it solved my problem.

@Kingroys Thanks man. That helped me out!

This still working on 2019 @Kingroys thanks a lot bro.

@mateusmx Glad if I can help :)

I know the post is a bit old but if it can helps, here's what I've done to fix it :

$('.datepicker').datepicker().on('changeDate', function(ev) {
  // YOUR CODE
}).on('hide', function(event) {
  event.preventDefault();
  event.stopPropagation();
});

Thank you so much. That solved my a day problem.

sanjeevkse would that work for antd design picker because i have same problem in my model

You should try but I guess it'll work

Kingroys I am working in react and i am new in react so i donot know how to impleement it .
this is my Datepicker compoenet
className="inputcomponent_input"
onChange={(e,a,b)=>this.handleDatePicker(e,a,b,item.name)} />

This is handleDatePicker Method

handleDatePicker = (e,date,dateString,name) =>{
// console.log('handlePicker',e,date,dateString,name)
const event = window.event;
//console.log('handlePicker',event.view.onfocus)

this.setState({
  data:{
    ...this.state.data,
    [name]:dateString
  }
},
() =>{
//  console.log('handlePicker', this.state)
}
)

}

every time when clicks on it it closes the my reactstrap model.

This fix was made for jQuery. Not sure it's gonna work in your specific case. :(

Was this page helpful?
0 / 5 - 0 ratings