glimmer-dsl-web 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +472 -31
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +9 -5
- data/lib/glimmer/dsl/web/dsl.rb +6 -2
- data/lib/glimmer/dsl/web/element_expression.rb +2 -2
- data/lib/glimmer/dsl/web/listener_expression.rb +19 -0
- data/lib/glimmer/dsl/web/property_expression.rb +23 -0
- data/lib/glimmer/util/proc_tracker.rb +1 -1
- data/lib/glimmer/web/element_proxy.rb +118 -82
- data/lib/glimmer/web/listener_proxy.rb +39 -0
- data/lib/glimmer/web.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_button.rb +99 -0
- data/lib/glimmer-dsl-web/samples/hello/hello_world.rb +1 -1
- data/lib/glimmer-dsl-web.rb +1 -1
- metadata +11 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64730435caff848fd16bfad099963c9c3d6298da78af51bb0bbcbd9c41ed5ca9
|
4
|
+
data.tar.gz: 80cb8d417c40726210eab103ace178016c9595b2d123f931ab9dd2e6469e37ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4964424f7ccc8b35257d5c28b28749f8ee9fcc0be889d498c17ff3a81faac173fc9d3ae2d1d4a0818a0af7685a3e88dd2885b4733cc213995a54c7d76a6f3443
|
7
|
+
data.tar.gz: 4d9cb434aa3d62053f98351ec38c821198f2426cdc00503d6a0f2eefd402377a4158f80a504942e966df2c95f7b2ee1644bea199c1f63011fe0c719e9cb27628
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,24 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.4
|
4
|
+
|
5
|
+
- Support nesting attributes/properties under element (e.g. `input { value 'something'; dir 'rtl' }`)
|
6
|
+
- Ensure when calling `element#remove`, all its listeners and children are removed cleanly too (e.g. calling `button.remove` automatically unregisters `on_click` listener)
|
7
|
+
|
8
|
+
## 0.0.3
|
9
|
+
|
10
|
+
- Set Glimmer specific element attributes (e.g. `parent`) as data attributes on generated HTML elements
|
11
|
+
- Support setting text content by passing as first argument to an element as an alternative to block return value
|
12
|
+
- Proxy method/attribute invocations on an element to its HTML element (e.g. `input_element.check_validity` proxies to `checkValidity` JS function)
|
13
|
+
- Support JS listeners like `onclick` by nesting an `on_someeventname` block under an element (e.g. `on_click { ... }`)
|
14
|
+
- New Hello, Button! Sample: `require 'glimmer-dsl-web/samples/hello/hello_button'`
|
15
|
+
|
3
16
|
## 0.0.2
|
4
17
|
|
5
18
|
- Rename element `:root` option to `:parent` option
|
6
19
|
- Set `body` as parent by default if `:parent` option is not specified for a root element
|
7
|
-
- `glimmer-dsl-web/samples/hello/hello_world.rb`
|
8
20
|
- Set `class` instead of `id` on generated HTML elements to identify them (e.g. `element-2`).
|
21
|
+
- New Hello, World! Sample: `require 'glimmer-dsl-web/samples/hello/hello_world'`
|
9
22
|
|
10
23
|
## 0.0.1
|
11
24
|
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.0.
|
2
|
-
## Ruby in the Browser Web GUI Library
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.0.4 (Early Alpha)
|
2
|
+
## Ruby in the Browser Web GUI Frontend Library
|
3
3
|
[](http://badge.fury.io/rb/glimmer-dsl-web)
|
4
4
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
5
|
|
@@ -29,12 +29,14 @@ require 'glimmer-dsl-web'
|
|
29
29
|
|
30
30
|
include Glimmer
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
'
|
36
|
-
|
37
|
-
}
|
32
|
+
Document.ready? do
|
33
|
+
# This will hook into element #app-container and then build HTML inside it using Ruby DSL code
|
34
|
+
div(parent: '#app-container') {
|
35
|
+
label(class: 'greeting') {
|
36
|
+
'Hello, World!'
|
37
|
+
}
|
38
|
+
}.render
|
39
|
+
end
|
38
40
|
```
|
39
41
|
|
40
42
|
That produces:
|
@@ -42,7 +44,7 @@ That produces:
|
|
42
44
|
```html
|
43
45
|
...
|
44
46
|
<div id="app-container">
|
45
|
-
<div parent="#app-container" class="element element-1">
|
47
|
+
<div data-parent="#app-container" class="element element-1">
|
46
48
|
<label class="greeting element element-2">
|
47
49
|
Hello, World!
|
48
50
|
</label>
|
@@ -51,6 +53,8 @@ That produces:
|
|
51
53
|
...
|
52
54
|
```
|
53
55
|
|
56
|
+

|
57
|
+
|
54
58
|
**Hello, World! Sample**
|
55
59
|
|
56
60
|
Glimmer GUI code:
|
@@ -70,13 +74,183 @@ end
|
|
70
74
|
That produces the following under `<body></body>`:
|
71
75
|
|
72
76
|
```html
|
73
|
-
<div parent="body" class="element element-1">
|
77
|
+
<div data-parent="body" class="element element-1">
|
74
78
|
Hello, World!
|
75
79
|
</div>
|
76
80
|
```
|
77
81
|
|
82
|
+

|
83
|
+
|
78
84
|
**Hello, Button! Sample**
|
79
85
|
|
86
|
+
Glimmer GUI code:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
require 'glimmer-dsl-web'
|
90
|
+
|
91
|
+
include Glimmer
|
92
|
+
|
93
|
+
Document.ready? do
|
94
|
+
div {
|
95
|
+
h1('Contact Form')
|
96
|
+
form {
|
97
|
+
div(class: 'field-row') {
|
98
|
+
label('Name: ', for: 'name-field')
|
99
|
+
@name_input = input(id: 'name-field', class: 'field', type: 'text', required: true)
|
100
|
+
}
|
101
|
+
div(class: 'field-row') {
|
102
|
+
label('Email: ', for: 'email-field')
|
103
|
+
@email_input = input(id: 'email-field', class: 'field', type: 'email', required: true)
|
104
|
+
}
|
105
|
+
button('Add Contact', class: 'submit-button') {
|
106
|
+
on_click do
|
107
|
+
if ([@name_input, @email_input].all? {|input| input.check_validity })
|
108
|
+
@table.content {
|
109
|
+
tr {
|
110
|
+
td { @name_input.value }
|
111
|
+
td { @email_input.value }
|
112
|
+
}
|
113
|
+
}
|
114
|
+
@email_input.value = @name_input.value = ''
|
115
|
+
else
|
116
|
+
error_messages = []
|
117
|
+
error_messages << "Name is not valid! Make sure it is filled." if !@name_input.check_validity
|
118
|
+
error_messages << "Email is not valid! Make sure it is filled and has a valid format." if !@email_input.check_validity
|
119
|
+
$$.alert(error_messages.join("\n"))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
}
|
123
|
+
}
|
124
|
+
h1('Contacts Table')
|
125
|
+
@table = table {
|
126
|
+
tr {
|
127
|
+
th('Name')
|
128
|
+
th('Email')
|
129
|
+
}
|
130
|
+
tr {
|
131
|
+
td('John Doe')
|
132
|
+
td('johndoe@example.com')
|
133
|
+
}
|
134
|
+
tr {
|
135
|
+
td('Jane Doe')
|
136
|
+
td('janedoe@example.com')
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
# CSS Styles
|
141
|
+
style {
|
142
|
+
<<~CSS
|
143
|
+
.field-row {
|
144
|
+
margin: 10px 5px;
|
145
|
+
}
|
146
|
+
.field {
|
147
|
+
margin-left: 5px;
|
148
|
+
}
|
149
|
+
.submit-button {
|
150
|
+
display: block;
|
151
|
+
margin: 10px 5px;
|
152
|
+
}
|
153
|
+
table {
|
154
|
+
border:1px solid grey;
|
155
|
+
border-spacing: 0;
|
156
|
+
}
|
157
|
+
table tr td, table tr th {
|
158
|
+
padding: 5px;
|
159
|
+
}
|
160
|
+
table tr:nth-child(even) {
|
161
|
+
background: #ccc;
|
162
|
+
}
|
163
|
+
CSS
|
164
|
+
}
|
165
|
+
}.render
|
166
|
+
end
|
167
|
+
```
|
168
|
+
|
169
|
+
That produces the following under `<body></body>`:
|
170
|
+
|
171
|
+
```html
|
172
|
+
<div data-parent="body" class="element element-1">
|
173
|
+
<h1 class="element element-2">Contact Form</h1>
|
174
|
+
<form class="element element-3">
|
175
|
+
<div class="field-row element element-4">
|
176
|
+
<label for="name-field" class="element element-5">Name: </label>
|
177
|
+
<input id="name-field" class="field element element-6" type="text" required="true">
|
178
|
+
</div>
|
179
|
+
<div class="field-row element element-7">
|
180
|
+
<label for="email-field" class="element element-8">Email: </label>
|
181
|
+
<input id="email-field" class="field element element-9" type="email" required="true">
|
182
|
+
</div>
|
183
|
+
<button class="submit-button element element-10">Add Contact</button>
|
184
|
+
</form>
|
185
|
+
<h1 class="element element-11">Contacts Table</h1>
|
186
|
+
<table class="element element-12">
|
187
|
+
<tr class="element element-13">
|
188
|
+
<th class="element element-14">Name</th>
|
189
|
+
<th class="element element-15">Email</th>
|
190
|
+
</tr>
|
191
|
+
<tr class="element element-16">
|
192
|
+
<td class="element element-17">John Doe</td>
|
193
|
+
<td class="element element-18">johndoe@example.com</td>
|
194
|
+
</tr>
|
195
|
+
<tr class="element element-19">
|
196
|
+
<td class="element element-20">Jane Doe</td>
|
197
|
+
<td class="element element-21">janedoe@example.com</td>
|
198
|
+
</tr>
|
199
|
+
</table>
|
200
|
+
<style class="element element-22">.field-row {
|
201
|
+
margin: 10px 5px;
|
202
|
+
}
|
203
|
+
.field {
|
204
|
+
margin-left: 5px;
|
205
|
+
}
|
206
|
+
.submit-button {
|
207
|
+
display: block;
|
208
|
+
margin: 10px 5px;
|
209
|
+
}
|
210
|
+
table {
|
211
|
+
border:1px solid grey;
|
212
|
+
border-spacing: 0;
|
213
|
+
}
|
214
|
+
table tr td, table tr th {
|
215
|
+
padding: 5px;
|
216
|
+
}
|
217
|
+
table tr:nth-child(even) {
|
218
|
+
background: #ccc;
|
219
|
+
}
|
220
|
+
</style>
|
221
|
+
</div>
|
222
|
+
```
|
223
|
+
|
224
|
+
Screenshots:
|
225
|
+
|
226
|
+
---
|
227
|
+
|
228
|
+
***Hello, Button!***
|
229
|
+
|
230
|
+

