-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathejs_tutorial.html
200 lines (171 loc) · 7.75 KB
/
ejs_tutorial.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<!doctype html><html><body><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>eval js</title>
<style>
.red { color:red; padding-top: 1em; }
[embeddedjs] { display: none; }
</style>
<script>
// eval-write an element
function writeElement(element, process, remove=true){
// to update an element first remove it
if(remove) element.parentNode.removeChild(element.nextSibling)
var html_result=process(element)
// if there is no result from the eval don't write any html in this way
// but the script can still call outHTML and write html in this way
if(typeof html_result != 'undefined') outHTML(element, html_result)
}
function getContent(element){
return element.tagName=='TEMPLATE'?
element.content.textContent:(
element.tagName=='SPAN'?element.innerText:
element.innerHTML)
}
function evalElement(element){
// the eval part (evaluate the script)
var eval_result=eval(getContent(element))
// if the evaluated script results in a function, call this function (that results in html)
var html_result=typeof eval_result!='function'?eval_result:eval_result(element)
return html_result
}
function ejsElement(element){
var html_result=ejs.render(getContent(element),window)
return html_result
}
// eval-write an element
function evalWriteElement(element, remove=true){
writeElement(element, evalElement, remove)
}
// eval-write an element
function ejsWriteElement(element, remove=true){
writeElement(element, ejsElement, remove)
}
// the write part (insert an adiacent span with the resulting html)
function outHTML(element, html_result){
element.insertAdjacentHTML('afterend','<span>'+html_result+'</span>')
}
// on document ready
document.addEventListener("DOMContentLoaded", () => {
// first mandatory write
document.querySelectorAll('[evalwrite]').forEach((element)=>evalWriteElement(element, false))
// time-continous repeated write (updates)
document.querySelectorAll('[evalwrite=repeatedly]').forEach(element=>setInterval(()=>evalWriteElement(element)))
// first mandatory write
document.querySelectorAll('[embeddedjs]').forEach((element)=>ejsWriteElement(element, false))
// time-continous repeated write (updates)
document.querySelectorAll('[embeddedjs=repeatedly]').forEach(element=>setInterval(()=>ejsWriteElement(element)))
})
// fetch with Url and Type
const fetchUT = async (url,type='json') => await (await fetch(url))[type]()
// a linear array variable
var array=[]
// converts a linear array into <ul>
function ulFromArray(array){
var html='<ul>'
for(var i of array.keys())
html+='<li>'+array[i]+'</li>'
html+='</ul>'
return html
}
// integer counter variable
var counter=1
var user=''
</script>
<div class="red">embeddedjs test/example</div>
<div>
<input value="lynx" placeholder="username" id="username">
<button onclick="user=document.all.username.value;ejsWriteElement(document.all.ifuser)">login</button>
<script type="text/ejs" embeddedjs="triggered" id="ifuser">
<% if (user!="") { %>
<h2>"<%= user %>" user logged in</h2>
<% } %>
</script></div>
<div class="red">EmbeddedJS(<a href="http://ejs.co" target="_blank">http://ejs.co</a>) templating (see <a href="https://github.com/arkenidar/ejs_plus" target="_blank">https://github.com/arkenidar/ejs_plus</a>)</div>
<script src="https://arkenidar.github.io/ejs_plus/ejs.min.js"></script>
<script src="https://arkenidar.github.io/ejs_plus/ejs_price.js"></script>
<div><script evalwrite="once">price('product1', 0.5)</script></div>
<div class="red">live date (repeatedly updated)</div>
<div><script evalwrite="repeatedly">new Date()</script></div>
<div class="red">evalAsync with fetch (no update)</div>
<div><script evalwrite="once">
((element)=>{
// some text file is fetched and ouputted
fetchUT('sample_text.txt','text').then((data)=>{
outHTML(element, data)
})
})
</script></div>
<div class="red">value from <input> (updated)</div>
<div><input id="name" placeholder="name" value="World"> Hello <script evalwrite="repeatedly">document.all.name.value</script></div>
<div class="red">value from input modified for "two-way data binding" (IMPORTANT: two way data-binding is not shown here but in an example that follows)</div>
<div>
<input id="name2" placeholder="name" value="World" oninput="window.name2=this.value">
Hello <script evalwrite="repeatedly">name2</script>
<script>
document.addEventListener("DOMContentLoaded", () => {
//document.all.name2.dispatchEvent(new Event('input'))
// every <input> with value triggers an input event
// input fired in a generalized style (id not specified)
document.querySelectorAll('input[value]').forEach((input)=>{input.dispatchEvent(new Event('input'))})
})
</script>
</div>
<div class="red">optional display (shows only 1 of many)</div>
<a onclick="option(1)">option1</a> <a onclick="option(2)">option2</a> <a onclick="option(3)">option3</a>
<script>function option(n){
document.querySelectorAll('.option').forEach(option=>option.style.display='none')
document.querySelector('#option'+parseInt(n)).style.display='block'
}</script>
<div class="option" id="option1"><script evalwrite="once">ulFromArray([10,20,30])</script></div>
<div class="option" id="option2"><script evalwrite="once">ulFromArray(['aaa','bbb','ccc'])</script></div>
<div class="option" id="option3">option3...</div>
<div class="red">shows an <ul> from an array that is assigned</div>
<script evalwrite="repeatedly">ulFromArray(array)</script>
<button onclick="array=[1,2,3]">set [1,2,3]</button>
<button onclick="array=[3,4,5]">set [3,4,5]</button>
<div class="red">evalAsync with fetch + rendered JSON</div>
<div><script evalwrite="once">
((element)=>{
fetchUT('sample_json.json','json').then((json)=>{
outHTML(element, ulFromArray(json))
})
})
</script></div>
<div class="red">password reveal example (using "repeatedly")</div>
<div>
<input type="password" id="password"><input type="checkbox" id="showPassword">
<script evalwrite="repeatedly">document.getElementById('showPassword').checked?document.getElementById('password').value:''</script>
</div>
<div class="red">password reveal example (using "triggered")</div>
<div>
<script>function updatePasswordReveal(){evalWriteElement(document.all.pr2)}</script>
<input type="password" id="password2" oninput="updatePasswordReveal()"><input type="checkbox" id="showPassword2" oninput="updatePasswordReveal()">
<script id="pr2" evalwrite="triggered">document.getElementById('showPassword2').checked?document.getElementById('password2').value:''</script>
</div>
<div class="red">introduction of "triggered" type, compared to a "repeatedly" type</div>
<div><button onclick="counter++">+</button><script evalwrite="repeatedly">counter</script></div>
<div><button onclick="counter++;evalWriteElement(document.all.tew)">+</button><script evalwrite="triggered" id="tew">counter</script></div>
<script>
class Counter{
constructor(){ self.number = 1}
get n(){ return self.number }
set n(x){
self.number=x
evalWriteElement(document.all.tew2)
}
}
counterObj=new Counter()
</script>
<div><button onclick="counterObj.n++">+</button><script evalwrite="triggered" id="tew2">counterObj.n</script></div>
<div class="red">embeddedjs="repeatedly" test/example</div>
<div><span id="counter" embeddedjs="repeatedly">counter=<%= counter %></span></div>
<div class="red">embeddedjs="triggered" test/example (THIS allows a kind of "2-way data-binding")</div>
<div embeddedjs="triggered" id="bind">
<input value="<%= variable %>" oninput="variable=this.value">
<button onclick="changeVarTriggerDemo()">changeVarTriggerDemo()</button>
</div>
<script>
var variable='variable1'
function changeVarTriggerDemo(){
variable=variable+"123"; ejsWriteElement(document.all.bind)
}</script></body></html>