Automatically move inner html in created node when inheriting from HTMLElement

This commit is contained in:
Antoine Bartuccio 2024-10-20 18:29:48 +02:00
parent 301fc73687
commit 517263dd58
4 changed files with 17 additions and 17 deletions

View File

@ -60,12 +60,6 @@ class AutocompleteSelect extends inheritHtmlElement("select") {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
for (const option of Array.from(this.children).filter(
(child) => child.tagName.toLowerCase() === "option",
)) {
this.removeChild(option);
this.node.appendChild(option);
}
this.widget = new TomSelect(this.node, this.tomSelectSettings()); this.widget = new TomSelect(this.node, this.tomSelectSettings());
this.attachBehaviors(); this.attachBehaviors();
} }
@ -129,6 +123,7 @@ abstract class AjaxSelect extends AutocompleteSelect {
protected abstract renderItem(item: TomOption, sanitize: typeof escape_html): string; protected abstract renderItem(item: TomOption, sanitize: typeof escape_html): string;
protected abstract search(query: string): Promise<TomOption[]>; protected abstract search(query: string): Promise<TomOption[]>;
private initialValues: TomOption[] = [];
public setFilter(filter?: (items: TomOption[]) => TomOption[]) { public setFilter(filter?: (items: TomOption[]) => TomOption[]) {
this.filter = filter; this.filter = filter;
} }
@ -176,13 +171,20 @@ abstract class AjaxSelect extends AutocompleteSelect {
}; };
} }
connectedCallback() {
/* Capture initial values before they get moved to the inner node and overridden by tom-select */
this.initialValues = Array.from(this.children)
.filter((child) => child.tagName.toLowerCase() === "slot")
.map((slot) => JSON.parse(slot.innerHTML));
super.connectedCallback();
}
protected attachBehaviors() { protected attachBehaviors() {
super.attachBehaviors(); super.attachBehaviors();
// Gather selected options, they must be added with slots like `<slot>json</slot>` // Gather selected options, they must be added with slots like `<slot>json</slot>`
for (const value of Array.from(this.children) for (const value of this.initialValues) {
.filter((child) => child.tagName.toLowerCase() === "slot")
.map((slot) => JSON.parse(slot.innerHTML))) {
this.widget.addOption(value, false); this.widget.addOption(value, false);
this.widget.addItem(value[this.valueField]); this.widget.addItem(value[this.valueField]);
} }

View File

@ -193,10 +193,6 @@ const loadEasyMde = (textarea: HTMLTextAreaElement) => {
class MarkdownInput extends inheritHtmlElement("textarea") { class MarkdownInput extends inheritHtmlElement("textarea") {
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
const initialValue = this.querySelector("slot[name='initial']");
if (initialValue as HTMLSlotElement) {
this.node.textContent = initialValue.textContent;
}
loadEasyMde(this.node); loadEasyMde(this.node);
} }
} }

View File

@ -43,7 +43,11 @@ export function inheritHtmlElement<K extends keyof HTMLElementTagNameMap>(tagNam
this.removeAttributeNode(attr); this.removeAttributeNode(attr);
this.node.setAttributeNode(attr); this.node.setAttributeNode(attr);
} }
// Atuomatically add node to DOM if autoAddNode is true or unspecified
this.node.innerHTML = this.innerHTML;
this.innerHTML = "";
// Automatically add node to DOM if autoAddNode is true or unspecified
if (autoAddNode === undefined || autoAddNode) { if (autoAddNode === undefined || autoAddNode) {
this.appendChild(this.node); this.appendChild(this.node);
} }

View File

@ -2,8 +2,6 @@
<script-once src="{{ statics.js }}" defer></script-once> <script-once src="{{ statics.js }}" defer></script-once>
<link-once rel="stylesheet" type="text/css" href="{{ statics.css }}" defer></link-once> <link-once rel="stylesheet" type="text/css" href="{{ statics.css }}" defer></link-once>
<markdown-input name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}> <markdown-input name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>{% if widget.value %}{{ widget.value }}{% endif %}</markdown-input>
<slot name="initial" style="display: none">{% if widget.value %}{{ widget.value }}{% endif %}</slot>
</markdown-input>
</div> </div>