-
Notifications
You must be signed in to change notification settings - Fork 17
/
form_table3.rb
119 lines (99 loc) · 3.95 KB
/
form_table3.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
require 'glimmer-dsl-libui'
class FormTable
Contact = Struct.new(:full_name, :email_address, :phone_number, :city_or_town, :state_or_province)
include Glimmer
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
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 launch
window('Contacts', 600, 600) {
margined true
vertical_box {
form {
stretchy false
entry {
label 'Name'
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
}
entry {
label 'Email'
text <=> [self, :email]
}
entry {
label 'Phone'
text <=> [self, :phone]
}
entry {
label 'City'
text <=> [self, :city]
}
entry {
label 'State'
text <=> [self, :state]
}
}
button('Save Contact') {
stretchy false
on_clicked do
new_row = [name, email, phone, city, state]
if new_row.map(&:to_s).include?('')
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
else
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
@unfiltered_contacts = @contacts.dup
self.name = '' # automatically clears name entry through explicit data-binding
self.email = ''
self.phone = ''
self.city = ''
self.state = ''
end
end
}
search_entry {
stretchy false
# bidirectional data-binding of text to self.filter_value with after_write option
text <=> [self, :filter_value,
after_write: ->(filter_value) { # execute after write to self.filter_value
@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
}
]
}
table {
text_column('Name')
text_column('Email')
text_column('Phone')
text_column('City')
text_column('State')
editable true
cell_rows <=> [self, :contacts, column_attributes: [:full_name, :email_address, :phone_number, :city_or_town, :state_or_province]] # explicit data-binding to Model Array with column_attributes mapping for all columns
on_changed do |row, type, row_data|
puts "Row #{row} #{type}: #{row_data}"
$stdout.flush # for Windows
end
on_edited do |row, row_data| # only fires on direct table editing
puts "Row #{row} edited: #{row_data}"
$stdout.flush # for Windows
end
}
}
}.show
end
end
FormTable.new.launch