I am trying to implement Sortablejs in Polymer2.0 app, where in I dynamically assign ids to the ul element in a dom repeat template.
The problem I have is I can't access the ul with id in the observer method of the data list todos.
I tried document.getElementId, this.$.querySelector but both return null and Sortablejs create method throws error that html el is required. I have also tried this.shadowRoot.querySelector(child.id) ... it also returned null.
I am struggling since last 2 days to get it working. what is it that I need to do to fix it? Help pls.
<!DOCTYPE html>
<dom-module id="t-page">
<script src="http://SortableJS.github.io/Sortable/Sortable.js"> .
</script>
<template is="dom-bind">
<style include="shared-styles">
....
</style>
<div class="board__sprint">
<template is="dom-repeat" items="{{todos}}" as="row">
<div class="list">
<div class="list-content">
<ul id="[[row.id]]">
<!-- id is v789878 (some random unique number prefix by v per row -->
<template is="dom-repeat" items="{{row.tasks}}" as="todo">
<li>
<div class="ticket" data-index$="{{todo.id}}">
<paper-card style="float:center; width: 100%;" class="singleColor" data-index$="{{todo}}"
data-index$="{{row}}">
<h7 class="banksTitle" style="color: black; font-size: 12px; text-align:left;">
<b>[{{index}}]</b> [[todo.actTitle]]
</h7>
<h7 class="banksTitle" style="color: grey; font-size: 12px; text-align:left;">
[[todo.actDesc]]
</h7>
</paper-card>
</div>
</li>
</template>
</ul>
</div>
<div class="addTicket">
<paper-button raised class="blue" on-tap="_addTicketDialog" row={{row}}>Add Ticket</paper-button>
</div>
</div>
</div>
</template>
</div>
<script>
/**
* @polymer
* @extends HTMLElement
*/
class TPage extends Polymer.Element {
static get is() {
return 't-page';
}
static get properties() {
return {
todos: {
type: Object,
notify: true,
observer: '_todosChanged'
},
....
}
_todosChanged() {
console.log('this.todos.length = ' + this.todos.length);
if (this.todos !== null || this.todos !== undefined) {
var self = this;
this.todos.forEach(function (child) {
Sortable.create(self.$.querySelector(child.id), {
group: 'shared'
});
});
}
}
window.customElements.define(TPage.is, TPage);
There are three points in order to select your element:
- Id standards: The value must be unique amongst all the IDs in the element's home subtree and must contain at least
one character
. The value must not contain any space characters...
<ul id="myid[[row.id]]">
- Rendering timing of dom-repeat. For this you may wrap your function
setTimeout
to be sure to render your all items in dom-repeat.
_todosChanged() {
setTimeout(()=>{
console.log('this.todos.length = ' + this.todos.length);
if (this.todos !== null || this.todos !== undefined) {
var self = this
this.todos.forEach(child=> {
console.log(child.id)
var selector = this.shadowRoot.querySelector('#myid'+child.id);
Sortable.create(selector, {
group: 'shared'
});
});
}
})
}
- The context of your function is not bound to the Polymer object, So the shortest solution is use array function ( ES6 ):
this.todos.forEach(child=> {....
instead of:
this.todos.forEach(function (child) {...