Skip to content Skip to sidebar Skip to footer

Vanilla Custom Element Repeater For

I'm currently trying to implement a repeater WebComponent to allow the company to easily create front-end without depending on any framework (decision took by architecture). Here'

Solution 1:

Solution 1

Put the repeater around your elements. Ex. for a minimal <data-repeater> custom element :

customElements.define('data-repeater', class extends HTMLElement 
{
  connectedCallback() 
  {
    const parent = this.firstElementChild
    const data = JSON.parse(this.dataset.values)

    const interpolate = obj => parent.innerHTML.replace(
      /\${(\w+)}/g,
      (match, key) => obj[key]
    )

    parent.innerHTML = data.map(interpolate).join('')
  }
})
<data-repeater data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
  <ul>
    <li id="${id}">${label}</li>
  </ul>
</data-repeater>

<data-repeater data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
  <select>
      <option value="${value}">${name}</option>
  </select>
</data-repeater>

Solution 2

Use customized built-in elements. You need to choose a new name for each standard element you want to extend, but you can reuse internally a unique base class to render the elements:

<select is="repeat-option" data-values="[...]">
   <option value="${value}">${name}</option>
</select>

customElements.define('select-repeater', class extends HTMLSelectElement {
  connectedCallback() { render(this) }
}, { extends: 'select' })

customElements.define('ul-repeater', class extends HTMLUListElement {
  connectedCallback() { render(this) }
}, { extends: 'ul' })

function render(view) {
  const data = JSON.parse(view.dataset.values)

  const interpolate = obj => view.innerHTML.replace(
    /\${(\w+)}/g,
    (match, key) => obj[key]
  )

  view.innerHTML = data.map(interpolate).join('')
}
<script src="https://rawgit.com/WebReflection/document-register-element/master/build/document-register-element.js"></script>


<ul is="ul-repeater" data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
    <li id="${id}">${label}</li>
</ul>


<select is="select-repeater" data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
		<option value="${value}">${name}</option>
</select>

If the rendering is very different depending on the element you could decide to create a class for rendering and to use derived classes for each type fo rendering ( select, ul, tr, td ), like in this example for tables.


Post a Comment for "Vanilla Custom Element Repeater For