Wednesday, June 5, 2013

Datepickers in Bootstrap that are Contained in a Modal Window

The current version of Bootstrap amazingly does not contain a UI datepicker element.   There are ways around this of course.   Someone in Romania named Stefan Petre created a datepicker for bootstrap that is widely used.  Kudos to Stefan for filling that gap.

Mark Leusink of http://bootstrap4xpages.com has taken Stefan's Datapicker and created an xpages custom control.   This control is available here and the code for the custom control is here.   If you use this control, you will need to recreate the custom parameters by using this xsp-config file.   If you are not using the datepicker in a modal window, then this should work great for you.

Unfortunately for me, I tried for most of a day to get this working in my project but was unsuccessful.  The issue that I had was that the date window would not display correctly no matter what I tried.

Full calendar would not display
If you have read my last few posts, you will know that I am creating a responsive application in Bootstrap using a series of Modal Windows that act like a wizard.   These windows work nicely, even on an iPhone 4.   Being able to nicely add dates is essential in any screen size.   Initially I tried using the Dojo date text box control, and even the date time picker core control, but neither would work.   I then tried the Bootstrap datepicker after reading a recent blogpost by Karl-Henry Martinsson where he mentions it.

I could sort of get the Bootstap datepicker to work but had the following issues.
  • Clicking on the data icon would not work, but clicking in the field did work
  • The datepicker wouldn't work unless you clicked in the field, clicked out, and then back in
  • If you enter a value, then go back in again, the UI would mess up as shown in the screen print
  • The datepicker wouldn't close after selecting a value, you had to click outside the calendar to close it
Calendar messed up when re-editing date field
Here is how I went about fixing this mess.   
  1. I could never get the calendar icon button to click for entering the value.  I decided that I would just accept that you click in the field and get the calendar.   I think this works fine, even though I would have rather used a button.   The default is to highlight today's date which I like.
    The finished product
  2. To fix the 2nd and 3rd bullet point above I wrote the code as shown in the screen print.  This is because I discovered that $('.datepicker').datepicker('show'); caused it to open correctly the first time, but caused the UI to progressively mess up (see second screenprint) upon editing an existing value.   When I used $('.datepicker').datepicker(); then the UI acted normally, and since there was already a value in the field, it worked right away.  (I did not want a default value.)  This client side javascript code is in the onClick event of the <xp:inputText> tag. 
    This was the fix to get it to work
        3.   To get the calendar to close when selecting a value, I added a <xp:scriptBlock> containing:                    $('.datepicker').datepicker()
    .on('changeDate', function(ev){
    $('.datepicker').datepicker('hide');
     });

    The on('changeDate') method is part of the api.  There is a similar example on the Bootstrap Datepicker page.

      4.   Lastly, you will surely want to turn autocomplete="off".   For whatever reason, I was also unable to size the input field using the bootstrap value="input-small" .   Because of this, I set the width to using "em", which is a variable sizing measurement.   You wouldn't want to use pixels in this case.

    Note:  I didn't mention earlier, but you have to install the datepicker CSS and Javascript in your database first.   In you input field, you MUST set the style to "datepicker".

    Update:  To use more than one datepicker in a single modal window, wrap each in a <div> with a different id.   In the onClick event, reference the id in the jQuery selector.

    Conclusion:   This whole exercise was a big pain, but necessary.  If you are not using a Datepicker in a modal dialog then you are better off using Mark Leusink's custom control or just copy code from Stefan Petre's sight.  If you are using a modal dialog to display the calendar date then this will help you.   If you have any alternatives or questions, leave a comment.

    10 comments:

    1. I wrote a Bootstrap DatePicker and TimePicker just recently using Dojo and I had no problem with having to work with a modal dialog or not.

      ReplyDelete
    2. Thanks Richard. I didn't spend much time getting the dojo control to work. In hindsight, I think it was a z-index issue, as in it needed to be brought to the front. Love your blog, btw.

      ReplyDelete
    3. Another approach, which you can use if you have control over your users' browsers, is to simply use type="date" for your input control and let the browser take care of the rendering. This approach works in Chrome and Safari, but not Firefox and Internet Explorer. As the support for HTML 5 increases, this will probably be the best way to solve this and similar problems.

      ReplyDelete
    4. Thanks Saša, I am playing with the 'type' attribute now to make the right keyboard show on mobile. HTML5 is awesome, but I need this to still work on IE8 :( Thanks for the suggestion!

      ReplyDelete
    5. Thanks for posting your findings.
      If you set the autoclose option to true (by default is false) the calendar will close when selecting a value.

      $('.datepicker').datepicker({format: "dd/mm/yyyy", autoclose: true });


      ReplyDelete
    6. iam using datepicker in popup but is is now showing in popup instead behind popup its coming help me

      ReplyDelete
    7. //DATE PICKER
      $('.datepicker').datepicker().on('changeDate', function(ev) {
      //
      }).on('hide', function(event) {
      event.preventDefault();
      event.stopPropagation();
      });

      ReplyDelete
    8. thanks for article, now problem get solved

      ReplyDelete
    9. Thanks for sharing the information. I am searching for this for past months.

      ReplyDelete