zpt
Version:
Zenon Page Templates - JS (ZPT-JS)
586 lines (548 loc) • 18.2 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>More about updating</title>
<script type="module" src="../js/zpt.js"></script>
<script type="text/javascript" src="../lib/syntaxHighlighter/lib.js"></script>
<link rel="stylesheet" type="text/css" href="../docs.css">
<link rel="stylesheet" type="text/css" href="../lib/syntaxHighlighter/theme.css">
</head>
<body>
<div data-use-macro="'page@templates.html'">
<div data-fill-slot="'page-header'">
<h1>ZPT-JS tutorial - More about updating</h1>
<ul>
<li><a href="#intro">Intro</a>.</li>
<li><a href="#creatingArrays">Adding array items</a>.</li>
<li><a href="#updatingArrays">Updating array items</a>.</li>
<li><a href="#deletingArrays">Deleting array items</a>.</li>
<li><a href="#search">Using searches to define complex expressions</a>.</li>
<li><a href="#updatingObjects">Updating object properties</a>.</li>
<li><a href="#deletingObjects">Deleting object properties</a>.</li>
<li><a href="#reactiveDictionaries">Using reactive dictionaries</a>.</li>
</ul>
</div>
<article data-fill-slot="'article'">
<h2 data-attributes="id 'intro'">Intro</h2>
<p>
We have already seen how to update a template using the <em>update</em> command. And we have also seen <em>reactive dictionaries</em> in action. But in some cases this is not enough.
</p>
<p>
Take a look at this template:
</p>
<pre class="brush: html">
<ol>
<li data-repeat="item items">
<span data-content="item/name">an item name</span>:
<span data-content="item/description">an item description</span>
</li>
</ol>
</pre>
<p>
The javascript code to invoke ZPT-JS:
</p>
<pre class="brush: js">
import { zpt } from './zpt-esm.js';
var dictionary = new zpt.ReactiveDictionary({
items: [
{
name: 'John',
description: 'The number 1'
},
{
name: 'Peter',
description: 'The number 2'
},
{
name: 'Luke',
description: 'The number 3'
}
];
});
// Parse template
zpt.run({
root: document.body,
dictionary: dictionary
});
</pre>
<p>
Now we want to update the list of items. We can set the <em>items</em> in the dictionary this way:
</p>
<pre class="brush: js">
dictionary.items = [
{
name: 'John',
description: 'The number 1'
},
{
name: 'Peter',
description: 'The number 2'
},
{
name: 'Luke',
description: 'The number 3'
},
{
name: 'Mary',
description: 'The number 4'
}
];
);
</pre>
<p>
That code makes ZPT-JS to update the <em>data-repeat</em> node. It removes the current content and rebuilds it all. Perhaps this is not important for you, but it can be.
</p>
<p>
Anyway this way is not very natural, it would be great if ZPT-JS would provide a way to update the <em>items</em> array and then rebuilds only the needed HTML.
</p>
<h2 data-attributes="id 'creatingArrays'">Adding array items</h2>
<p>
Take a look at this:
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'items',
action: 'createArray',
index: '_last_',
newElement: {
name: 'Mary',
description: 'The number 4'
}
}
]
});
</pre>
<p>
Using <em>dictionaryActions</em> makes it easy to update the dictionary and the template. Some remarks about this:
</p>
<ul>
<li>
The <em>id</em> refers to the variable to modify.
</li>
<li>
The <em>action</em> defines the action to run. Available options are <em>createArray</em>, <em>updateArray</em>, <em>deleteArray</em>, <em>updateObject</em> and <em>deleteObject</em>.
</li>
<li>
The <em>index</em> indicates the place in the list to add the new element. Available options are <em>'_first_'</em>, <em>'_last_'</em> and a numeric value.
</li>
<li>
The <em>newElement</em> can be a <em>String</em>, number or object. If it is an array ZPT-JS will add each element of the array, making it easy to add several elements at once.
</li>
</ul>
<h2 data-attributes="id 'updatingArrays'">Updating array items</h2>
<p>
Now we are going to update the second item (replace <em>Peter</em> by <em>Mia</em>):
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'items',
action: 'updateArray',
index: 1,
newElement: {
name: 'Mia',
description: 'The number 5'
}
}
]
});
</pre>
<p>
Another way would be:
</p>
<pre class="brush: js; highlight: [7,8,9]">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'items',
action: 'updateArray',
currentElement: {
name: 'Peter'
},
newElement: {
name: 'Mia',
description: 'The number 5'
}
}
]
});
</pre>
<p>
Using <em>currentElement</em> provides an alternative way of finding elements to update or delete. The element must match all the fields of the <em>currentElement</em> if it is an object; if it is a literal (numeric or string) it must be equal.
</p>
<h2 data-attributes="id 'deletingArrays'">Deleting array items</h2>
<p>
Now we are going to delete the first item (delete <em>John</em>):
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'items',
action: 'deleteArray',
index: '_first_'
}
]
});
</pre>
<p>
We could use a <em>0</em> value as <em>index</em>.
</p>
<p>
Another way would be:
</p>
<pre class="brush: js; highlight: [7,8,9]">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'items',
action: 'deleteArray',
currentElement: {
name: 'John'
}
}
]
});
</pre>
<h2 data-attributes="id 'search'">Using searches to define complex expressions</h2>
<p>
Take a look at this template:
</p>
<pre class="brush: html">
<ol>
<li data-repeat="object objectList">
<span data-content="object/id"></span>
<ol>
<li data-repeat="item object/items">
<span data-content="item/name">an item name</span>:
<span data-content="item/description">an item description</span>
</li>
</ol>
</li>
</ol>
</pre>
<p>
The javascript code to invoke ZPT-JS:
</p>
<pre class="brush: js">
import { zpt } from './zpt-esm.js';
var dictionary = new zpt.ReactiveDictionary({
objectList: [
{
id: 'object1',
items: [
{
name: 'John',
description: 'The number 1'
},
{
name: 'Peter',
description: 'The number 2'
},
{
name: 'Luke',
description: 'The number 3'
}
]
},
{
id: 'object2',
items: [
{
name: 'Michael',
description: 'The number 4'
},
{
name: 'Chris',
description: 'The number 5'
},
{
name: 'Lars',
description: 'The number 6'
}
]
}
]
});
// Parse template
zpt.run({
root: document.body,
dictionary: dictionary
});
</pre>
<p>
Now we want to add a new element to <em>objectList</em>:
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
id: 'objectList',
action: 'createArray',
index: '_last_',
newElement: {
id: 'object3',
items: [
{
name: 'Mary',
description: 'The number 7'
},
{
name: 'Ann',
description: 'The number 8'
}
]
}
}
]
});
</pre>
<p>
The resulting HTML looks like this:
</p>
<pre class="brush: html">
1. object1
John: The number 1
Peter: The number 2
Luke: The number 3
2. object2
Michael: The number 4
Chris: The number 5
Lars: The number 6
3. object3
Mary: The number 7
Ann: The number 8
</pre>
<p>
Now we are going to insert a new <em>item</em> inside <em>object3</em> (Selena, the number 9) to get something like this:
</p>
<pre class="brush: html highlight: [10]">
1. object1
John: The number 1
Peter: The number 2
Luke: The number 3
2. object2
Michael: The number 4
Chris: The number 5
Lars: The number 6
3. object3
Selena: The number 9
Mary: The number 7
Ann: The number 8
</pre>
<p>
And the command to run:
</p>
<pre class="brush: js; highlight: [5,6,7,8,9,10,11,11]">
zpt.run({
command: 'update',
dictionaryActions: [
{
search: [
'objectList',
{
id: 'object3'
},
'items'
],
action: 'createArray',
index: '_first_',
newElement: {
name: 'Selena',
description: 'The number 9'
}
}
]
});
</pre>
<p>
A <em>search</em> element is an array of elements that ZPT-JS combines to define a path to access the variable you want to modify. Each element can be one of these types:
</p>
<ul>
<li><strong>A literal string</strong>. Such as <em>objectList</em> or <em>items</em> in this example.</li>
<li><strong>A literal integer</strong>. Useful to select item from arrays.</li>
<li><strong>An object</strong>. ZPT-JS will search into the available items the first that matches it.</li>
</ul>
<p>
In this example the path defined by the <em>search</em> is <em>objectList[ id='object3' ].items.</em>
</p>
<p>
The same search using an integer as a search item:
</p>
<pre class="brush: js; highlight: [7]">
zpt.run({
command: 'update',
dictionaryActions: [
{
search: [
'objectList',
2,
'items'
],
action: 'createArray',
index: '_first_',
newElement: {
name: 'Selena',
description: 'The number 9'
}
}
]
});
</pre>
<p>
In this example the path defined by the <em>search</em> is <em>objectList[1].items.</em>
</p>
<p>
The same search using <em>_last_</em> as a search item:
</p>
<pre class="brush: js; highlight: [7]">
zpt.run({
command: 'update',
dictionaryActions: [
{
search: [
'objectList',
'_last_',
'items'
],
action: 'createArray',
index: '_first_',
newElement: {
name: 'Selena',
description: 'The number 9'
}
}
]
});
</pre>
<p>
Search elements can be used in any class of dictionaryActions, not only in <em>createArray</em> actions.
</p>
<h2 data-attributes="id 'updatingObjects'">Updating object properties</h2>
<p>
Take a look at this template:
</p>
<pre class="brush: html">
<div>
<span data-content="object/name">an item name</span>:
<span data-content="object/description">an item description</span>
</div>
</pre>
<p>
Now we are going to update the <em>name</em> property (now the name is <em>Dave</em>):
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
search: [
'object'
],
action: 'updateObject',
property: 'name',
newElement: 'Dave'
}
]
});
</pre>
<h2 data-attributes="id 'deletingObjects'">Deleting object properties</h2>
<p>
Using the previous template, now we are going to delete the <em>name</em> property:
</p>
<pre class="brush: js">
zpt.run({
command: 'update',
dictionaryActions: [
{
search: [
'object'
],
action: 'deleteObject',
property: 'name'
}
]
});
</pre>
<p>
The <em>name</em> property has been deleted from the <em>object</em> vaiable in the dictionary.
</p>
<h2 data-attributes="id 'reactiveDictionaries'">Using reactive dictionaries</h2>
<p>
An alternative way of working with <em>dictionary actions</em> is using a reactive dictionary:
</p>
<pre class="brush: js">
import { zpt } from './zpt-esm.js';
var dictionary = new zpt.ReactiveDictionary({
items: [
{
id: 'object1',
items: [
{
name: 'John',
description: 'The number 1'
},
{
name: 'Peter',
description: 'The number 2'
},
{
name: 'Luke',
description: 'The number 3'
}
]
}
];
});
// Parse template
zpt.run({
root: document.body,
dictionary: dictionary
});
</pre>
<p>
To run a dictionary action, you can do this:
</p>
<pre class="brush: js">
dictionary._addActions([
{
id: 'items',
action: 'createArray',
index: '_last_',
newElement: {
id: 'object2',
items: [
{
name: 'Sophia',
description: 'The number 4'
},
{
name: 'Jane',
description: 'The number 5'
},
{
name: 'Drew',
description: 'The number 6'
}
]
}
}
]);
</pre>
<p>
Be careful, the update is done inmediately. For more details about <em>reactive dictionaries</em>, see <a href="../reference/reactiveDictionaries.html">reference page</a>
</p>
</article>
</div>
</body>
</html>