mirror of
https://github.com/JeremyLikness/vanillajs-deck
synced 2024-12-04 19:27:37 +00:00
Add data-binding for lists
This commit is contained in:
parent
a4ae68dfb8
commit
0cab33efe5
@ -8,7 +8,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="DevNexus presentation Vanilla.js: Modern 1st Party JavaScript">
|
<meta name="description" content="DevNexus presentation Vanilla.js: Modern 1st Party JavaScript">
|
||||||
<meta http-equiv="Content-Security-Policy"
|
<meta http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; child-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; style-src 'self';">
|
content="default-src 'self'; script-src 'self' 'unsafe-eval'; child-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; style-src 'self';">
|
||||||
<link rel="shortcut icon" href="/images/logo.png" type="image/png" />
|
<link rel="shortcut icon" href="/images/logo.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<link rel="stylesheet" href="css/style.css">
|
||||||
<link rel="stylesheet" href="css/animations.css">
|
<link rel="stylesheet" href="css/animations.css">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<script type="module" src="./js/app.js"></script>
|
<script type="module" src="./js/app.js"></script>
|
||||||
<slide-deck id="main" start="001-title">
|
<slide-deck id="main" start="data-binding">
|
||||||
<h1>DevNexus | Vanilla.js: Modern 1st Party JavaScript</h1>
|
<h1>DevNexus | Vanilla.js: Modern 1st Party JavaScript</h1>
|
||||||
<h2>Setting things up ...</h2>
|
<h2>Setting things up ...</h2>
|
||||||
</slide-deck>
|
</slide-deck>
|
||||||
|
3
js/controls.js
vendored
3
js/controls.js
vendored
@ -85,6 +85,9 @@ export class Controls extends HTMLElement {
|
|||||||
* Enables/disables buttons and updates position based on index in the deck
|
* Enables/disables buttons and updates position based on index in the deck
|
||||||
*/
|
*/
|
||||||
refreshState() {
|
refreshState() {
|
||||||
|
if (this._controlRef == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const next = this._deck.hasNext;
|
const next = this._deck.hasNext;
|
||||||
const prev = this._deck.hasPrevious;
|
const prev = this._deck.hasPrevious;
|
||||||
this._controlRef.first.disabled = !prev;
|
this._controlRef.first.disabled = !prev;
|
||||||
|
41
js/slide.js
41
js/slide.js
@ -14,6 +14,11 @@ export class Slide {
|
|||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
this._text = text;
|
this._text = text;
|
||||||
|
/**
|
||||||
|
* Context for embedded scripts
|
||||||
|
* @type {object}
|
||||||
|
*/
|
||||||
|
this._context = {};
|
||||||
/**
|
/**
|
||||||
* The HTML DOM hosting the slide contents
|
* The HTML DOM hosting the slide contents
|
||||||
* @type {HTMLDivElement}
|
* @type {HTMLDivElement}
|
||||||
@ -49,6 +54,42 @@ export class Slide {
|
|||||||
else {
|
else {
|
||||||
this._nextSlideName = null;
|
this._nextSlideName = null;
|
||||||
}
|
}
|
||||||
|
// execute any scripts
|
||||||
|
const script = this._html.querySelector("script");
|
||||||
|
if (script) {
|
||||||
|
(function (/** @type {string} */src) {
|
||||||
|
return eval(src)
|
||||||
|
}).call(this._context, script.innerText);
|
||||||
|
this.dataBind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans for data-binding and applies the bindings
|
||||||
|
*/
|
||||||
|
dataBind() {
|
||||||
|
const listBinding = this._html.querySelectorAll("[repeat]");
|
||||||
|
listBinding.forEach(elem => {
|
||||||
|
const parent = elem.parentElement;
|
||||||
|
const expression = elem.getAttribute("repeat");
|
||||||
|
elem.removeAttribute("repeat");
|
||||||
|
const template = elem.outerHTML;
|
||||||
|
parent.removeChild(elem);
|
||||||
|
this._context[expression].forEach(item => {
|
||||||
|
let newTemplate = `${template}`;
|
||||||
|
const matches = newTemplate.match(/\{\{([^\}]*?)\}\}/g);
|
||||||
|
if (matches) {
|
||||||
|
matches.forEach(match => {
|
||||||
|
match = match.replace("{{", "").replace("}}", "");
|
||||||
|
const value = (function (/** @type {string} */src) {
|
||||||
|
return eval(src)
|
||||||
|
}).call({ item }, match);
|
||||||
|
newTemplate = newTemplate.replace(`{{${match}}}`, value);
|
||||||
|
});
|
||||||
|
parent.innerHTML += newTemplate;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
<h1>I'm Not Anti-Angular!</h1>
|
<h1>I'm Not Anti-Angular!</h1>
|
||||||
<i>Here's proof from 2014...</i>
|
<i>Here's proof from 2014...</i>
|
||||||
<img src="/images/ng-conf.png" class="expandable" alt="Inside the inaugural Angular conference ngConf"
|
<img src="/images/ng-conf.png" class="expandable" alt="Inside the inaugural Angular conference ngConf"
|
||||||
title="Inside the inaugural Angular conference ngConf" />
|
title="Inside the inaugural Angular conference ngConf" />
|
8
slides/data-binding.html
Normal file
8
slides/data-binding.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<title>Data-Binding Example 1</title>
|
||||||
|
<h1>Data-Binding Example</h1>
|
||||||
|
<ul>
|
||||||
|
<li repeat="list" class="appear">{{item.idx}} — {{item.value}}</li>
|
||||||
|
</ul>
|
||||||
|
<script>
|
||||||
|
this.list = [{idx: 0, value:"one"}, {idx: 1, value:"two"}, {idx: 2, value:"three"}];
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user