Question

I am struggling to get a jquery datepicker to work within a custom polymer element. It seems to bind to the body instead of the element itself, for example:

<polymer-element
  name="test-datepicker">
  <template>
      <p>Date: <input type="text" id="dp"></p>
  </template>
</polymer-element>

with the definition:

Polymer('test-datepicker', {

    ready: function() {
        $(this.$.dp).datepicker();
    },
});

... results in the pop-up calendar displaying at the top of the page instead of under the input as it would otherwise, as you can see in the running example over at jsbin: http://jsbin.com/saqojihi/1/

I'm having similar issues with bootstrap tooltips not displaying if they overlap the edges of a web component, and I'm hoping these two are related.

Is there another way that I should be calling the datepicker? I've tried direct references, $("#id").datepicker(), but as it says in another ticket, jquery "doesn't know about ShadowDOM". I've also tried using the lightdom attribute to no avail.

I'm hoping someone has had success with this.

Edit: 4/4/14

Thanks to @Scott Miles for the suggestion, I've added the following override of JQuery.contains, but this probably still isn't the ideal solution:

$(function(){
  // Store a reference to the original contains method.
  var originalContains = jQuery.contains;
  jQuery.contains = function(parent, child){
      var re = /datepicker|dp/i;
      if(child.className.match(re)) {
        return true;
      }
      // Execute the original method.
      return originalContains.apply( this, arguments );
  }
});

It works for now, but I'll have to see how it plays out in a more complete app.

Was it helpful?

Solution

In this particular case, the problem boils down to the notion of what document.contains returns wrt elements in ShadowDOM (https://www.w3.org/Bugs/Public/show_bug.cgi?id=22141).

The datepicker positioning code is written to ignore elements not contained by document. The <input> is currently not considered contained, so the positioning code aborts.

I was able to hack a solution by simply stubbing out JQuery's contains code like this:

$(function() {
  jQuery.contains = function() {
    return true;
  };
 });

This is clearly a workaround (bad) solution, but it makes the JsBin work for now.

http://jsbin.com/saqojihi/8/edit

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top