Templating
Monster’s updater uses a DOM-based approach. The configuration and the template system are valid and parsable HTML.
The configuration is done via some special attributes with a data-monster-
prefix.
Code is always the most informative. So let’s take a look at a complete example right away.
// The first thing to do is to include the Updater class.
import {Updater} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js';
// Now we prepare the html document.
// This is done here via script, but can also be inserted into the document as pure html.
// To do this, simply insert the tag <h1 data-monster-replace="path:headline"></h1>.
const body = document.querySelector('body');
const headline = document.createElement('h1');
headline.setAttribute('data-monster-replace','path:headline')
body.appendChild(headline);
// the data structure
let obj = {
headline: "Go!",
};
// Now comes the real magic. we pass the updater the parent HTMLElement
// and the desired data structure.
const updater = new Updater(body, obj);
// now we get the used data structure. why can't we take the original structure?
// the updater puts a proxy over the data structure and thus allows to monitor changes.
// We would not see changes to the original object.
const subject = updater.getSubject();
// now start the updater
updater.run();
// Now you can change the data structure and the HTML will follow these changes.
// to illustrate, let's put the change into a timer call.
setTimeout(function(){
console.log(obj);
subject['headline'] = "Hello!"
},1000);
We have seen how we can change the content of an htm element. now let’s look at what options are available.
Replace
The simplest manipulation is to replace the content of a HTMLElement.
To do this, simply use the data-monster-replace
attribute (see example).
The syntax is quite simple. The result of the attribute pipe is inserted as content of the
HTMLElement. For the processing the Pipe
and Transformer class
is used.
If, for example, you have an object x
with the structure listed below and want to insert the value of the key b, you write: path:a.b
.
The pipe can then be used to apply operators. For example, tolower
can be used to convert everything to lowercase.
let x = {
a: {
b: "EXAMPLE"
}
}
this is how it looks as an attribute:
<div data-monster-replace="static:HELLO | tolower"></div>
The result is then the following html:
<div data-monster-replace="static:hello">hello</div>
A full example looks like this:
import {Updater} from 'https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js';
const body = document.querySelector('body');
const headline = document.createElement('h1');
headline.setAttribute('data-monster-replace','static:hello')
body.appendChild(headline);
// result in ↦ <div data-monster-replace="static:hello"></div>
new Updater(body).run();
Attributes
Attributes can be added via the data-monster-attributes
attribute. The syntax is attribute name followed by
a space and the desired pipe definition.
<div data-monster-attributes="id static:myid">hello</div>
The result is then the following html:
<div id="myid" data-monster-attributes="id static:myid">hello</div>
Multiple attributes can be separated by commas.
<div data-monster-attributes="id static:myid, class static:myclass">hello</div>
Remove
The data-monster-remove
attribute can be used to remove html elements. it is important to
note that this cannot be undone. Once removed, nodes will not be reinserted.
This tag is removed via the updater
<div data-monster-remove></div>
Insert
The strongest feature is adding elements to a node.
For this feature you need a template and the data-monster-insert
attribute.
The syntax of the attribute is first an id followed by a space. This is then followed by the pipe command.
<ol data-monster-insert="myid path:a"></ol>
Furthermore, you need a template. The template must have the same string as id.
<template id="myid">
<li data-monster-replace="path:myid | index:id | tostring | prefix:x"></li>
</template>
In this template, we define the structure of the new elements. In this case, the id is taken
from the dataset index:id
, converted to a string tostring
, and an x is placed in front of it prefix:x
.
The values for the corresponding data must be available as an array.
let obj = {
a: [
{"id": 1},
{"id": 2},
{"id": 3},
{"id": 4}
]
};
Below we have a complete example. Instead of specifying the template <template />
in HTML, it is constructed via
javascript document.createElement('template')
. But it is essentially the same.
const body = document.querySelector('body');
const li = document.createElement('li');
li.innerHTML="-/-";
li.setAttribute('data-monster-replace','path:myid | index:id | tostring | prefix:x');
const template = document.createElement('template');
template.setAttribute('id','myid');
template.content.appendChild(li);
body.appendChild(template);
const list = document.createElement('ul');
list.setAttribute('data-monster-insert', 'myid path:a')
body.appendChild(list);
let obj = {
a: [
{"id": 1},
{"id": 2},
{"id": 3},
{"id": 4}
]
};
const updater = new Updater(body, obj)
updater.run();
The result will be
<ul data-monster-insert="myid path:a">
<li data-monster-replace="path:a.0 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-0">x1</li>
<li data-monster-replace="path:a.1 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-1">x2</li>
<li data-monster-replace="path:a.2 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-2">x3</li>
<li data-monster-replace="path:a.3 | index:id | tostring | prefix:x" data-monster-insert-reference="myid-3">x4</li>
</ul>
You can easily add and delete values to the array. The DOM will be adjusted accordingly.
The attribute data-monster-insert-reference
identifies if the entry already exists.