Initializing from Templates
Qite does not use render functions — it instead uses native HTML
<template>
elements. Templates allow you to define component markup
in HTML and instantiate it dynamically when needed.
The browser already provides
<template>
as a safe, inert container for markup.
Its content is not rendered until cloned. Qite builds on that instead of
inventing its own rendering abstraction.
When to use templates
Templates are very useful when you don't know ahead of time how many instances
of a particular component you might need on your page as time passes and
things change. For instance, you might want to dynamically add form fields
(which you decided are going to be instances of
TextInputComponent
class)
if user, say, needs to add more delivery addresses into his profile.
A good way to handle this would be to have an "Add address" button which,
when clicked, creates a new
TextInputComponent
using a template.
Defining the address template
You would first define a template in your HTML:
<template
data-component="TextInput"
data-tag-name="div"
data-qtemplate-name="default"
>
<label data-field="label"></label>
<input data-part="value" name="" value=""/>
<div class="hint" data-part="hint"></div>
<div class="errors" data-field="validation_errors"></div>
</template>
This template describes how a
TextInputComponent
should be constructed.
Nothing inside it is rendered immediately because
<template>
content
is inert by default.
Instead of wrapping the component in a
<div data-component="TextInput">,
Qite reads
data-component,
data-tag-name
and
data-qtemplate-name
directly from the
<template>
tag and constructs the root element for you.
-
data-component="TextInput"tells Qite which component class to instantiate. -
data-tag-name="div"defines which HTML tag should be created. -
data-qtemplate-name="default"gives this template a name.
When this template is used, Qite creates a
<div data-component="TextInput">
element, inserts the template content inside it, scans it and instantiates
a
TextInputComponent
All standard Qite components have an
.html
file in their directory
which contains the expected HTML structure. For
TextInputComponent,
check
src/components/text_input/text_input.html.
You can copy that structure and move it inside
<template>
tags.
Default vs named templates
A component may have more than one template.
The
data-qtemplate-name
attribute allows you to define multiple variations:
<template
data-component="TextInput"
data-tag-name="div"
data-qtemplate-name="default"
>
<!-- default layout -->
</template>
<template
data-component="TextInput"
data-tag-name="div"
data-qtemplate-name="compact"
>
<!-- compact layout -->
</template>
The template with name
"default"
is used automatically when
no specific template is requested.
To explicitly choose a template:
TextInputComponent.create({
parent: this,
template_name: "compact"
});
If you omit
template_name, Qite uses
"default"
Adding address fields dynamically
Now suppose you have a parent component responsible for managing a list of delivery addresses.
import BaseComponent from "/assets/vendor/qite/src/components/base_component.js";
import TextInputComponent from "/assets/vendor/qite/src/components/text_input/text_input_component.js";
export default class DeliveryComponent extends BaseComponent {
constructor(tree_node) {
super(tree_node);
this.events.add([
["click", "add_address", () => this.addAddress() ],
]);
}
addAddress() {
TextInputComponent.create({
parent: this,
template_name: "default"
});
}
}
Qite.components.Delivery = DeliveryComponent;
And in HTML:
<div data-component="Delivery">
<button data-component="Button" data-roles="add_address">
Add address
</button>
</div>
When the user clicks the button,
addAddress()
is called.
TextInputComponent.create(...)
then:
-
Finds the
<template>matchingdata-component="TextInput"anddata-qtemplate-name="default" -
Creates a new root element with
data-tag-name - Inserts template content inside it.
- Appends it to the parent.
- Scans that subtree.
-
Instantiates a new
TextInputComponent - Links it into the component hierarchy.
The newly created component behaves exactly like one that was present at page load.
Hierarchy and wiring
When you pass
parent: this
to
create()
-
The new component is appended to
this.children -
Its
parentproperty is set. - Event subscriptions are wired.
-
Its
mountedpromise is resolved after hierarchy attachment.
There is no special case for template-created components. They become first-class components in the tree.
Templates keep HTML in HTML
With this approach:
- HTML structure lives in HTML.
- Component behavior lives in JavaScript.
- Styling lives in CSS.
You are not building HTML strings, not mixing markup inside JavaScript, and not re-rendering entire blocks. Qite clones structured DOM and attaches behavior to it.
Creating a component from a template triggers scanning only for the cloned subtree. It does not rescan the entire document.
What to read next
Now that you understand how to create components dynamically, the next page explains how parent and child components relate to each other in more detail.