hobo 0.5.3 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hobo +18 -4
- data/hobo_files/plugin/CHANGES.txt +511 -0
- data/hobo_files/plugin/README +8 -3
- data/hobo_files/plugin/Rakefile +81 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +4 -4
- data/hobo_files/plugin/generators/hobo/templates/guest.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +16 -22
- data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +6 -5
- data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +4 -6
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +237 -0
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +9 -0
- data/hobo_files/plugin/generators/hobo_model/USAGE +2 -3
- data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +1 -6
- data/hobo_files/plugin/generators/hobo_model/templates/model.rb +10 -4
- data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +7 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_base.css +68 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.css +93 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +11 -6
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/plus.png +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +24 -14
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +28 -44
- data/hobo_files/plugin/generators/hobo_user_model/USAGE +2 -12
- data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +1 -14
- data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +0 -6
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -1
- data/hobo_files/plugin/init.rb +6 -2
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +23 -12
- data/hobo_files/plugin/lib/extensions.rb +134 -40
- data/hobo_files/plugin/lib/extensions/test_case.rb +0 -1
- data/hobo_files/plugin/lib/hobo.rb +77 -46
- data/hobo_files/plugin/lib/hobo/authenticated_user.rb +24 -2
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +2 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +35 -12
- data/hobo_files/plugin/lib/hobo/define_tags.rb +4 -4
- data/hobo_files/plugin/lib/hobo/dryml.rb +33 -51
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +47 -34
- data/hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb +37 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +27 -5
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +545 -302
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +305 -135
- data/hobo_files/plugin/lib/hobo/email_address.rb +5 -0
- data/hobo_files/plugin/lib/hobo/field_spec.rb +66 -0
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +325 -0
- data/hobo_files/plugin/lib/hobo/html_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +13 -1
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +3 -1
- data/hobo_files/plugin/lib/hobo/model.rb +185 -66
- data/hobo_files/plugin/lib/hobo/model_controller.rb +56 -49
- data/hobo_files/plugin/lib/hobo/password_string.rb +2 -0
- data/hobo_files/plugin/lib/hobo/plugins.rb +75 -0
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +98 -0
- data/hobo_files/plugin/lib/hobo/static_tags +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +11 -1
- data/hobo_files/plugin/lib/hobo/undefined.rb +1 -1
- data/hobo_files/plugin/lib/rexml.rb +166 -75
- data/hobo_files/plugin/spec/fixtures/users.yml +9 -0
- data/hobo_files/plugin/spec/spec.opts +6 -0
- data/hobo_files/plugin/spec/spec_helper.rb +28 -0
- data/hobo_files/plugin/spec/unit/hobo/dryml/template_spec.rb +650 -0
- data/hobo_files/plugin/tags/core.dryml +58 -4
- data/hobo_files/plugin/tags/rapid.dryml +289 -135
- data/hobo_files/plugin/tags/rapid_document_tags.dryml +49 -0
- data/hobo_files/plugin/tags/rapid_editing.dryml +92 -69
- data/hobo_files/plugin/tags/rapid_forms.dryml +242 -0
- data/hobo_files/plugin/tags/rapid_navigation.dryml +65 -65
- data/hobo_files/plugin/tags/rapid_pages.dryml +197 -124
- data/hobo_files/plugin/tags/rapid_support.dryml +23 -0
- metadata +29 -22
- data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +0 -13
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +0 -11
- data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +0 -15
- data/hobo_files/plugin/lib/hobo/HtmlString +0 -3
- data/hobo_files/plugin/lib/hobo/controller_helpers.rb +0 -135
- data/hobo_files/plugin/lib/hobo/core.rb +0 -475
- data/hobo_files/plugin/lib/hobo/rapid.rb +0 -447
- data/hobo_files/plugin/test/hobo_dryml_template_test.rb +0 -7
- data/hobo_files/plugin/test/hobo_test.rb +0 -7
@@ -0,0 +1,49 @@
|
|
1
|
+
<def tag="field_list"><table class="field_list"><tagbody/></table></def>
|
2
|
+
|
3
|
+
<def tag="field_list_item"><tr merge_attrs><tagbody/></tr></def>
|
4
|
+
|
5
|
+
<def tag="item_label"><th merge_attrs><tagbody/></th></def>
|
6
|
+
|
7
|
+
<def tag="item_value"><td merge_attrs><tagbody/></td></def>
|
8
|
+
|
9
|
+
|
10
|
+
<def tag="heading">
|
11
|
+
<%= content_tag "h#{scope.heading_level || '1'}", tagbody.call, attributes %>
|
12
|
+
</def>
|
13
|
+
|
14
|
+
<def tag="nav">
|
15
|
+
<div class="nav" merge_attrs><tagbody/></div>
|
16
|
+
</def>
|
17
|
+
|
18
|
+
<!-- section represents a generic document or application section. -->
|
19
|
+
<def tag="section">
|
20
|
+
<set body="&tagbody ? tagbody.call : ''"/>
|
21
|
+
<div class="section" merge_attrs if="&body"><tagbody/></div>
|
22
|
+
</def>
|
23
|
+
|
24
|
+
<def tag="aside">
|
25
|
+
<set body="&tagbody ? tagbody.call : ''"/>
|
26
|
+
<div class="aside" merge_attrs if="&body"><tagbody/></div>
|
27
|
+
</def>
|
28
|
+
|
29
|
+
<def tag="header">
|
30
|
+
<set body="&tagbody ? tagbody.call : ''"/>
|
31
|
+
<div class="header" merge_attrs if="&body"><tagbody/></div>
|
32
|
+
</def>
|
33
|
+
|
34
|
+
<def tag="footer">
|
35
|
+
<set body="&tagbody ? tagbody.call : ''"/>
|
36
|
+
<div class="footer" merge_attrs if="&body"><tagbody/></div>
|
37
|
+
</def>
|
38
|
+
|
39
|
+
<!-- article represents an independent piece of content of a -->
|
40
|
+
<!-- document, such as a blog entry or newspaper article. -->
|
41
|
+
<def tag="article">
|
42
|
+
<set body="&tagbody ? tagbody.call : ''"/>
|
43
|
+
<div class="article" merge_attrs if="&body"><tagbody/></div>
|
44
|
+
</def>
|
45
|
+
|
46
|
+
<!-- temporary tag -->
|
47
|
+
<def tag="panel">
|
48
|
+
<div class="panel" merge_attrs><tagbody/></div>
|
49
|
+
</def>
|
@@ -1,6 +1,52 @@
|
|
1
|
+
<def tag="editor"><%=
|
2
|
+
if !can_edit?
|
3
|
+
view(attributes)
|
4
|
+
elsif this_type.respond_to?(:macro)
|
5
|
+
if this_type.macro == :belongs_to
|
6
|
+
belongs_to_editor(attributes)
|
7
|
+
else
|
8
|
+
has_many_editor(attributes)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
attrs = add_classes(attributes, "#{type_and_field}", "#{type_name}", "editor")
|
12
|
+
call_polymorphic_tag("editor", attrs) or
|
13
|
+
raise HoboError.new("<editor> not implemented for #{this.class.name}\##{this_field} " +
|
14
|
+
"(#{this.inspect}:#{this_type})")
|
15
|
+
end
|
16
|
+
%></def>
|
17
|
+
|
18
|
+
|
19
|
+
<def tag="has_many_editor">
|
20
|
+
<% #TODO: Implement %>
|
21
|
+
<a merge_attrs/>
|
22
|
+
</def>
|
23
|
+
|
24
|
+
<def tag="belongs_to_editor"><%= belongs_to_menu_editor(attributes) %></def>
|
25
|
+
|
26
|
+
<def tag="editor" for="string"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
27
|
+
|
28
|
+
<def tag="editor" for="text"><%= in_place_editor "in_place_textarea_bhv", attributes %></def>
|
29
|
+
|
30
|
+
<def tag="editor" for="html"><%= in_place_editor "in_place_html_textarea_bhv", attributes %></def>
|
31
|
+
|
32
|
+
<def tag="editor" for="datetime"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
33
|
+
|
34
|
+
<def tag="editor" for="date"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
35
|
+
|
36
|
+
<def tag="editor" for="integer"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
37
|
+
|
38
|
+
<def tag="editor" for="float"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
39
|
+
|
40
|
+
<def tag="editor" for="password"><% raise HoboError, "passwords cannot be edited in place" %></def>
|
41
|
+
|
42
|
+
<def tag="editor" for="boolean"><boolean_checkbox_editor merge_attrs/></def>
|
43
|
+
|
1
44
|
|
2
|
-
<def tag="submit" attrs="label">
|
3
|
-
<input
|
45
|
+
<def tag="submit" attrs="label, image">
|
46
|
+
<input if="&image" type="image" src="&image" merge_attrs class="image_input submit_button"/>
|
47
|
+
<else>
|
48
|
+
<input type="submit" value="#{label}" merge_attrs class="button_input submit_button"/>
|
49
|
+
</else>
|
4
50
|
</def>
|
5
51
|
|
6
52
|
|
@@ -15,35 +61,21 @@
|
|
15
61
|
id ||= this_field_dom_id + "_completer"
|
16
62
|
url = object_url(completer_model, "completions",
|
17
63
|
{ :for => completer_attr },
|
18
|
-
|
64
|
+
attributes.select_hash {|k,v| k.to_s.starts_with? "where_"})
|
19
65
|
%>
|
20
|
-
<input type="text" name="
|
21
|
-
autocomplete_url="
|
22
|
-
|
66
|
+
<input type="text" name="#{name}" id="#{id}" class="autocomplete_bhv"
|
67
|
+
autocomplete_url="#{url}" value="#{value}"
|
68
|
+
merge_attrs/>
|
23
69
|
<div id="<%= id %>_completions" class="completions_popup" style="display:none"></div>
|
24
70
|
</def>
|
25
71
|
|
26
72
|
|
27
|
-
<def tag="belongs_to_menu_field"><%
|
28
|
-
raise HoboError.new("Not allowed to edit") unless can_edit_this?
|
29
|
-
#Todo: switch to autocompleter for id_name when too many records, and id_name supported
|
30
|
-
select_options = this_type.klass.find(:all).select {|x| can_view?(x)}.map { |x|
|
31
|
-
[ display_name(:obj => x, :no_span => true), x.id ]
|
32
|
-
}
|
33
|
-
select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil?
|
34
|
-
%>
|
35
|
-
<select name="<%= param_name_for_this(true) %>">
|
36
|
-
<%= options_for_select(select_options.sort, this ? this.id : "") %>
|
37
|
-
</select>
|
38
|
-
</def>
|
39
|
-
|
40
|
-
|
41
73
|
<def tag="belongs_to_menu_editor"><%
|
42
|
-
raise HoboError.new("Not allowed to edit") unless
|
74
|
+
raise HoboError.new("Not allowed to edit") unless can_edit?
|
43
75
|
link_id = "#{this_field_dom_id}_editor" %>
|
44
|
-
<span id="#link_id"
|
76
|
+
<span id="#{link_id}" part="rapid_belongs_to_edit">
|
45
77
|
<% select_options = this_type.klass.find(:all).select {|x| can_view?(x)}.map {|x|
|
46
|
-
[
|
78
|
+
[ name(:with => x, :no_wrapper => true), x.id ]
|
47
79
|
}
|
48
80
|
select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil?
|
49
81
|
link_id = "#{this_field_dom_id}_editor"
|
@@ -54,32 +86,17 @@
|
|
54
86
|
this_type.primary_key_name => Hobo.raw_js('this.value')
|
55
87
|
} })
|
56
88
|
%>
|
57
|
-
<select onchange="<%= f %>"
|
89
|
+
<select onchange="<%= f %>">
|
58
90
|
<%= options_for_select(select_options.sort, this ? this.id : "") %>
|
59
91
|
</select>
|
60
|
-
<
|
92
|
+
<a if="&this">View</a>
|
61
93
|
</span>
|
62
94
|
</def>
|
63
95
|
|
64
96
|
|
65
|
-
<def tag="belongs_to_autocompleting_field">
|
66
|
-
<% refl = this_type
|
67
|
-
completer_model ||= refl.klass
|
68
|
-
completer_attr ||= refl.klass.id_name_column
|
69
|
-
id ||= this_field_dom_id + "_completer"
|
70
|
-
where_options = options.select_hash {|k,v| k.to_s.starts_with? "where_"}
|
71
|
-
url = object_url(completer_model, :completions, { :for => completer_attr }.update(where_options))
|
72
|
-
%>
|
73
|
-
|
74
|
-
<input type="text" id="<%= id %>" class="autocomplete_bhv" autocomplete_url="<%= url %>"
|
75
|
-
name="<%= param_name_for_this %>" xattrs=""/>
|
76
|
-
<div id="<%= id %>_completions" class="completions_popup" style="display:none"></div>
|
77
|
-
</def>
|
78
|
-
|
79
|
-
|
80
97
|
<def tag="belongs_to_autocompleting_editor" attrs="update">
|
81
98
|
<if_can_edit><%
|
82
|
-
return object_link unless
|
99
|
+
return object_link unless can_edit?
|
83
100
|
|
84
101
|
id ||= this_field_dom_id + "_completer"
|
85
102
|
f = ajax_updater(object_url(this_parent),
|
@@ -93,12 +110,12 @@
|
|
93
110
|
completer_attr ||= refl.klass.id_name_column
|
94
111
|
url = object_url(completer_model, "completions",
|
95
112
|
{ :for => completer_attr },
|
96
|
-
|
113
|
+
attributes.select_hash {|k,v| k.to_s.starts_with? "where_"})
|
97
114
|
%>
|
98
|
-
<form onsubmit="
|
99
|
-
<input type="text" class="autocomplete_bhv autosubmit" id="
|
100
|
-
value="
|
101
|
-
<div id="
|
115
|
+
<form onsubmit="#{f}; $('#{id}').blur(); return false">
|
116
|
+
<input type="text" class="autocomplete_bhv autosubmit" id="#{id}" autocomplete_url="#{url}"
|
117
|
+
value="#{this && this.id_name}" merge_attrs />
|
118
|
+
<div id="#{id}_completions" class="completions_popup" style="display:none"></div>
|
102
119
|
</form>
|
103
120
|
</if_can_edit>
|
104
121
|
<else>
|
@@ -107,32 +124,43 @@
|
|
107
124
|
</def>
|
108
125
|
|
109
126
|
|
110
|
-
<def tag="
|
111
|
-
raise HoboError.new("Not allowed to edit") unless
|
127
|
+
<def tag="string_select_editor" attrs="update, values"><%
|
128
|
+
raise HoboError.new("Not allowed to edit") unless can_edit?
|
129
|
+
|
130
|
+
values = comma_split(values)
|
112
131
|
f = ajax_updater(object_url(this_parent),
|
113
132
|
"Change #{this_field.to_s.titleize}", update,
|
114
133
|
:method => "put",
|
115
134
|
:params => { this_parent.class.name.underscore => {
|
116
|
-
this_field => Hobo.raw_js('this.
|
135
|
+
this_field => Hobo.raw_js('this.value')
|
117
136
|
} })
|
118
|
-
|
137
|
+
html_attributes = add_classes(attributes, editor_class)
|
119
138
|
%>
|
120
|
-
<
|
121
|
-
|
139
|
+
<select onchange="#{f}" merge_attrs="&html_attributes">
|
140
|
+
<%= options_for_select(values, this) %>
|
141
|
+
</select>
|
122
142
|
</def>
|
123
143
|
|
124
144
|
|
125
|
-
<def tag="
|
126
|
-
|
127
|
-
|
128
|
-
|
145
|
+
<def tag="boolean_checkbox_editor" attrs="update"><%
|
146
|
+
raise HoboError.new("Not allowed to edit") unless can_edit?
|
147
|
+
f = ajax_updater(object_url(this_parent),
|
148
|
+
"Change #{this_field.to_s.titleize}", update,
|
149
|
+
:method => "put",
|
150
|
+
:params => { this_parent.class.name.underscore => {
|
151
|
+
this_field => Hobo.raw_js('this.checked')
|
152
|
+
} })
|
153
|
+
attributes = add_classes(attributes, editor_class)
|
154
|
+
%>
|
155
|
+
<input type="checkbox" value="1" onclick="#{f}"
|
156
|
+
merge_attrs="& this ? attributes.merge(:checked => 'checked') : attributes" />
|
129
157
|
</def>
|
130
158
|
|
131
|
-
|
159
|
+
|
132
160
|
<def tag="sti_type_editor" attrs="update">
|
133
161
|
<% base_class = this.class
|
134
162
|
base_class = base_class.superclass while base_class.superclass != ActiveRecord::Base
|
135
|
-
f = ajax_updater("#{
|
163
|
+
f = ajax_updater("#{base_url}/#{controller_for base_class}/#{this.id}",
|
136
164
|
"Change #{this_field.to_s.titleize}", update,
|
137
165
|
:method => "put",
|
138
166
|
:params => { base_class.name.underscore => {
|
@@ -140,8 +168,8 @@
|
|
140
168
|
} })
|
141
169
|
%>
|
142
170
|
|
143
|
-
<select onchange="
|
144
|
-
<if
|
171
|
+
<select onchange="#{f}">
|
172
|
+
<if test="&tagbody">
|
145
173
|
<tagbody/>
|
146
174
|
</if>
|
147
175
|
<else>
|
@@ -152,17 +180,12 @@
|
|
152
180
|
|
153
181
|
|
154
182
|
<def tag="integer_select_editor" attrs="min, max, update, nil_option, message">
|
155
|
-
<select class="number_editor_bhv" hobo_update="
|
156
|
-
hobo_model_id="
|
157
|
-
|
158
|
-
<if
|
183
|
+
<select class="number_editor_bhv" hobo_update="#{update}"
|
184
|
+
hobo_model_id="#{this_field_dom_id}"
|
185
|
+
merge_attrs="&message ? attributes.merge(:hobo_message => message) : attributes">
|
186
|
+
<if test="&this.nil?"><option value=""><%= nil_option || "Choose a value" %></option></if>
|
159
187
|
<%= options_for_select((min.to_i..max.to_i).to_a, this) %>
|
160
188
|
</select>
|
161
189
|
</def>
|
162
190
|
|
163
191
|
|
164
|
-
<def tag="select_field">
|
165
|
-
<select name="<%= param_name_for_this %>">
|
166
|
-
<tagbody/>
|
167
|
-
</select>
|
168
|
-
</def>
|
@@ -0,0 +1,242 @@
|
|
1
|
+
<def tag="hidden_fields" attrs="fields, skip"><%=
|
2
|
+
hiddens = case fields
|
3
|
+
when '*', nil
|
4
|
+
this.class.column_names - ['type', 'created_at', 'updated_at']
|
5
|
+
else
|
6
|
+
comma_split(fields)
|
7
|
+
end
|
8
|
+
hiddens -= comma_split(skip)
|
9
|
+
pname = this.class.name.underscore
|
10
|
+
hidden_tags = hiddens.map do |h|
|
11
|
+
val = this.send(h)
|
12
|
+
name = "#{pname}[#{h}]"
|
13
|
+
hidden_field_tag(name, val.to_s) if val
|
14
|
+
end.join("\n")
|
15
|
+
%></def>
|
16
|
+
|
17
|
+
|
18
|
+
<def tag="form" attrs="message, update, hidden_fields, action, method, web_method"><%=
|
19
|
+
ajax_attrs, html_attrs = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
20
|
+
|
21
|
+
html_attrs[:action] = action || object_url(this, web_method)
|
22
|
+
|
23
|
+
new_record = this.respond_to?(:new_record?) && this.new_record?
|
24
|
+
|
25
|
+
method = if method.nil?
|
26
|
+
(action || web_method || new_record) ? "post" : "put"
|
27
|
+
else
|
28
|
+
method.downcase
|
29
|
+
end
|
30
|
+
if method == "put"
|
31
|
+
http_method_hidden = hidden_field_tag("_method", "PUT")
|
32
|
+
html_attrs[:method] = "post"
|
33
|
+
else
|
34
|
+
html_attrs[:method] = method
|
35
|
+
end
|
36
|
+
|
37
|
+
if update || !ajax_attrs.empty?
|
38
|
+
# add an onsubmit to convert to an ajax form if `update` is given
|
39
|
+
function = ajax_updater(:post_form, message, update, ajax_attrs)
|
40
|
+
html_attrs[:onsubmit] = [html_attrs[:onsubmit], "#{function}; return false;"].compact.join("; ")
|
41
|
+
end
|
42
|
+
|
43
|
+
body, field_names = with_form_context { tagbody.call }
|
44
|
+
|
45
|
+
hiddens = hidden_fields(:fields => hidden_fields, :skip => field_names) if new_record
|
46
|
+
|
47
|
+
body = [http_method_hidden, hiddens, body].join
|
48
|
+
|
49
|
+
if web_method
|
50
|
+
add_classes!(html_attrs, "#{type_name}_#{web_method}_form")
|
51
|
+
else
|
52
|
+
add_classes!(html_attrs, "#{'new_' if new_record}#{type_name}")
|
53
|
+
end
|
54
|
+
|
55
|
+
content_tag("form", body, html_attrs)
|
56
|
+
%></def>
|
57
|
+
|
58
|
+
|
59
|
+
<def tag="input"><%=
|
60
|
+
if attributes[:type]
|
61
|
+
tag :input, attributes
|
62
|
+
elsif !can_edit?
|
63
|
+
view
|
64
|
+
else
|
65
|
+
if this_type.respond_to?(:macro)
|
66
|
+
if this_type.macro == :belongs_to
|
67
|
+
belongs_to_input(attributes)
|
68
|
+
elsif this_type.macro == :has_many
|
69
|
+
has_many_input(attributes)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
attrs = {}.update(attributes)
|
73
|
+
attrs[:name] ||= param_name_for_this
|
74
|
+
the_input = call_polymorphic_tag('input', attrs) or
|
75
|
+
raise HoboError, ("No input tag for #{this_field}:#{this_type} (this=#{this.inspect})")
|
76
|
+
if this_parent.errors[this_field]
|
77
|
+
"<div class='field_with_errors'>#{the_input}</div>"
|
78
|
+
else
|
79
|
+
the_input
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
%></def>
|
84
|
+
|
85
|
+
<def tag="input" for="text" attrs="name">
|
86
|
+
<%= text_area_tag(name, this, attributes) %>
|
87
|
+
</def>
|
88
|
+
|
89
|
+
<def tag="input" for="boolean" attrs="name">
|
90
|
+
<%= check_box_tag(name, '1', this, attributes) + hidden_field_tag(name, '0') %>
|
91
|
+
</def>
|
92
|
+
|
93
|
+
<def tag="input" for="password" attrs="name">
|
94
|
+
<%= password_field_tag(name, this) %>
|
95
|
+
</def>
|
96
|
+
|
97
|
+
<def tag="input" for="html" attrs="name">
|
98
|
+
<%= text_area_tag(name, this, add_classes(attributes, :tiny_mce)) %>
|
99
|
+
</def>
|
100
|
+
|
101
|
+
<def tag="input" for="date">
|
102
|
+
<%= select_date(this || Time.now, :prefix => param_name_for_this) %>
|
103
|
+
</def>
|
104
|
+
|
105
|
+
<def tag="input" for="datetime">
|
106
|
+
<%= select_datetime(this || Time.now, :prefix => param_name_for_this) %>
|
107
|
+
</def>
|
108
|
+
|
109
|
+
<def tag="input" for="integer" attrs="name">
|
110
|
+
<%= text_field_tag(name, this, attributes) %>
|
111
|
+
</def>
|
112
|
+
|
113
|
+
<def tag="input" for="float" attrs="name">
|
114
|
+
<%= text_field_tag(name, this, attributes) %>
|
115
|
+
</def>
|
116
|
+
|
117
|
+
<def tag="input" for="string" attrs="name">
|
118
|
+
<%= text_field_tag(name, this, attributes) %>
|
119
|
+
</def>
|
120
|
+
|
121
|
+
<def tag="belongs_to_input">
|
122
|
+
<%= belongs_to_menu_input(attributes) %>
|
123
|
+
</def>
|
124
|
+
|
125
|
+
<!--- Buttons --->
|
126
|
+
|
127
|
+
<def tag="remote_method_button" attrs="method, update, result_update, params, label, message"><%=
|
128
|
+
ajax_attributes, html_attributes = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
129
|
+
|
130
|
+
message ||= method.titleize
|
131
|
+
func = ajax_updater(object_url(this) + "/#{method}", message, update,
|
132
|
+
ajax_attributes.merge(:params => params, :result_update => result_update))
|
133
|
+
html_attributes.update(:type =>'button', :onclick => "var e = this; " + func, :value => label)
|
134
|
+
tag(:input, add_classes(html_attributes, "button_input remote_method_button #{method}_button"))
|
135
|
+
%></def>
|
136
|
+
|
137
|
+
|
138
|
+
<def tag="update_button" attrs="label, message, update, fields, params"><%=
|
139
|
+
raise HoboError.new("no update specified") unless update
|
140
|
+
message ||= label
|
141
|
+
func = ajax_updater(object_url(this), message, update,
|
142
|
+
:params => { this.class.name.underscore => fields }.merge(params || {}),
|
143
|
+
:method => :put)
|
144
|
+
tag :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
145
|
+
"button_input update_button update_#{this.class.name.underscore}_button") %>
|
146
|
+
</def>
|
147
|
+
|
148
|
+
|
149
|
+
<def tag="delete_button" attrs="label, message, update, in_place, image, confirm, fade"><%=
|
150
|
+
if can_delete?
|
151
|
+
attributes = attributes.merge(if image
|
152
|
+
{ :type => "image", :src => "#{base_url}/images/#{image}" }
|
153
|
+
else
|
154
|
+
{ :type => "button" }
|
155
|
+
end)
|
156
|
+
label ||= "Remove"
|
157
|
+
confirm ||= "Are you sure?"
|
158
|
+
|
159
|
+
add_classes!(attributes,
|
160
|
+
image ? "image_button_input" : "button_input",
|
161
|
+
"delete_button delete_#{this.class.name.underscore}_button")
|
162
|
+
url = object_url(this, "destroy")
|
163
|
+
if in_place == false
|
164
|
+
attributes[:confirm] = confirm
|
165
|
+
button_to(label, url, attributes)
|
166
|
+
else
|
167
|
+
fade = true if fade.nil?
|
168
|
+
attributes[:value] = label
|
169
|
+
attributes[:onclick] = "Hobo.removeButton(this, '#{url}', #{js_updates(update)}, #{fade ? 'true' : 'false'})"
|
170
|
+
tag(:input, attributes)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
%></def>
|
174
|
+
|
175
|
+
|
176
|
+
<def tag="create_button" attrs="model, update, label, message, fields"><%=
|
177
|
+
raise HoboError.new("no update specified") unless update
|
178
|
+
|
179
|
+
fields ||= {}
|
180
|
+
class_or_assoc = if model
|
181
|
+
model.is_a?(String) ? model.constantize : model
|
182
|
+
elsif Hobo.simple_has_many_association?(this)
|
183
|
+
fields[this.proxy_reflection.primary_key_name] = this.proxy_owner.id
|
184
|
+
this
|
185
|
+
else
|
186
|
+
raise HoboError.new("invalid context for <create_button>")
|
187
|
+
end
|
188
|
+
new = class_or_assoc.new(fields)
|
189
|
+
new.set_creator(current_user)
|
190
|
+
if can_create?(new)
|
191
|
+
label ||= "New #{new.class.name.titleize}"
|
192
|
+
message ||= label
|
193
|
+
class_name = new.class.name.underscore
|
194
|
+
func = ajax_updater(object_url(new.class), message, update,
|
195
|
+
({:params => { class_name => fields }} unless fields.empty?))
|
196
|
+
tag :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
197
|
+
"button_input create_button create_#{class_name}_button")
|
198
|
+
end
|
199
|
+
%></def>
|
200
|
+
|
201
|
+
|
202
|
+
<def tag="belongs_to_menu_input" attrs="include_none"><%
|
203
|
+
raise HoboError.new("Not allowed to edit") unless can_edit?
|
204
|
+
#Todo: switch to autocompleter for id_name when too many records, and id_name supported
|
205
|
+
select_options = this_type.klass.find(:all).select {|x| can_view?(x)}.map { |x|
|
206
|
+
[ name(:with => x, :no_wrapper => true), x.id ]
|
207
|
+
}
|
208
|
+
select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil? || include_none
|
209
|
+
%>
|
210
|
+
<select name="<%= param_name_for_this(true) %>">
|
211
|
+
<%= options_for_select(select_options.sort, this ? this.id : "") %>
|
212
|
+
</select>
|
213
|
+
</def>
|
214
|
+
|
215
|
+
|
216
|
+
<def tag="belongs_to_autocompleting_input">
|
217
|
+
<% refl = this_type
|
218
|
+
completer_model ||= refl.klass
|
219
|
+
completer_attr ||= refl.klass.id_name_column
|
220
|
+
id ||= this_field_dom_id + "_completer"
|
221
|
+
where_attributes = attributes.select_hash {|k,v| k.to_s.starts_with? "where_"}
|
222
|
+
url = object_url(completer_model, :completions, { :for => completer_attr }.update(where_attributes))
|
223
|
+
%>
|
224
|
+
|
225
|
+
<input type="text" id="#{id}" class="autocomplete_bhv" autocomplete_url="#{url}"
|
226
|
+
name="#{param_name_for_this}" merge_attrs/>
|
227
|
+
<div id="#{id}_completions" class="completions_popup" style="display:none"></div>
|
228
|
+
</def>
|
229
|
+
|
230
|
+
|
231
|
+
<def tag="sti_type_input">
|
232
|
+
<select name="<%= param_name_for(form_this, form_field_path + ['type']) %>">
|
233
|
+
<%= options_for_select(this.class.send(:subclasses).omap{[name.titleize, name]}, this.class.name) %>
|
234
|
+
</select>
|
235
|
+
</def>
|
236
|
+
|
237
|
+
|
238
|
+
<def tag="select_input">
|
239
|
+
<select name="#{param_name_for_this}">
|
240
|
+
<tagbody/>
|
241
|
+
</select>
|
242
|
+
</def>
|