|
231
|
+
|
232
|
+
---
|
233
|
+
|
234
|
+
***Hello, Button! Submitted Invalid Data***
|
235
|
+
|
236
|
+

|
237
|
+
|
238
|
+
---
|
239
|
+
|
240
|
+
***Hello, Button! Filled Valid Name and Email***
|
241
|
+
|
242
|
+

|
243
|
+
|
244
|
+
---
|
245
|
+
|
246
|
+
***Hello, Button! Added Contact***
|
247
|
+
|
248
|
+

|
249
|
+
|
250
|
+
---
|
251
|
+
|
252
|
+
**Button Counter Sample**
|
253
|
+
|
80
254
|
**UPCOMING (NOT RELEASED OR SUPPORTED YET)**
|
81
255
|
|
82
256
|
Glimmer GUI code demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
|
@@ -106,7 +280,7 @@ class HelloButton
|
|
106
280
|
markup {
|
107
281
|
# This will hook into element #app-container and then build HTML inside it using Ruby DSL code
|
108
282
|
div(root_css_selector) {
|
109
|
-
text '
|
283
|
+
text 'Button Counter'
|
110
284
|
|
111
285
|
button {
|
112
286
|
# Unidirectional Data-Binding indicating that on every change to @counter.count, the value
|
@@ -170,11 +344,13 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
170
344
|
- [Background](#background)
|
171
345
|
- [Prerequisites](#prerequisites)
|
172
346
|
- [Setup](#setup)
|
347
|
+
- [Usage](#usage)
|
173
348
|
- [Supported Glimmer DSL Keywords](#supported-glimmer-dsl-keywords)
|
174
349
|
- [Samples](#samples)
|
175
350
|
- [Hello Samples](#hello-samples)
|
176
351
|
- [Hello, World!](#hello-world)
|
177
352
|
- [Hello, Button!](#hello-button)
|
353
|
+
- [Button Counter](#button-counter)
|
178
354
|
- [Glimmer Process](#glimmer-process)
|
179
355
|
- [Help](#help)
|
180
356
|
- [Issues](#issues)
|
@@ -187,6 +363,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
187
363
|
|
188
364
|
## Prerequisites
|
189
365
|
|
366
|
+
- Ruby 3.0 (newer Ruby versions are not supported at this time)
|
190
367
|
- Rails 6-7: [https://github.com/rails/rails](https://github.com/rails/rails)
|
191
368
|
- Opal 1.4.1 for Rails 6-7 or Opal 1.0.5 for Rails 5: [https://github.com/opal/opal](https://github.com/opal/opal)
|
192
369
|
- Opal-Rails 2.0.2 for Rails 6-7 or Opal-Rails 1.1.2 for Rails 5: [https://github.com/opal/opal-rails](https://github.com/opal/opal-rails)
|
@@ -221,7 +398,7 @@ gem 'opal', '1.4.1'
|
|
221
398
|
gem 'opal-rails', '2.0.2'
|
222
399
|
gem 'opal-async', '~> 1.4.0'
|
223
400
|
gem 'opal-jquery', '~> 0.4.6'
|
224
|
-
gem 'glimmer-dsl-web', '~> 0.0.
|
401
|
+
gem 'glimmer-dsl-web', '~> 0.0.4'
|
225
402
|
gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
|
226
403
|
gem 'glimmer-dsl-css', '~> 1.2.1', require: false
|
227
404
|
```
|
@@ -298,12 +475,14 @@ require 'glimmer-dsl-web'
|
|
298
475
|
|
299
476
|
include Glimmer
|
300
477
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
'
|
305
|
-
|
306
|
-
}
|
478
|
+
Document.ready? do
|
479
|
+
# This will hook into element #app-container and then build HTML inside it using Ruby DSL code
|
480
|
+
div(parent: '#app-container') {
|
481
|
+
label(class: 'greeting') {
|
482
|
+
'Hello, World!'
|
483
|
+
}
|
484
|
+
}.render
|
485
|
+
end
|
307
486
|
```
|
308
487
|
|
309
488
|
That produces:
|
@@ -311,7 +490,7 @@ That produces:
|
|
311
490
|
```html
|
312
491
|
...
|
313
492
|
<div id="app-container">
|
314
|
-
<div parent="#app-container" class="element element-1">
|
493
|
+
<div data-parent="#app-container" class="element element-1">
|
315
494
|
<label class="greeting element element-2">
|
316
495
|
Hello, World!
|
317
496
|
</label>
|
@@ -364,7 +543,7 @@ gem 'opal', '1.4.1'
|
|
364
543
|
gem 'opal-rails', '2.0.2'
|
365
544
|
gem 'opal-async', '~> 1.4.0'
|
366
545
|
gem 'opal-jquery', '~> 0.4.6'
|
367
|
-
gem 'glimmer-dsl-web', '~> 0.0.
|
546
|
+
gem 'glimmer-dsl-web', '~> 0.0.4'
|
368
547
|
gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
|
369
548
|
gem 'glimmer-dsl-css', '~> 1.2.1', require: false
|
370
549
|
```
|
@@ -445,12 +624,14 @@ require 'glimmer-dsl-web'
|
|
445
624
|
|
446
625
|
include Glimmer
|
447
626
|
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
'
|
452
|
-
|
453
|
-
}
|
627
|
+
Document.ready? do
|
628
|
+
# This will hook into element #app-container and then build HTML inside it using Ruby DSL code
|
629
|
+
div(parent: '#app-container') {
|
630
|
+
label(class: 'greeting') {
|
631
|
+
'Hello, World!'
|
632
|
+
}
|
633
|
+
}.render
|
634
|
+
end
|
454
635
|
```
|
455
636
|
|
456
637
|
That produces:
|
@@ -458,7 +639,7 @@ That produces:
|
|
458
639
|
```html
|
459
640
|
...
|
460
641
|
<div id="app-container">
|
461
|
-
<div parent="#app-container" class="element element-1">
|
642
|
+
<div data-parent="#app-container" class="element element-1">
|
462
643
|
<label class="greeting element element-2">
|
463
644
|
Hello, World!
|
464
645
|
</label>
|
@@ -484,11 +665,79 @@ If you run into any issues in setup, refer to the [Sample Glimmer DSL for Web Ra
|
|
484
665
|
|
485
666
|
Otherwise, if you still cannot setup successfully (even with the help of the sample project, or if the sample project stops working), please do not hesitate to report an [Issue request](https://github.com/AndyObtiva/glimmer-dsl-web/issues) or fix and submit a [Pull Request](https://github.com/AndyObtiva/glimmer-dsl-web/pulls).
|
486
667
|
|
668
|
+
## Usage
|
669
|
+
|
670
|
+
Glimmer DSL for Web offers a GUI DSL for building HTML Web User Interfaces declaratively in Ruby.
|
671
|
+
|
672
|
+
1- Keywords (HTML Elements)
|
673
|
+
|
674
|
+
You can declare any HTML element by simply using the lowercase underscored version of its name (Ruby convention for method names) like `div`, `span`, `form`, `input`, `button`, `table`, `tr`, `th`, and `td`.
|
675
|
+
|
676
|
+
Under the hood, HTML element DSL keywords are invoked as Ruby methods.
|
677
|
+
|
678
|
+
2- Arguments (HTML Attributes + Text Content)
|
679
|
+
|
680
|
+
You can set any HTML element attributes by passing as keyword arguments to element methods like `div(id: 'container', class: 'stack')` or `input(type: 'email', required: true)`
|
681
|
+
|
682
|
+
Also, if the element has a little bit of text content that can fit in one line, it can be passed as the 1st argument like `label('Name: ', for: 'name_field')`, `button('Calculate', class: 'round-button')`, or `span('Mr')`
|
683
|
+
|
684
|
+
3- Content Block (Properties + Listeners + Nested Elements + Text Content)
|
685
|
+
|
686
|
+
Element methods can accept a Ruby content block. It intentionally has a `{...}` style even as a multi-line block to indicate that the code is declarative GUI structure code.
|
687
|
+
|
688
|
+
You can nest HTML element properties under an element like:
|
689
|
+
|
690
|
+
```ruby
|
691
|
+
input(type: 'text') {
|
692
|
+
content_editable false
|
693
|
+
}
|
694
|
+
```
|
695
|
+
|
696
|
+
You can nest HTML event listeners under an element by using a more friendly underscored version of listener properties (e.g. `onclick` becomes `on_click`):
|
697
|
+
|
698
|
+
```ruby
|
699
|
+
button('Add') {
|
700
|
+
on_click do
|
701
|
+
@model.add_selected_element
|
702
|
+
end
|
703
|
+
}
|
704
|
+
```
|
705
|
+
|
706
|
+
Given that listener code is imperative, it uses a `do; end` style for Ruby blocks to separate it from declarative GUI structure code and enable quicker readability of the code.
|
707
|
+
|
708
|
+
You can nest other HTML elements under an HTML element the same way you do so in HTML, like:
|
709
|
+
|
710
|
+
```ruby
|
711
|
+
form {
|
712
|
+
div(class: 'field-row') {
|
713
|
+
label('Name: ', for: 'name-field')
|
714
|
+
input(id: 'name-field', class: 'field', type: 'text', required: true)
|
715
|
+
}
|
716
|
+
div(class: 'field-row') {
|
717
|
+
label('Email: ', for: 'email-field')
|
718
|
+
input(id: 'email-field', class: 'field', type: 'email', required: true)
|
719
|
+
}
|
720
|
+
button('Add Contact', class: 'submit-button') {
|
721
|
+
on_click do
|
722
|
+
...
|
723
|
+
end
|
724
|
+
}
|
725
|
+
}
|
726
|
+
```
|
727
|
+
|
728
|
+
You can nest text content underneath an element's Ruby block, like:
|
729
|
+
|
730
|
+
```ruby
|
731
|
+
span(class: 'summary') {
|
732
|
+
'This text content is going into the body of the span element'
|
733
|
+
}
|
734
|
+
```
|
735
|
+
|
487
736
|
## Supported Glimmer DSL Keywords
|
488
737
|
|
489
|
-
All HTML elements.
|
738
|
+
[All HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element).
|
490
739
|
|
491
|
-
All HTML attributes.
|
740
|
+
[All HTML attributes](https://www.w3schools.com/html/html_attributes.asp).
|
492
741
|
|
493
742
|
## Samples
|
494
743
|
|
@@ -519,13 +768,205 @@ end
|
|
519
768
|
That produces the following under `<body></body>`:
|
520
769
|
|
521
770
|
```html
|
522
|
-
<div parent="body" class="element element-1">
|
771
|
+
<div data-parent="body" class="element element-1">
|
772
|
+
Hello, World!
|
773
|
+
</div>
|
774
|
+
```
|
775
|
+
|
776
|
+

|
777
|
+
|
778
|
+
Alternative syntax when an element only has text content:
|
779
|
+
|
780
|
+
```ruby
|
781
|
+
require 'glimmer-dsl-web'
|
782
|
+
|
783
|
+
include Glimmer
|
784
|
+
|
785
|
+
Document.ready? do
|
786
|
+
div('Hello, World!').render
|
787
|
+
end
|
788
|
+
```
|
789
|
+
|
790
|
+
That produces the following under `<body></body>`:
|
791
|
+
|
792
|
+
```html
|
793
|
+
<div data-parent="body" class="element element-1">
|
523
794
|
Hello, World!
|
524
795
|
</div>
|
525
796
|
```
|
526
797
|
|
798
|
+

|
799
|
+
|
527
800
|
#### Hello, Button!
|
528
801
|
|
802
|
+
Glimmer GUI code:
|
803
|
+
|
804
|
+
```ruby
|
805
|
+
require 'glimmer-dsl-web'
|
806
|
+
|
807
|
+
include Glimmer
|
808
|
+
|
809
|
+
Document.ready? do
|
810
|
+
div {
|
811
|
+
h1('Contact Form')
|
812
|
+
form {
|
813
|
+
div(class: 'field-row') {
|
814
|
+
label('Name: ', for: 'name-field')
|
815
|
+
@name_input = input(id: 'name-field', class: 'field', type: 'text', required: true)
|
816
|
+
}
|
817
|
+
div(class: 'field-row') {
|
818
|
+
label('Email: ', for: 'email-field')
|
819
|
+
@email_input = input(id: 'email-field', class: 'field', type: 'email', required: true)
|
820
|
+
}
|
821
|
+
button('Add Contact', class: 'submit-button') {
|
822
|
+
on_click do
|
823
|
+
if ([@name_input, @email_input].all? {|input| input.check_validity })
|
824
|
+
@table.content {
|
825
|
+
tr {
|
826
|
+
td { @name_input.value }
|
827
|
+
td { @email_input.value }
|
828
|
+
}
|
829
|
+
}
|
830
|
+
@email_input.value = @name_input.value = ''
|
831
|
+
else
|
832
|
+
error_messages = []
|
833
|
+
error_messages << "Name is not valid! Make sure it is filled." if !@name_input.check_validity
|
834
|
+
error_messages << "Email is not valid! Make sure it is filled and has a valid format." if !@email_input.check_validity
|
835
|
+
$$.alert(error_messages.join("\n"))
|
836
|
+
end
|
837
|
+
end
|
838
|
+
}
|
839
|
+
}
|
840
|
+
h1('Contacts Table')
|
841
|
+
@table = table {
|
842
|
+
tr {
|
843
|
+
th('Name')
|
844
|
+
th('Email')
|
845
|
+
}
|
846
|
+
tr {
|
847
|
+
td('John Doe')
|
848
|
+
td('johndoe@example.com')
|
849
|
+
}
|
850
|
+
tr {
|
851
|
+
td('Jane Doe')
|
852
|
+
td('janedoe@example.com')
|
853
|
+
}
|
854
|
+
}
|
855
|
+
|
856
|
+
# CSS Styles
|
857
|
+
style {
|
858
|
+
<<~CSS
|
859
|
+
.field-row {
|
860
|
+
margin: 10px 5px;
|
861
|
+
}
|
862
|
+
.field {
|
863
|
+
margin-left: 5px;
|
864
|
+
}
|
865
|
+
.submit-button {
|
866
|
+
display: block;
|
867
|
+
margin: 10px 5px;
|
868
|
+
}
|
869
|
+
table {
|
870
|
+
border:1px solid grey;
|
871
|
+
border-spacing: 0;
|
872
|
+
}
|
873
|
+
table tr td, table tr th {
|
874
|
+
padding: 5px;
|
875
|
+
}
|
876
|
+
table tr:nth-child(even) {
|
877
|
+
background: #ccc;
|
878
|
+
}
|
879
|
+
CSS
|
880
|
+
}
|
881
|
+
}.render
|
882
|
+
end
|
883
|
+
```
|
884
|
+
|
885
|
+
That produces the following under `<body></body>`:
|
886
|
+
|
887
|
+
```html
|
888
|
+
<div data-parent="body" class="element element-1">
|
889
|
+
<h1 class="element element-2">Contact Form</h1>
|
890
|
+
<form class="element element-3">
|
891
|
+
<div class="field-row element element-4">
|
892
|
+
<label for="name-field" class="element element-5">Name: </label>
|
893
|
+
<input id="name-field" class="field element element-6" type="text" required="true">
|
894
|
+
</div>
|
895
|
+
<div class="field-row element element-7">
|
896
|
+
<label for="email-field" class="element element-8">Email: </label>
|
897
|
+
<input id="email-field" class="field element element-9" type="email" required="true">
|
898
|
+
</div>
|
899
|
+
<button class="submit-button element element-10">Add Contact</button>
|
900
|
+
</form>
|
901
|
+
<h1 class="element element-11">Contacts Table</h1>
|
902
|
+
<table class="element element-12">
|
903
|
+
<tr class="element element-13">
|
904
|
+
<th class="element element-14">Name</th>
|
905
|
+
<th class="element element-15">Email</th>
|
906
|
+
</tr>
|
907
|
+
<tr class="element element-16">
|
908
|
+
<td class="element element-17">John Doe</td>
|
909
|
+
<td class="element element-18">johndoe@example.com</td>
|
910
|
+
</tr>
|
911
|
+
<tr class="element element-19">
|
912
|
+
<td class="element element-20">Jane Doe</td>
|
913
|
+
<td class="element element-21">janedoe@example.com</td>
|
914
|
+
</tr>
|
915
|
+
</table>
|
916
|
+
<style class="element element-22">.field-row {
|
917
|
+
margin: 10px 5px;
|
918
|
+
}
|
919
|
+
.field {
|
920
|
+
margin-left: 5px;
|
921
|
+
}
|
922
|
+
.submit-button {
|
923
|
+
display: block;
|
924
|
+
margin: 10px 5px;
|
925
|
+
}
|
926
|
+
table {
|
927
|
+
border:1px solid grey;
|
928
|
+
border-spacing: 0;
|
929
|
+
}
|
930
|
+
table tr td, table tr th {
|
931
|
+
padding: 5px;
|
932
|
+
}
|
933
|
+
table tr:nth-child(even) {
|
934
|
+
background: #ccc;
|
935
|
+
}
|
936
|
+
</style>
|
937
|
+
</div>
|
938
|
+
```
|
939
|
+
|
940
|
+
Screenshots:
|
941
|
+
|
942
|
+
---
|
943
|
+
|
944
|
+
***Hello, Button!***
|
945
|
+
|
946
|
+

|
947
|
+
|
948
|
+
---
|
949
|
+
|
950
|
+
***Hello, Button! Submitted Invalid Data***
|
951
|
+
|
952
|
+

|
953
|
+
|
954
|
+
---
|
955
|
+
|
956
|
+
***Hello, Button! Filled Valid Name and Email***
|
957
|
+
|
958
|
+

|
959
|
+
|
960
|
+
---
|
961
|
+
|
962
|
+
***Hello, Button! Added Contact***
|
963
|
+
|
964
|
+

|
965
|
+
|
966
|
+
---
|
967
|
+
|
968
|
+
#### Button Counter
|
969
|
+
|
529
970
|
**UPCOMING (NOT RELEASED OR SUPPORTED YET)**
|
530
971
|
|
531
972
|
Glimmer GUI code demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
|
@@ -555,7 +996,7 @@ class HelloButton
|
|
555
996
|
markup {
|
556
997
|
# This will hook into element #app-container and then build HTML inside it using Ruby DSL code
|
557
998
|
div(root_css_selector) {
|
558
|
-
text '
|
999
|
+
text 'Button Counter'
|
559
1000
|
|
560
1001
|
button {
|
561
1002
|
# Unidirectional Data-Binding indicating that on every change to @counter.count, the value
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|