ruby_mvc 0.0.1 → 0.0.2
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.
- data/README.md +14 -0
- data/lib/ruby_mvc.rb +3 -1
- data/lib/ruby_mvc/application.rb +52 -2
- data/lib/ruby_mvc/controllers.rb +28 -0
- data/lib/ruby_mvc/controllers/action.rb +93 -0
- data/lib/ruby_mvc/controllers/action_group.rb +70 -0
- data/lib/ruby_mvc/controllers/app_controller.rb +4 -2
- data/lib/ruby_mvc/controllers/rails_controller.rb +2 -0
- data/lib/ruby_mvc/models.rb +2 -0
- data/lib/ruby_mvc/models/ar_table_model.rb +133 -0
- data/lib/ruby_mvc/models/array_table_model.rb +81 -13
- data/lib/ruby_mvc/models/keyed_array_table_model.rb +1 -1
- data/lib/ruby_mvc/models/model.rb +129 -0
- data/lib/ruby_mvc/models/table_model.rb +107 -10
- data/lib/ruby_mvc/models/view_model_template.rb +140 -0
- data/lib/ruby_mvc/renderers.rb +1 -0
- data/lib/ruby_mvc/renderers/html4_table_model_renderer.rb +7 -6
- data/lib/ruby_mvc/renderers/hyperlink_cell_renderer.rb +47 -0
- data/lib/ruby_mvc/toolkit.rb +5 -1
- data/lib/ruby_mvc/toolkit/browser_history.rb +115 -0
- data/lib/ruby_mvc/toolkit/dialog.rb +12 -1
- data/lib/ruby_mvc/toolkit/frame.rb +3 -1
- data/lib/ruby_mvc/toolkit/grid_view.rb +46 -0
- data/lib/ruby_mvc/toolkit/messagebox.rb +32 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby.rb +5 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/app.rb +23 -2
- data/lib/ruby_mvc/toolkit/peers/wxruby/common.rb +11 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/dialog.rb +82 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/form_builder.rb +108 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/frame.rb +85 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_model.rb +79 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_view.rb +117 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/messagebox.rb +58 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/web_view.rb +40 -10
- data/lib/ruby_mvc/toolkit/property_change_notifier.rb +46 -0
- data/lib/ruby_mvc/toolkit/signal_handler.rb +149 -0
- data/lib/ruby_mvc/toolkit/web_view.rb +1 -1
- data/lib/ruby_mvc/toolkit/widget.rb +13 -6
- data/lib/ruby_mvc/views.rb +8 -59
- data/lib/ruby_mvc/views/{ar_type_list.rb → ar_form_view.rb} +10 -13
- data/lib/ruby_mvc/views/ar_support.rb +29 -0
- data/lib/ruby_mvc/views/ar_type_editor.rb +17 -28
- data/lib/ruby_mvc/views/ar_web_model_view.rb +59 -0
- data/lib/ruby_mvc/views/ar_web_type_list.rb +44 -0
- data/lib/ruby_mvc/views/browser_view.rb +185 -0
- data/lib/ruby_mvc/views/form_view.rb +111 -0
- data/lib/ruby_mvc/views/grid_table_view.rb +96 -0
- data/lib/ruby_mvc/views/table_view.rb +0 -39
- data/lib/ruby_mvc/views/view.rb +121 -0
- data/lib/ruby_mvc/views/web_content_table_view.rb +40 -0
- data/lib/ruby_mvc/views/{web_view.rb → web_content_view.rb} +17 -28
- data/lib/ruby_mvc/views/web_model_view.rb +67 -0
- data/ruby_mvc.gemspec +1 -1
- data/sample/browser_view.rb +57 -0
- data/sample/form.rb +59 -0
- data/sample/form2.rb +63 -0
- data/sample/grid_table_view.rb +68 -0
- data/sample/grid_view.rb +44 -0
- data/sample/grid_view2.rb +57 -0
- data/sample/test.html +1 -0
- data/sample/test2.html +33 -0
- data/sample/web_view.rb +4 -0
- data/test/unit/models/test_array_table_model.rb +19 -3
- data/test/unit/models/test_keyed_array_table_model.rb +3 -2
- data/test/unit/models/test_model.rb +88 -0
- metadata +39 -20
- data/lib/ruby_mvc/toolkit/notification.rb +0 -202
- data/lib/ruby_mvc/views/ar_model_editor.rb +0 -84
@@ -0,0 +1,29 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_support.rb
|
21
|
+
# Created: Mon 12 Dec 2011 06:49:00 CST
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
require 'ruby_mvc/views/ar_form_view'
|
27
|
+
require 'ruby_mvc/views/ar_type_editor'
|
28
|
+
require 'ruby_mvc/views/ar_web_type_list'
|
29
|
+
require 'ruby_mvc/views/ar_web_model_view'
|
@@ -26,36 +26,25 @@
|
|
26
26
|
module RubyMVC
|
27
27
|
module Views
|
28
28
|
|
29
|
-
class ActiveRecordTypeEditor <
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
window do
|
46
|
-
stack do
|
47
|
-
obj.description = "Some text"
|
48
|
-
editor = active_record_model_editor obj
|
49
|
-
flow :margin_left => 0, :left => "-25%" do
|
50
|
-
button "Cancel", :align => "right" do
|
51
|
-
close
|
52
|
-
end
|
53
|
-
button "Save", :align => "right" do
|
54
|
-
editor.save
|
55
|
-
close
|
29
|
+
class ActiveRecordTypeEditor < GridTableView
|
30
|
+
def initialize(app, parent, entity_type, options = {}, &block)
|
31
|
+
options[:editable] = false
|
32
|
+
options[:show_row_labels] = false
|
33
|
+
@model = Models::ActiveRecordTableModel.new(entity_type)
|
34
|
+
@template = options[:template]
|
35
|
+
super((@template ? @template.apply(@model) : @model), options)
|
36
|
+
signal_connect("row-edit") do |s, m, i, r|
|
37
|
+
app.dialog(:title => options[:editor_title], :parent => parent) do |dlg|
|
38
|
+
form = FormView.new((@template ? @template.apply(r) : r), &block)
|
39
|
+
form.signal_connect("form-submit") do |form, d|
|
40
|
+
begin
|
41
|
+
r.save!
|
42
|
+
m.update_row(i, r)
|
43
|
+
rescue ActiveRecord::RecordInvalid => e
|
44
|
+
app.error(e, :title => "Validation Error", :parent => dlg)
|
56
45
|
end
|
57
|
-
debug("created buttons")
|
58
46
|
end
|
47
|
+
dlg.add form
|
59
48
|
end
|
60
49
|
end
|
61
50
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011-2012 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_web_model_view.rb
|
21
|
+
# Created: Mon 9 Jan 2012 22:45:05 GMT
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
class ActiveRecordWebModelView < WebModelView
|
30
|
+
signal "row-edit"
|
31
|
+
signal "row-delete", :vetoable => true
|
32
|
+
|
33
|
+
def initialize(row, options = {})
|
34
|
+
super
|
35
|
+
|
36
|
+
action(:edit, :label => "Edit", :icon => :stock_edit) do
|
37
|
+
signal_emit("row-edit", self, row)
|
38
|
+
end
|
39
|
+
|
40
|
+
# action(:delete, :label => "Delete", :icon => :stock_delete) do
|
41
|
+
# signal_emit("row-delete", self, row)
|
42
|
+
# end
|
43
|
+
end
|
44
|
+
|
45
|
+
def render
|
46
|
+
html = super
|
47
|
+
tagz {
|
48
|
+
tagz.concat html
|
49
|
+
tagz.concat render_links
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def render_links
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011-2012 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_web_type_list.rb
|
21
|
+
# Created: Mon 9 Jan 2012 15:56:18 GMT
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
class ActiveRecordWebTypeList < WebContentTableView
|
30
|
+
def initialize(entity_type, options = {}, &block)
|
31
|
+
@model = Models::ActiveRecordTableModel.new(entity_type)
|
32
|
+
if options.is_a? Hash
|
33
|
+
@template = options[:template]
|
34
|
+
else
|
35
|
+
@template = options
|
36
|
+
options = {}
|
37
|
+
end
|
38
|
+
super((@template ? @template.apply(@model) : @model), options)
|
39
|
+
action(:edit, :label => "Edit", :icon => :stock_edit, &block)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: browser_view.rb
|
21
|
+
# Created: Mon 2 Jan 2012 22:44:26 CET
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
# This class is slightly different at the moment as it
|
30
|
+
# really should have a HypermediaContentModel instance that
|
31
|
+
# feeds it vs. being explicitly driven by the client. This
|
32
|
+
# should be addressed better in a future version.
|
33
|
+
|
34
|
+
class BrowserView < PeerView
|
35
|
+
widget Toolkit::WebView
|
36
|
+
|
37
|
+
def initialize(options = {}, &block)
|
38
|
+
super
|
39
|
+
|
40
|
+
class << action(:back,
|
41
|
+
:label => "Back", :icon => :stock_back, :widget => widget) do
|
42
|
+
go_back
|
43
|
+
end
|
44
|
+
|
45
|
+
def sensitive
|
46
|
+
x = @options[:widget].can_go_back?
|
47
|
+
property_changed(:sensitive, @sensitive, x)
|
48
|
+
@sensitive = x
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class << action(:forward,
|
53
|
+
:label => "Forward", :icon => :stock_forward, :widget => widget) do
|
54
|
+
go_forward
|
55
|
+
end
|
56
|
+
|
57
|
+
def sensitive
|
58
|
+
x = @options[:widget].can_go_forward?
|
59
|
+
property_changed(:sensitive, @sensitive, x)
|
60
|
+
@sensitive = x
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class << action(:reload,
|
65
|
+
:label => "Reload", :icon => :stock_reload, :widget => widget) do
|
66
|
+
reload
|
67
|
+
end
|
68
|
+
|
69
|
+
def sensitive
|
70
|
+
w = @options[:widget]
|
71
|
+
x = (!w.location.nil? && "" != w.location)
|
72
|
+
property_changed(:sensitive, @sensitive, x)
|
73
|
+
@sensitive = x
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
widget.signal_connect("load-finished") do
|
78
|
+
# puts "load-finished #{widget.location}"
|
79
|
+
# FIXME: this is a hack, but it's the only way for now
|
80
|
+
@actions.each { |a| a.selection(self, nil, nil); a.sensitive }
|
81
|
+
# puts "back? #{widget.can_go_back?}"
|
82
|
+
# puts "forward? #{widget.can_go_forward?}"
|
83
|
+
end
|
84
|
+
|
85
|
+
widget.signal_connect("navigation-requested") do |s, h, t|
|
86
|
+
puts "BrowserView#navigation-requested: #{h}"
|
87
|
+
if (c = self.controller)
|
88
|
+
puts "forwarding to controller: #{c}"
|
89
|
+
c.link_activated(s, h)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def go_forward
|
95
|
+
reset_actions
|
96
|
+
widget.go_forward
|
97
|
+
append_actions((location || {})[:actions])
|
98
|
+
end
|
99
|
+
|
100
|
+
def go_back
|
101
|
+
reset_actions
|
102
|
+
widget.go_back
|
103
|
+
append_actions((location || {})[:actions])
|
104
|
+
end
|
105
|
+
|
106
|
+
def open(uri)
|
107
|
+
reset_actions
|
108
|
+
widget.open(uri)
|
109
|
+
end
|
110
|
+
|
111
|
+
def load_html(*args)
|
112
|
+
reset_actions
|
113
|
+
# puts "#load_html: " << args.inspect
|
114
|
+
widget.load_html(*args)
|
115
|
+
end
|
116
|
+
|
117
|
+
def reload
|
118
|
+
if location && v = location[:view]
|
119
|
+
load(v, location[:uri])
|
120
|
+
else
|
121
|
+
super
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def append_html(*args, &block)
|
126
|
+
widget.append_html(*args, &block)
|
127
|
+
end
|
128
|
+
|
129
|
+
def load(view, uri = nil)
|
130
|
+
if !view.is_a? WebContentView
|
131
|
+
raise ArgumentError, "view must currently be a WebContentView instance"
|
132
|
+
end
|
133
|
+
|
134
|
+
# FIXME: need action support in the history management
|
135
|
+
# too so that actions are appropriately added/removed
|
136
|
+
# during forward/backward navigation requests
|
137
|
+
|
138
|
+
load_html(view.render, uri || view.uri)
|
139
|
+
widget.location[:view] = view
|
140
|
+
|
141
|
+
# If our view provides a different controller, then we
|
142
|
+
# need to defer link handling to that controller instead
|
143
|
+
# of ours (which probably wasn't defined in the first
|
144
|
+
# place)
|
145
|
+
|
146
|
+
if (vc = view.controller) && vc != self.controller
|
147
|
+
puts "assigned new controller from WebContentView: #{vc}"
|
148
|
+
self.controller = vc
|
149
|
+
else
|
150
|
+
puts "no controller defined for #{view}"
|
151
|
+
end
|
152
|
+
|
153
|
+
# add any content actions
|
154
|
+
append_actions(view.actions)
|
155
|
+
end
|
156
|
+
|
157
|
+
def add(view)
|
158
|
+
if !view.is_a? WebContentView
|
159
|
+
raise ArgumentError, "view must currently be a WebContentView instance"
|
160
|
+
end
|
161
|
+
|
162
|
+
append_html(view.render)
|
163
|
+
|
164
|
+
# FIXME: this should really be done, but we need to be a bit
|
165
|
+
# more sophisticated in the way we manage it
|
166
|
+
# append_actions(view.actions)
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
def append_actions(actions)
|
171
|
+
return if !actions
|
172
|
+
|
173
|
+
location[:actions] = actions if location
|
174
|
+
frame.merge_actions(actions)
|
175
|
+
end
|
176
|
+
|
177
|
+
def reset_actions
|
178
|
+
if location && (ca = location[:actions])
|
179
|
+
frame.unmerge_actions(ca)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: form_view.rb
|
21
|
+
# Created: Fri 30 Dec 2011 14:48:46 CET
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
# FormView instances are an abstract representation of a
|
30
|
+
# form-based editor for model instances. It is deliberately
|
31
|
+
# modelled on HTML forms where possible.
|
32
|
+
|
33
|
+
class FormView < View
|
34
|
+
# This signal is emitted by the hosting widget when the
|
35
|
+
# form has been submitted. The block is passed arguments
|
36
|
+
# for the form and the model (or model proxy) being used.
|
37
|
+
|
38
|
+
signal "form-submit", :vetoable => true
|
39
|
+
|
40
|
+
# This signal is emitted by the hosting widget when the
|
41
|
+
# form has been reset.
|
42
|
+
|
43
|
+
signal "form-reset"
|
44
|
+
|
45
|
+
def initialize(model, &block)
|
46
|
+
@model = model
|
47
|
+
@editors = {}
|
48
|
+
@validators = {}
|
49
|
+
@disabled = {}
|
50
|
+
self.instance_eval(&block) if block
|
51
|
+
end
|
52
|
+
|
53
|
+
def editor(key, editor)
|
54
|
+
@editors[key.to_sym] = editor
|
55
|
+
end
|
56
|
+
|
57
|
+
# This method sets a validator block for the given key.
|
58
|
+
# More than one validator can be initialized for each
|
59
|
+
# property key
|
60
|
+
|
61
|
+
def validator(key, &block)
|
62
|
+
return if !block
|
63
|
+
vals = (@validators[key.to_sym] ||= [])
|
64
|
+
vals << block
|
65
|
+
end
|
66
|
+
|
67
|
+
# This method is used to ensure that the specified model
|
68
|
+
# key field appears, but is disabled. This can also be
|
69
|
+
# done via the model by ensuring editable is false.
|
70
|
+
|
71
|
+
def disabled(key, val = true)
|
72
|
+
@disabled[key.to_sym] = val
|
73
|
+
end
|
74
|
+
|
75
|
+
# This method is used by the concrete hosting widget to
|
76
|
+
# iterate through the form field definitions so that it
|
77
|
+
# can create the actual UI form.
|
78
|
+
|
79
|
+
def layout(&block)
|
80
|
+
@model.labels.each do |l|
|
81
|
+
k = l[:key]
|
82
|
+
if (@disabled.has_key?(k) && @disabled[k]) \
|
83
|
+
|| !@model.is_editable?(k)
|
84
|
+
disabled = true
|
85
|
+
else
|
86
|
+
disabled = false
|
87
|
+
end
|
88
|
+
block.call(k, l[:label], @model[k], @editors[k] || l[:editor], disabled)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# This method is called when the form should be saved to
|
93
|
+
# the underlying model.
|
94
|
+
|
95
|
+
def submit(values)
|
96
|
+
values.each do |k, v|
|
97
|
+
@model[k] = v if @model.is_editable? k
|
98
|
+
end
|
99
|
+
signal_emit("form-submit", self, @model)
|
100
|
+
end
|
101
|
+
|
102
|
+
def reset(&block)
|
103
|
+
@model.keys.each do |k|
|
104
|
+
block.call(k, @model[k])
|
105
|
+
end
|
106
|
+
signal_emit("form-reset", self, @model)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|