Bootstrap (actually JQuery) DatePicker does not hide on blur in Wicket modal
Asked Answered
O

2

17

I have a wicket bootstrap DateTextField on a panel inside modal. When datepicker is shown from click, datepicker is attached to the root page, not the modal.

That causes a problem: without adding some z-index to datepicker, I cannot see it on top of modal.

When I blur from the picker, it should close. Somehow, due the fact the picker is not child of modal, clicking outside datepicker closes it only, if it is clicked outside the modal. Inside modal nothing happens.

I can tweak this by autoclose, but when you go to input and manually use backSpace to clear the value, there is no a way to close datepicker by clicking somewhere inside the modal.

Some html to make it clear:

 <html>
   <panel>
     <modal>
       <input>datefield is here</input>
     </modal>
   <panel>
   <datepicker comes here>
 </html>

How to get datepicker attached to modal, or somehow else fix the issue of blur inside the modal?

I have tried to attach the panel a click event that hides datepicker, but it hides the datepicker right away when it opens.

Edit:

Click to modal does nothing, although html is moved artificially there and is placed correctly in DOM tree. Thanks to @Gavriel about insight to moving stuff between DOM elements, though.

Edit2:

Code to reproduce situation:

class MyPanel extends Panel {
    DateTextField field = new DateTextField("foo");
    (...)
    add(field);   
}

class MyPage extends WebPage {
     (...)
     ModalWindow modal = new ModalWindow("modal");
     modal.add(new MyPanel());
     (...)
}

html for the panel, containing the dateTextField

<html>
   ..
   <input wicket:id="foo"></input>
   ..
</html>

As you see from snippet, java code generates the jQuery part.

Edit3:

I speak about this creature:

[DateTextField sources] https://github.com/l0rdn1kk0n/wicket-bootstrap/blob/master/bootstrap-extensions/src/main/java/de/agilecoders/wicket/extensions/markup/html/bootstrap/form/DateTextField.java

Edit4:

Hmm.. I added in Javascript a blur event listener inside the input in modal and that blur even did not work. So it turns out that the real question in hand is how to get onblur work inside modal. Because that is what is broken!!

Edit5:

Sorry, cannot give fiddle. From Edit3 you see sources I use for picker and what I really call is this function:

protected CharSequence createScript(final DateTextFieldConfig config) {
    return $(this).chain("datepicker", config).get();
}

which is inside java class, so not JavaScript at all although syntax is looking so similar. For my understanding fiddles take no java code inside them. Wicket needs the java part, I am sorry about it.

For fiddle askers I found similar situation on this fiddle: http://jsfiddle.net/VytfY/227/ - works 100% ok, similar technologies I mention here, no use to my problem.

Last edit:

$('html').on('click',function(e){
        if(e.target.className.indexOf('datepicker') == -1 && 
           e.target.className != 'next' && e.target.className != 'prev' && 
           e.target.className != 'year' && e.target.className != 'month'){
            if ($('.datepicker').get(0) != undefined){
                $('.datepicker').get(0).remove();
            }
        }
     });

Thanks @Mathew you made my day, above is what it ended to be. I added to input element a class datepickerContainer so clicking it does not hide picker.

Thanks folks, this is done!

One more: for IE, use:

 var canvas =  $('.datepicker').get(0);
 canvas.parentNode.removeChild(canvas);

instead of direct remove. Remove not yet supported, even IE11.

