-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
231 lines (184 loc) · 9.64 KB
/
index.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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<!DOCTYPE html>
<html lang>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>heatmeal.js - How pure HTML should be</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+Code+Latin:[email protected]&display=swap');
html { font-family: "M PLUS Code Latin", sans-serif; font-size: 1.2rem; color: #CCC; background: #222; }
body { margin: 0 auto; }
header { padding: 40px 10px; background:#2e2e2e; border-bottom: 2px solid #444; }
header h1, header h3 { margin: 0; }
header h1 { font-size: 3rem; text-align: center; }
header h3 { text-align: center; }
main { margin: 0 auto; padding: 30px 10px; max-width: 700px; }
footer { padding: 10px 10px; font-size: 0.8rem; text-align: center; background:#2e2e2e; border-top: 2px solid #444; }
h1, h2, h3, h4, h5, h6 { font-weight: 500; color: #FFF; }
h2, h3 { margin-top: 50px; }
a { color: #CCC; }
button, input[type=submit] {
padding: 10px 20px; font-family: inherit; font-size: 1.0rem; color: #CCC;
cursor: pointer; background: #333; border: none; box-shadow: 4px 4px 0 #444;
}
button:active, input[type=submit]:active { margin: 4px -4px -4px 4px; background: #444; box-shadow: none; }
code { padding: 1px 4px; font-size: 0.9rem; font-weight: bold; border: 1px solid #DDD; }
.red { color: #B22 !important; }
.gray { color: #555; }
.inline-block { display: inline-block; }
.example { margin: 10px 0; padding: 25px; color: #FFF; background: #333 }
</style>
<script src="https://gogs.com.br/chili/chili.js" defer onload="chili('.highlight')"></script>
<script src="heatmeal.js"></script>
</head>
<body>
<header>
<h1>heat<span class="red">meal</span><span class="gray">.js</span></h1>
<h3>How pure HTML should be</h3>
</header>
<main>
<h2>What is it?</h2>
<p>A simple framework that enable HTML FORM to make all REST methods and enable any other elements to act as forms.</p>
<h2>Usage</h2>
<p>The only requirement to make it work is import the script src and a <code>target</code> attribute set to a classname or id.</p>
<p>TIP: Open network inspector and check the requests in real time.</p>
<h3>Form methods</h3>
<p>You can use any HTTP method, including <code>PUT</code>, <code>DELETE</code>, <code>PATCH</code> and others instead of only <code>GET</code> and <code>POST</code>.</p>
<pre class="highlight">
<script src="heatmeal.js"></script>
<form action="/example" method="DELETE" target=".example">
<input hidden name="id" value="1">
<input type="submit" value="DELETE FORM BUTTON">
</form>
<!-- OR -->
<form action="/example" target=".example">
<input hidden name="_method" value="DELETE">
<input hidden name="id" value="1">
<input type="submit" value="DELETE FORM BUTTON">
</form>
<div class="example"></div>
</pre>
<form action="./example" method="DELETE" target=".first.example" class="inline-block">
<input hidden name="id" value="1">
<input type="submit" value="DELETE FORM BUTTON">
</form>
<div class="first example" onerror="this.innerHTML = 'Resource with id 1 was deleted successfully'"></div>
<!-- This 'onerror' is only for demonstration purposes. Static website hosting doesn't implement other methods. -->
<h3>Link response</h3>
<p>You can render a link response into a <code>div</code> or any other HTML element. Just set a target attribute that references an classname or id.</p>
<pre class="highlight">
<a href="/example" target=".example">Example Link</a>
<div class="example"></div>
</pre>
<a href="./example.html" target=".second.example">Example Link</a>
<div class="second example"></div>
<h3>Using data-* attributes</h3>
<p>You can use dataset attributes to set method, action, target and request attributes instead of create a whole <code>form</code>.</p>
<pre class="highlight">
<button
data-method="POST"
data-action="/example"
data-target=".example"
data-name="Example"
>POST BUTTON</button>
<div class="example"></div>
</pre>
<button
data-method="POST"
data-action="./example"
data-target=".third.example"
data-name="Example"
>POST BUTTON</button>
<div class="third example" onerror="this.innerHTML = 'Example was created successfully'"></div>
<!-- This 'onerror' is only for demonstration purposes. Static website hosting doesn't implement other methods. -->
<h2>Lifecycle</h2>
<p>You can call javascript functions before and after request execution just using <code>onchange</code> and <code>onload</code> HTML events. Errors can be handled by <code>onerror</code> event.</p>
<h3>Before - onchange</h3>
<p>The <code>onchange</code> event should be attached to the target element and will be dispatched before <code>fetch()</code> function be invoked. This is useful to create "Loading..." feedback messages.</p>
<pre class="highlight">
<a href="/example" target=".example">Click to load</a>
<div class=".example" onchange="this.innerHTML = 'Loading...'"></div>
</pre>
<a href="./example.html" target=".fourth.example">Click to load</a>
<div class="fourth example" onchange="this.innerHTML = 'Loading...'; setTimeout(() => alert('Press any key to continue'), 0)"></div>
<h3>After - onload</h3>
<p>The <code>ononload</code> event should be attached to the target element and will be dispatched after request return and it's content be rendered in target element.</p>
<pre class="highlight">
<a href="/example.html" target=".example">Click to load</a>
<div class=".example" onload="this.classList.add('red')"></div>
</pre>
<a href="./example.html" target=".fifth.example">Click to load</a>
<div class="fifth example" onchange="this.classList.remove('red')" onload="this.classList.add('red')"></div>
<h3>Error - onerror</h3>
<p>The <code>onerror</code> event should be attached to the target element and will be dispatched if request failed. The first paramenter will be the event object and the error message is event.message.</p>
<pre class="highlight">
<a href="/example" data-method="POST" target=".example">Click to try to POST</a>
<div class=".example" onerror="this.innerHTML = event.message"></div>
</pre>
<a href="./example" data-method="POST" target=".sixth.example">Click to try to POST</a>
<div class="sixth example" onerror="this.innerHTML = event.message"></div>
<h3>Other events</h3>
<p>Any other event will be dispatched as expected while using pure HTML. You can use <code>onclick</code> event to rise a confirmation dialog or a validator.</p>
<pre class="highlight">
<button
onclick="!confirm('Are you sure?') && event.stopPropagation()"
data-method="GET"
data-href="/example.html"
data-target=".example"
>CONFIRM BUTTON</button>
<div class=".example"></div>
</pre>
<button
onclick="document.querySelector('.seventh.example').innerHTML = ''; !confirm('Are you sure?') && event.stopPropagation()"
data-method="GET"
data-href="./example.html"
data-target=".seventh.example"
>CONFIRM BUTTON</button>
<div class="seventh example"></div>
<h2>Rendering position</h2>
<p>Sometimes you may need to render the content in adjacent postion of target element or in other place. To handle this you can use <code>.insertAdjacentHTML()</code> positions adding a data-position attribute.</p>
<pre class="highlight">
<a href="/example.html" target=".example">Render</a>
<!-- beforebegin -->
<div class="example" data-position="beforebegin">
<!-- afterbegin -->
Content
<!-- beforeend -->
</div>
<!-- afterend -->
</pre>
<a href="./example.html" target=".eight.example">Render</a>
<br /><br />
<div class="eight example" data-position="beforebegin"><div><b>NEW CONTENT</b> beforebegin</div></div>
<div class="eight example" data-position="afterbegin"><div><b>NEW CONTENT</b> afterbegin</div></div>
<div class="eight example" data-position="beforeend"><div><b>NEW CONTENT</b> beforeend</div></div>
<div class="eight example" data-position="afterend"><div><b>NEW CONTENT</b> afterend</div></div>
<h2>JSON requests</h2>
<p>What if the request response is a JSON and I want to adapt a template engine to it? Just set an unknown data-position and the "onload" event.detail will be the JSON.</p>
<pre class="highlight">
<a href="./example.json" target=".example">Render</a>
<div class="ninth example" data-position="-" onload="this.innerHTML = (({ name, description }) => `
<h1>name: ${name}</h1>
<p>description: ${description}</p>
`)(event.detail)"></div>
</pre>
<a href="./example.json" target=".ninth.example">Make request</a>
<br /><br />
<div class="ninth example" data-position="-" onload="this.innerHTML = (({ name, description }) => `
<h1>name: ${name}</h1>
<p>description: ${description}</p>
`)(event.detail)"></div>
<h2>Check the code</h2>
<p>See what's happening behind the scenes. Don't be afraid, is less than 50 lines of code.</p>
<a href="./heatmeal.js" target=".sourcecode">heatmeal.js</a>
<pre class="sourcecode" onload="chili('.sourcecode')"></pre>
<h2>Download</h2>
<a href="https://github.com/henriquegogo/heatmeal">GitHub Repository</a>
<h2>License</h2>
<p>MIT</p>
</main>
<footer>
Made for fun by <a href="https://gogs.com.br" target="_blank">Henrique Gogó</a>
</footer>
</body>
</html>