-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathform_table.rb
131 lines (109 loc) · 3.74 KB
/
form_table.rb
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
require 'glimmer-dsl-libui'
Contact = Struct.new(:name, :email, :phone, :city, :state) do
def valid?
values.map(&:to_s).any?(&:empty?)
end
def reset
self.name = ''
self.email = ''
self.phone = ''
self.city = ''
self.state = ''
end
end
class FormTablePresenter
attr_accessor :contacts, :filter_value, :unfiltered_contacts
def initialize
@contacts = [
Contact.new('Lisa Sky', '[email protected]', '720-523-4329', 'Denver', 'CO'),
Contact.new('Jordan Biggins', '[email protected]', '617-528-5399', 'Boston', 'MA'),
Contact.new('Mary Glass', '[email protected]', '847-589-8788', 'Elk Grove Village', 'IL'),
Contact.new('Darren McGrath', '[email protected]', '206-539-9283', 'Seattle', 'WA'),
Contact.new('Melody Hanheimer', '[email protected]', '213-493-8274', 'Los Angeles', 'CA'),
]
end
def new_contact
@new_contact ||= Contact.new
end
def save_contact
contacts << new_contact.dup # automatically inserts a row into the table due to explicit data-binding
self.unfiltered_contacts = contacts.dup
new_contact.reset # automatically clears form fields through explicit data-binding
end
def filter_table
self.unfiltered_contacts ||= contacts.dup
# Unfilter first to remove any previous filters
self.contacts = unfiltered_contacts.dup # affects table indirectly through explicit data-binding
# Now, apply filter if entered
unless filter_value.empty?
self.contacts = contacts.filter do |contact| # affects table indirectly through explicit data-binding
contact.members.any? do |attribute|
contact[attribute].to_s.downcase.include?(filter_value.downcase)
end
end
end
end
end
class FormTable
include Glimmer
def initialize
@presenter = FormTablePresenter.new
end
def launch
window('Contacts', 600, 600) {
margined true
vertical_box {
form {
stretchy false
entry {
label 'Name'
text <=> [@presenter.new_contact, :name] # bidirectional data-binding between entry text and @presenter.name
}
entry {
label 'Email'
text <=> [@presenter.new_contact, :email]
}
entry {
label 'Phone'
text <=> [@presenter.new_contact, :phone]
}
entry {
label 'City'
text <=> [@presenter.new_contact, :city]
}
entry {
label 'State'
text <=> [@presenter.new_contact, :state]
}
}
button('Save Contact') {
stretchy false
on_clicked do
if @presenter.new_contact.valid?
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
else
@presenter.save_contact
end
end
}
search_entry {
stretchy false
# bidirectional data-binding of text to @presenter.filter_value, filtering table after writing value to Model
text <=> [@presenter, :filter_value,
after_write: ->(filter_value) { @presenter.filter_table }
]
}
table {
text_column('Name')
text_column('Email')
text_column('Phone')
text_column('City')
text_column('State')
editable true
cell_rows <=> [@presenter, :contacts] # explicit data-binding to @presenter.contacts Model Array, auto-inferring model attribute names from underscored table column names by convention
}
}
}.show
end
end
FormTable.new.launch