Search code examples
javascriptpolymervaadinshadow-dom

How do you clone/copy a DOM node's shadow Dom?


I am trying to clone a table row with web API's cloneNode() method. Inside those table rows are table data with some vaadin web components that use shadow DOM to get and render its data.

When using cloneNode() to do this, the shadow DOM is not cloned/copied, so now I am left with some vaadin combo-boxes that have no output when rendered.

Is there some way to overcome this?

Example of a table cell that was cloned using cloneNode():

<td style="text-align:center;">
   <vaadin-combo-box id="xxxlist" 
    value="{{definition.lkp_xxx_unit_id}}"
    item-label-path="value" item-value-path="id">
   </vaadin-combo-box>
</td>

Then after that I have this block of code to actually get the items for the vaadin-combo-box component:

ready: function() {
        app.addEventListener('xxx-choices-changed', function(event) {
          this.$.xxxlist.items = app.choices['lkp_xxx_id'];
        }.bind(this));
        this.$.xxxlist.items = app.choices['lkp_xxx_id'];
      }

Any idea how to clone the node with the shadow DOM attached?


Solution

  • You should not clone the shadow dom contents. The web component (<vaadin-combo-box> in this case) is responsible for creating that with JavaScript when a new instance of that element is created. So, when you clone a web component and attach it to the DOM, it’ll create the shadow DOM by itself.

    Your problem here is probably that the items property is not set for the cloned elements. Note, that the ready method is only run for the first instance of a Polymer web component, not for all instances. Use connectedCallback or constructor instead if you want to run some code for every instance.