5

I want to achieve this in LWC.

I want to call the same HTML content (ex- div, p) multiple times in iteration & append them one below other as shown in above link.

I used this

$('div').clone().appendTo('.wrapper');

in JS, but it won't work...!!!

Can anyone please suggest some alternative. Thanks in advance.

9

In LWC, we usually do not create dynamic nodes this way. It is idiomatic in LWC to use a repeating template (for:each and for:item) and only change the data that drives the template, rather than clone the template itself. Here, I present what you'd do in LWC.

Playground


css

.note {
    margin-bottom: 10px;
    background-color: yellow;
    width: 100px;
    height: 100px;
}

html

<template>
    <div class="wrapper">
    <template for:each={items} for:item="item">
        <div key={item.key} class="note">
            <div>Content in div</div>
        </div>
    </template>
    </div>
    <lightning-button label="Add note" onclick={addNote}></lightning-button>
</template>

js

import { LightningElement, track } from 'lwc';

export default class App extends LightningElement {
    @track items = [
        { key: 0 }
    ];
    addNote() {
        this.items = [...this.items, { key: this.items.length }];
    }
}
  • 3
    I assume, for keys it should be this.items = [...this.items, { key: this.items.length}];, because { key: this.items.length+1 } produces indexes like 0,2,3,4... 1 is skipped in this case :) – Oleksandr Berehovskyi Dec 6 '19 at 13:24
  • 5
    @OleksandrBerehovskyi Yeah... this is probably why I shouldn't write answers before my first cup of coffee :p ... Thanks for the comment, I've edited that in to reflect what I meant. – sfdcfox Dec 6 '19 at 13:26
  • 1
    Thanks so much @sfdcfox ......You have amazing & in-depth knowledge... Please keep helping me :)) – Mohit Kulkarni Dec 6 '19 at 16:03
5

You can simply rewrite your jsfiddle jQuery snipper to LWC next way:

<template>
    <div class="container" lwc:dom="manual"></div>
    <button onclick={onAddNoteButtonClick}>Add note</button>
</template>
.note {
    margin-bottom: 10px;
    background-color: yellow;
    width: 100px;
    height: 100px;
}
import { LightningElement } from 'lwc';

export default class App extends LightningElement {

    renderedCallback() {
        const container = this.template.querySelector('.container');
        container.innerHTML = 
        `<div class="wrapper">
            <div class="note">Content in div</div>
        </div>`;
    }

    onAddNoteButtonClick () {
        const note = this.template.querySelector('.note');
        const wrapper = this.template.querySelector('.wrapper');
        wrapper.appendChild(note.cloneNode(true));
    }
}

Main idea here is adding lwc:dom="manual" directive to be able to manipulate the DOM within container div.

Playground

Not the answer you're looking for? Browse other questions tagged or ask your own question.