Oneeyed answered 26/1, 2016 at 7:6 Comment(4)
I'm not 100% sure this will work but try api.jqueryui.com/datepicker/#option-beforeShow . To get the idea: #6833122 Try to move the inst (2nd argument) in the DOM.Cristiano
@Gavriel: I don't quite get how I move the element inside DOM to another place? Could you elaborate more in form of an answer?Oneeyed
When you append an element to the DOM that was already inside the DOM, it is removed from the original place, in other words if you use $("#dst").append("#src"), then src element is moved to dstCristiano
Looking for new ideas: changing DOM did not save the situation.Oneeyed
P
1

   
$("#button").on('click', function(){
     var dt=$("#datepicker").show();
     dt.datepicker().on('change', function (ev) {
          $(dt).hide();
    });
   $('html').on('click',function(e){
         if(e.target.id !='button'){
               $(dt).hide();
           }
      });
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button id="button">choose date</button>
<div id="datepicker"></div>
<div>footer</div>
Pilarpilaster answered 4/2, 2016 at 6:0 Comment(3)
Well, hide on choose is working well on my current solution. What is not working is blur which means when you click outside the element and the picker should disappear. Blur works ok, if you click outside the modal, but inside modal not.Oneeyed
What I started thinking here is, that if I cannot rely on a datepicker coming through java code, a possibility is I could launch jquery datepicker manually from html/javascript. We have several pickers in the app, changing to different looking one is not a good thing, so I would wait still for a java way, if there is one.Oneeyed
I modified your script a little:$('html').on('click',function(e){ if(e.target.id != none of datepicker elements){ $(dt).remove(); } }); and it worked. I comment more on my question post.Oneeyed
C
2

The idea is to move the div created by datepicker.

Use http://api.jqueryui.com/datepicker/#option-beforeShow You can see an example how it is used in a slightly different use case: How to add a custom class to my JQuery UI Datepicker

When you append an element to the DOM that was already inside the DOM, it is removed from the original place, in other words if you use $("#dst").append("#src"), then src element is moved to dst.

Update: I think there's a more straightforward way: You provide the id of the div you want it to use. This way you can have this div inside your modal dialog.

     
$("#button").on('click', function(){
    $("#datepicker").datepicker();
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button id="button">choose date</button>
<div id="datepicker"></div>
<div>footer</div>
Cristiano answered 27/1, 2016 at 11:30 Comment(9)
This kind of works, I can tell in debugger the element in correct div. Still what is not working is how to call the javascript from wicket? I tried to attach script to renderHead but it painted the picker immediatedly, before user clicks.Oneeyed
My java element in wicket gives the datepicker html without possibility to use your update, but the original append made it and when inside modal I needed some css to place it exactly in correct place. Thanks, I'll accept this answer!Oneeyed
Well, I was too early accepting. The initial problem of onBlur not happening when click is inside modal is still there. I quessed it would be solved this way, but it was not.Oneeyed
Can you post a jsfiddle or snippet with the actual html, CSS, JavaScript? I should've ask it at the beginning...Cristiano
please set up a jsfiddle with your problemCristiano
I would wager that some sort of failure is taking place on the date selection, but not being reported. Possibly a date format issue. Are you able to make the datepicker work without using Boostrap (rather by using pure JQuery)?Unclear
@mico, can you set up a working jsfiddle? You're adding new information with your every comment, it would be much more efficient if we could see it.Cristiano
@Gavriel: Please show me fiddle with connection to java code (essential in Wicket) and I modify it to this purpose.Oneeyed
@Unclear : I looked on chrome dev tools to console while trying to blur and no error messages were shown there.Oneeyed
P
1

   
$("#button").on('click', function(){
     var dt=$("#datepicker").show();
     dt.datepicker().on('change', function (ev) {
          $(dt).hide();
    });
   $('html').on('click',function(e){
         if(e.target.id !='button'){
               $(dt).hide();
           }
      });
});
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<button id="button">choose date</button>
<div id="datepicker"></div>
<div>footer</div>
Pilarpilaster answered 4/2, 2016 at 6:0 Comment(3)
Well, hide on choose is working well on my current solution. What is not working is blur which means when you click outside the element and the picker should disappear. Blur works ok, if you click outside the modal, but inside modal not.Oneeyed
What I started thinking here is, that if I cannot rely on a datepicker coming through java code, a possibility is I could launch jquery datepicker manually from html/javascript. We have several pickers in the app, changing to different looking one is not a good thing, so I would wait still for a java way, if there is one.Oneeyed
I modified your script a little:$('html').on('click',function(e){ if(e.target.id != none of datepicker elements){ $(dt).remove(); } }); and it worked. I comment more on my question post.Oneeyed

© 2022 - 2024 — McMap. All rights reserved.