hobo 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hobo +24 -7
- data/hobo_files/plugin/CHANGES.txt +501 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +8 -6
- data/hobo_files/plugin/generators/hobo/templates/application.dryml +3 -0
- data/hobo_files/plugin/generators/hobo/templates/dryml-support.js +132 -0
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +4 -5
- data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +75 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb +7 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb +8 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb +2 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +30 -11
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +149 -92
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +0 -48
- data/hobo_files/plugin/init.rb +45 -13
- data/hobo_files/plugin/lib/action_view_extensions/base.rb +4 -3
- data/hobo_files/plugin/lib/active_record/association_proxy.rb +18 -0
- data/hobo_files/plugin/lib/active_record/association_reflection.rb +5 -0
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +7 -11
- data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +8 -0
- data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
- data/hobo_files/plugin/lib/hobo.rb +38 -60
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +1 -1
- data/hobo_files/plugin/lib/hobo/bundle.rb +131 -34
- data/hobo_files/plugin/lib/hobo/composite_model.rb +1 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +7 -8
- data/hobo_files/plugin/lib/hobo/dev_controller.rb +21 -0
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +14 -8
- data/hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb +13 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +6 -7
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +207 -73
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +67 -55
- data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +53 -3
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +75 -107
- data/hobo_files/plugin/lib/hobo/model.rb +236 -429
- data/hobo_files/plugin/lib/hobo/model_controller.rb +277 -437
- data/hobo_files/plugin/lib/hobo/model_router.rb +62 -29
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +48 -9
- data/hobo_files/plugin/lib/hobo/scopes.rb +98 -0
- data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +31 -0
- data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +282 -0
- data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +88 -0
- data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +18 -0
- data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +59 -0
- data/hobo_files/plugin/lib/hobo/undefined.rb +2 -0
- data/hobo_files/plugin/lib/hobo/user.rb +31 -14
- data/hobo_files/plugin/lib/hobo/user_controller.rb +41 -27
- data/hobo_files/plugin/taglibs/core.dryml +9 -11
- data/hobo_files/plugin/taglibs/rapid.dryml +51 -108
- data/hobo_files/plugin/taglibs/rapid_editing.dryml +25 -25
- data/hobo_files/plugin/taglibs/rapid_forms.dryml +111 -79
- data/hobo_files/plugin/taglibs/rapid_generics.dryml +74 -0
- data/hobo_files/plugin/taglibs/rapid_navigation.dryml +23 -21
- data/hobo_files/plugin/taglibs/rapid_pages.dryml +83 -169
- data/hobo_files/plugin/taglibs/rapid_plus.dryml +16 -2
- data/hobo_files/plugin/taglibs/rapid_support.dryml +3 -3
- data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +104 -0
- metadata +60 -55
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +0 -276
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +0 -9
- data/hobo_files/plugin/lib/active_record/table_definition.rb +0 -34
- data/hobo_files/plugin/lib/extensions.rb +0 -375
- data/hobo_files/plugin/lib/hobo/email_address.rb +0 -12
- data/hobo_files/plugin/lib/hobo/enum_string.rb +0 -50
- data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +0 -43
- data/hobo_files/plugin/lib/hobo/field_spec.rb +0 -68
- data/hobo_files/plugin/lib/hobo/html_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +0 -40
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +0 -11
- data/hobo_files/plugin/lib/hobo/migrations.rb +0 -12
- data/hobo_files/plugin/lib/hobo/model_queries.rb +0 -117
- data/hobo_files/plugin/lib/hobo/password_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/percentage.rb +0 -14
- data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +0 -78
- data/hobo_files/plugin/lib/hobo/proc_binding.rb +0 -32
- data/hobo_files/plugin/lib/hobo/text.rb +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +0 -25
- data/hobo_files/plugin/lib/hobo/where_fragment.rb +0 -28
@@ -7,6 +7,8 @@
|
|
7
7
|
<include src="rapid_forms"/>
|
8
8
|
<include src="rapid_navigation"/>
|
9
9
|
<include src="rapid_plus"/>
|
10
|
+
<include src="rapid_generics"/>
|
11
|
+
|
10
12
|
|
11
13
|
<def tag="field-list" attrs="tag">
|
12
14
|
<% tag ||= scope.in_form ? "input" : "view" %>
|
@@ -73,7 +75,7 @@
|
|
73
75
|
<td param="#{this_field.to_s.sub('?', '').gsub('.', '-')}-view"><call-tag tag="&field_tag"/></td>
|
74
76
|
</with-fields>
|
75
77
|
<td class="controls" param="controls" if="&all_parameters[:controls]">
|
76
|
-
<a param="edit-link">Edit</a>
|
78
|
+
<a param="edit-link" action="edit">Edit</a>
|
77
79
|
<delete-button param/>
|
78
80
|
</td>
|
79
81
|
</if>
|
@@ -97,39 +99,9 @@
|
|
97
99
|
</def>
|
98
100
|
|
99
101
|
|
100
|
-
<def tag="theme-image" attrs="src">
|
101
|
-
<img src="#{theme_asset('images/' + src)}" merge-attrs/>
|
102
|
-
</def>
|
103
|
-
|
104
|
-
|
105
|
-
<def tag="card">
|
106
|
-
<if test="&can_view?">
|
107
|
-
<%= poly = call_polymorphic_tag('card', attributes, parameters) %>
|
108
|
-
<div class="card #{linkable? ? 'linkable' : 'content'} #{type_name :dasherize => true}" unless="&poly">
|
109
|
-
<a if="&linkable?"/>
|
110
|
-
<div class="content" param="content">
|
111
|
-
<primary-content if="&!linkable?"/>
|
112
|
-
</div>
|
113
|
-
<creation-details/>
|
114
|
-
<span class="dependents"><count-dependents /></span>
|
115
|
-
</div>
|
116
|
-
</if>
|
117
|
-
</def>
|
118
|
-
|
119
|
-
|
120
|
-
<def tag="collection">
|
121
|
-
<%= poly = call_polymorphic_tag('collection', attributes, parameters) %>
|
122
|
-
<ul class="collection" merge-attrs unless="&poly">
|
123
|
-
<li:><card param/></li:>
|
124
|
-
</ul>
|
125
|
-
<p class="empty-collection-message" if="&this.empty?" param="empty-message">
|
126
|
-
There are no <type-name plural/>
|
127
|
-
</p>
|
128
|
-
</def>
|
129
|
-
|
130
|
-
|
131
102
|
<def tag="hobo-rapid-javascripts" attrs="tiny-mce"><%=
|
132
103
|
res = '<script type="text/javascript">var hoboParts = {};'
|
104
|
+
# FIXME: This should interrogate the model-router - not the models
|
133
105
|
unless Hobo.all_models.empty?
|
134
106
|
# Tell JS code how to pluralize names, unless they follow the simple rule
|
135
107
|
names = Hobo.all_models.map do |m|
|
@@ -147,7 +119,7 @@
|
|
147
119
|
if tiny_mce
|
148
120
|
res += javascript_include_tag("tiny_mce/tiny_mce_src") + %{
|
149
121
|
<script type="text/javascript">
|
150
|
-
tinyMCE.init({ mode: "textareas", editor_selector: "
|
122
|
+
tinyMCE.init({ mode: "textareas", editor_selector: "tiny-mce",
|
151
123
|
plugins: 'save',
|
152
124
|
theme_advanced_buttons1 : "bold, italic, separator, " +
|
153
125
|
"bullist, outdent, indent, separator, " +
|
@@ -183,13 +155,8 @@
|
|
183
155
|
%></def>
|
184
156
|
|
185
157
|
<def tag="type-name" attrs="type, plural, lowercase, dasherize"><%=
|
186
|
-
type ||= if this.is_a?(Class)
|
187
|
-
|
188
|
-
elsif this.respond_to? :proxy_reflection
|
189
|
-
this.proxy_reflection.klass
|
190
|
-
else
|
191
|
-
this.class
|
192
|
-
end
|
158
|
+
type ||= (this if this.is_a?(Class)) || this.try.member_class || this.class
|
159
|
+
|
193
160
|
name = dasherize ? type.name.underscore.dasherize : type.name.titleize
|
194
161
|
name = name.pluralize if plural
|
195
162
|
name = name.downcase if lowercase
|
@@ -216,15 +183,15 @@
|
|
216
183
|
# Link to a new object form
|
217
184
|
new_record = target.new
|
218
185
|
new_record.set_creator(current_user)
|
219
|
-
|
220
|
-
|
186
|
+
href = object_url(target, "new", params._?.merge(:subsite => subsite))
|
187
|
+
|
188
|
+
if href && can_create?(new_record)
|
221
189
|
new_class_name = if target.respond_to?(:proxy_reflection)
|
222
190
|
target.proxy_reflection.klass.name
|
223
191
|
else
|
224
192
|
target.name
|
225
193
|
end
|
226
194
|
|
227
|
-
href = object_url(target, "new", params._?.merge(:subsite => subsite))
|
228
195
|
add_classes!(attributes, "new-#{new_class_name.underscore}-link")
|
229
196
|
content = "New #{new_class_name.titleize}" if content.blank?
|
230
197
|
element(:a, attributes.update(:href => href), content)
|
@@ -235,17 +202,9 @@
|
|
235
202
|
else
|
236
203
|
# Link to an existing object
|
237
204
|
|
238
|
-
if target.is_a?(Array) && !target.respond_to?(:proxy_reflection) && target.respond_to?(:member_class)
|
239
|
-
# Not much to go on here - last guess is that this is an index page
|
240
|
-
target = target.member_class
|
241
|
-
end
|
242
|
-
|
243
205
|
content = name if content.blank?
|
244
206
|
|
245
|
-
|
246
|
-
# linkable?
|
247
|
-
only_if_linkable = format.blank?
|
248
|
-
href = object_url(target, action, (params || {}).merge(:subsite => subsite, :if_available => only_if_linkable))
|
207
|
+
href = object_url(target, action, (params || {}).merge(:subsite => subsite))
|
249
208
|
if href.nil?
|
250
209
|
# This target is registered with ModelRouter as not linkable
|
251
210
|
content
|
@@ -268,21 +227,23 @@
|
|
268
227
|
|
269
228
|
res = if this.nil? && if_blank.nil?
|
270
229
|
this_type.is_a?(Class) && this_type <= String ? "" : nil_view
|
271
|
-
elsif
|
272
|
-
if
|
230
|
+
elsif refl = this_field_reflection
|
231
|
+
if refl.macro == :belongs_to
|
273
232
|
belongs_to_view(attributes)
|
274
|
-
elsif
|
233
|
+
elsif refl.macro == :has_many
|
275
234
|
has_many_view(attributes)
|
276
235
|
end
|
277
236
|
else
|
278
|
-
attrs = add_classes(attributes, "view", type_id, type_and_field)
|
279
|
-
attrs['hobo-model-id'] = this_field_dom_id if this_parent && this_parent.respond_to?(:typed_id)
|
280
237
|
|
281
238
|
view_tag = find_polymorphic_tag("view")
|
282
239
|
|
283
240
|
if view_tag == "view" # i.e. it didn't find a type specific tag
|
284
241
|
raise HoboError, "Cannot view: #{this.inspect} (field is #{this_field}, type is #{this.class})"
|
285
242
|
else
|
243
|
+
attrs = add_classes(attributes, "view", type_and_field)
|
244
|
+
id = dom_id
|
245
|
+
attrs['hobo-model-id'] = id unless id == "nil"
|
246
|
+
|
286
247
|
view_attrs = attrs_for(view_tag)
|
287
248
|
the_view = send(view_tag, attrs & view_attrs)
|
288
249
|
|
@@ -325,32 +286,29 @@
|
|
325
286
|
|
326
287
|
<def tag="view" for="html"><%= this %></def>
|
327
288
|
|
328
|
-
<def tag="view" for="
|
289
|
+
<def tag="view" for="markdown"><%= this.to_html %></def>
|
290
|
+
|
291
|
+
<def tag="view" for="textile"><%= this.to_html %></def>
|
329
292
|
|
330
|
-
<def tag="view" for="
|
293
|
+
<def tag="view" for="password">[password withheld]</def>
|
331
294
|
|
332
|
-
<def tag="view" for="
|
295
|
+
<def tag="view" for="string"><%= h(this).gsub("\n", "<br/>") %></def>
|
333
296
|
|
334
|
-
<def tag="view" for="
|
297
|
+
<def tag="view" for="boolean"><%= this ? 'Yes' : 'No' %></def>
|
335
298
|
|
336
|
-
<def tag="view" for="TrueClass"><%= this ? 'Yes' : 'No' %></def>
|
337
299
|
|
338
|
-
<def tag="count" attrs="label, prefix, if-any"><%=
|
300
|
+
<def tag="count" attrs="label, prefix, if-any, lowercase"><%=
|
339
301
|
raise Exception.new("asked for count of a string") if this.is_a?(String)
|
340
302
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
else
|
351
|
-
this.length
|
352
|
-
end
|
353
|
-
end
|
303
|
+
c = this.try.to_int || this.try.total_entries || this.try.count || this.try.length
|
304
|
+
|
305
|
+
label ||= if this.is_a?(Class)
|
306
|
+
this.name
|
307
|
+
else
|
308
|
+
(this.try.association_name || this.try.member_class._?.name)
|
309
|
+
end.to_s.singularize.titleize
|
310
|
+
|
311
|
+
label = label.downcase if lowercase
|
354
312
|
|
355
313
|
Hobo::Dryml.last_if = c > 0 if if_any
|
356
314
|
if if_any && c == 0
|
@@ -360,7 +318,7 @@
|
|
360
318
|
|
361
319
|
if prefix.in? %w(are is)
|
362
320
|
p = c == 1 ? "is" : "are"
|
363
|
-
p + ' ' + main
|
321
|
+
p + ' ' + main.to_s
|
364
322
|
else
|
365
323
|
main
|
366
324
|
end
|
@@ -370,14 +328,11 @@
|
|
370
328
|
|
371
329
|
<def tag="theme-stylesheet" attrs="name">
|
372
330
|
<% name ||= 'application' -%>
|
373
|
-
<link href="
|
331
|
+
<link href="#{base_url}/hobothemes/#{Hobo.current_theme}/stylesheets/#{name}.css"
|
374
332
|
media="screen" rel="Stylesheet" type="text/css" />
|
375
333
|
</def>
|
376
334
|
|
377
335
|
|
378
|
-
<def tag="clearer"><div class='clearer'> </div></def>
|
379
|
-
|
380
|
-
|
381
336
|
<!-- The Tags defined below here are a bit rough and will be improved
|
382
337
|
in the future - use at your own risk. -->
|
383
338
|
|
@@ -386,12 +341,12 @@ in the future - use at your own risk. -->
|
|
386
341
|
|
387
342
|
<do param="default"/>
|
388
343
|
|
389
|
-
<if test="&delete_buttons != false
|
344
|
+
<if test="&delete_buttons != false && can_delete?(this)">
|
390
345
|
<td><delete-button/></td>
|
391
346
|
</if>
|
392
347
|
</table-for>
|
393
348
|
<else>
|
394
|
-
<p>There are no <%=
|
349
|
+
<p>There are no <%= this.member_class.name.titleize.pluralize.downcase %></p>
|
395
350
|
</else>
|
396
351
|
<div>
|
397
352
|
<create-button update="&id || part_id"/>
|
@@ -423,16 +378,9 @@ in the future - use at your own risk. -->
|
|
423
378
|
</def>
|
424
379
|
|
425
380
|
|
426
|
-
<def tag="you" attrs="have, are">
|
427
|
-
<if test="&this == current_user">you <%= if have then 'have' elsif are then 'are' end %></if>
|
428
|
-
<else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
|
429
|
-
</def>
|
381
|
+
<def tag="you" attrs="have, are, do, titleize"><if test="&this == current_user"><%= "#{titleize ? 'Y' : 'y'}ou #{'have' if have}#{'are' if are}#{'do' if do_}" %></if><else><do param="default"><name/> <%= "#{'has' if have}#{'is' if are}#{'does' if do_}" %></do></else></def>
|
430
382
|
|
431
|
-
|
432
|
-
<def tag="You" attrs="have, are">
|
433
|
-
<if test="&this == current_user">You <%= if have then 'have' elsif are then 'are' end %></if>
|
434
|
-
<else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
|
435
|
-
</def>
|
383
|
+
<def tag="You"><you merge titleize/></def>
|
436
384
|
|
437
385
|
<def tag="your">
|
438
386
|
<if test="&this == current_user">your</if>
|
@@ -446,17 +394,6 @@ in the future - use at your own risk. -->
|
|
446
394
|
</def>
|
447
395
|
|
448
396
|
|
449
|
-
<def tag="creation-details">
|
450
|
-
<span class="creation-details">
|
451
|
-
<view with="&this.send(this.class.creator_attribute)" class="creator" if="&this.class.creator_attribute" />
|
452
|
-
<view:created_at class="created-at" if="&this.respond_to?(:created_at)"/>
|
453
|
-
</span>
|
454
|
-
</def>
|
455
|
-
|
456
|
-
<def tag="primary-content">
|
457
|
-
<view class="primary-content" field="&this.class.primary_content_attribute" if="&this.class.primary_content_attribute"/>
|
458
|
-
</def>
|
459
|
-
|
460
397
|
<def tag="live-search">
|
461
398
|
<div class="search">
|
462
399
|
<label for="search-field">Search</label><input type="search" id="search-field" name="search-field" class="search-bhv search"/>
|
@@ -468,11 +405,6 @@ in the future - use at your own risk. -->
|
|
468
405
|
</section>
|
469
406
|
</def>
|
470
407
|
|
471
|
-
<def tag="count-dependents">
|
472
|
-
<% assoc = this.class.dependent_collections.first if this.class.dependent_collections.length == 1 %>
|
473
|
-
<count field="&assoc" if="&assoc"/>
|
474
|
-
</def>
|
475
|
-
|
476
408
|
|
477
409
|
<def tag="a-or-an" attrs="word"><%=
|
478
410
|
(word =~ /^[aeiouh]/i ? "an " : "a ") + word
|
@@ -482,3 +414,14 @@ in the future - use at your own risk. -->
|
|
482
414
|
<def tag="A-or-An" attrs="word"><%=
|
483
415
|
(word =~ /^[aeiouh]/i ? "An " : "A ") + word
|
484
416
|
%></def>
|
417
|
+
|
418
|
+
|
419
|
+
<def tag="filter-menu" attrs="param-name, options, no-filter">
|
420
|
+
<form action="&request.request_uri" method="get" class="filter-menu">
|
421
|
+
<hidden-field name="filter-parameter" value="¶m_name"/>
|
422
|
+
<select-menu name="¶m_name" options="&options" selected="¶ms[param_name.gsub('-', '_')]" first-option="&no_filter" merge-params/>
|
423
|
+
</form>
|
424
|
+
</def>
|
425
|
+
|
426
|
+
|
427
|
+
<def tag="comma-list" attrs="separator"><%= this.join(separator || ", ") %></def>
|
@@ -1,14 +1,14 @@
|
|
1
1
|
<def tag="editor" ><%=
|
2
2
|
if !can_edit?
|
3
3
|
view(attributes)
|
4
|
-
elsif
|
5
|
-
if
|
4
|
+
elsif (refl = this_field_reflection)
|
5
|
+
if refl.macro == :belongs_to
|
6
6
|
belongs_to_editor(attributes)
|
7
7
|
else
|
8
8
|
has_many_editor(attributes)
|
9
9
|
end
|
10
10
|
else
|
11
|
-
attrs = add_classes(attributes,
|
11
|
+
attrs = add_classes(attributes, type_id, type_and_field, "editor")
|
12
12
|
call_polymorphic_tag("editor", attrs) or
|
13
13
|
raise HoboError.new("<editor> not implemented for #{this.class.name}\##{this_field} " +
|
14
14
|
"(#{this.inspect}:#{this_type})")
|
@@ -44,7 +44,7 @@
|
|
44
44
|
<def tag="editor" for="big_integer"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
45
45
|
|
46
46
|
<def tag="editor" for="Hobo::EnumString">
|
47
|
-
<string-select-editor values="&this_type.values"/>
|
47
|
+
<string-select-editor values="&this_type.values" merge/>
|
48
48
|
</def>
|
49
49
|
|
50
50
|
|
@@ -56,31 +56,31 @@
|
|
56
56
|
else
|
57
57
|
completer_model = completer_model.constantize if completer_model.is_a? String
|
58
58
|
end
|
59
|
-
id ||=
|
59
|
+
id ||= dom_id + "_completer"
|
60
60
|
url = object_url(completer_model, "completions",
|
61
61
|
{ :for => completer_attr }.update(attributes.select_hash {|k,v| k.to_s.starts_with? "where_"}))
|
62
62
|
%>
|
63
63
|
<input type="text" name="#{name}" id="#{id}" class="autocomplete-bhv"
|
64
64
|
autocomplete-url="#{url}" value="#{value}"
|
65
65
|
merge-attrs/>
|
66
|
-
|
66
|
+
<div id="#{id}-completions" class="completions-popup" style="display:none"></div>
|
67
67
|
</def>
|
68
68
|
|
69
69
|
|
70
70
|
<def tag="belongs-to-menu-editor"><%
|
71
71
|
raise HoboError.new("Not allowed to edit") unless can_edit?
|
72
|
-
link_id = "#{
|
72
|
+
link_id = "#{dom_id}_editor" %>
|
73
73
|
<span id="#{link_id}" part="rapid-belongs-to-edit">
|
74
|
-
<% select_options =
|
74
|
+
<% select_options = this_field_reflection.klass.find(:all).select {|x| can_view?(x)}.map {|x|
|
75
75
|
[ name(:with => x, :no_wrapper => true), x.id ]
|
76
76
|
}
|
77
77
|
select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil?
|
78
|
-
link_id = "#{
|
78
|
+
link_id = "#{dom_id}_editor"
|
79
79
|
f = ajax_updater(object_url(this_parent),
|
80
|
-
|
80
|
+
[link_id],
|
81
81
|
:method => "put",
|
82
82
|
:params => { this_parent.class.name.underscore => {
|
83
|
-
|
83
|
+
this_field_reflection.primary_key_name => Hobo.raw_js('this.value')
|
84
84
|
} })
|
85
85
|
%>
|
86
86
|
<select onchange="#{f}">
|
@@ -94,9 +94,9 @@
|
|
94
94
|
<if-can-edit><%
|
95
95
|
return object_link unless can_edit?
|
96
96
|
|
97
|
-
id ||=
|
97
|
+
id ||= dom_id + "_completer"
|
98
98
|
f = ajax_updater(object_url(this_parent),
|
99
|
-
|
99
|
+
update,
|
100
100
|
:method => "put",
|
101
101
|
:params => { this_parent.class.name.underscore => {
|
102
102
|
this_field => Hobo.raw_js("$('#{id}').value")
|
@@ -125,7 +125,7 @@
|
|
125
125
|
|
126
126
|
values = comma_split(values)
|
127
127
|
f = ajax_updater(object_url(this_parent),
|
128
|
-
|
128
|
+
update,
|
129
129
|
:method => "put",
|
130
130
|
:params => { this_parent.class.name.underscore => {
|
131
131
|
this_field => Hobo.raw_js('this.value')
|
@@ -141,9 +141,9 @@
|
|
141
141
|
<def tag="boolean-checkbox-editor" attrs="update, message"><%
|
142
142
|
raise HoboError.new("Not allowed to edit") unless can_edit?
|
143
143
|
f = ajax_updater(object_url(this_parent),
|
144
|
-
message || "Change #{this_field.to_s.titleize}",
|
145
144
|
update,
|
146
145
|
:method => "put",
|
146
|
+
:message => message,
|
147
147
|
:spinner_next_to => Hobo.raw_js("this"),
|
148
148
|
:params => { this_parent.class.name.underscore => {
|
149
149
|
this_field => Hobo.raw_js('this.checked')
|
@@ -159,11 +159,11 @@
|
|
159
159
|
<% base_class = this.class
|
160
160
|
base_class = base_class.superclass while base_class.superclass != ActiveRecord::Base
|
161
161
|
f = ajax_updater("#{base_url}/#{controller_for base_class}/#{this.id}",
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
162
|
+
update,
|
163
|
+
:method => "put",
|
164
|
+
:params => { base_class.name.underscore => {
|
165
|
+
"type" => Hobo.raw_js('this.value')
|
166
|
+
} })
|
167
167
|
%>
|
168
168
|
|
169
169
|
<select onchange="#{f}">
|
@@ -175,7 +175,7 @@
|
|
175
175
|
|
176
176
|
<def tag="integer-select-editor" attrs="min, max, update, nil-option, message">
|
177
177
|
<select class="number-editor-bhv" hobo-update="#{update}"
|
178
|
-
hobo-model-id="#{
|
178
|
+
hobo-model-id="#{dom_id}"
|
179
179
|
merge-attrs="&message ? attributes.merge(:hobo_message => message) : attributes">
|
180
180
|
<if test="&this.nil?"><option value=""><%= nil_option || "Choose a value" %></option></if>
|
181
181
|
<%= options_for_select((min.to_i..max.to_i).to_a, this) %>
|
@@ -197,17 +197,17 @@
|
|
197
197
|
if obj == nil
|
198
198
|
new = klass.new(fields)
|
199
199
|
permission = if can_create?(new)
|
200
|
-
message ||= "Setting #{new.class.name.titleize}"
|
201
200
|
class_name = new.class.name.underscore
|
202
|
-
|
203
|
-
|
201
|
+
ajax_options = { :message => message }
|
202
|
+
ajax_options[:params] = { class_name => fields } unless fields.empty?
|
203
|
+
checkbox_attrs[:onclick] = ajax_updater(object_url(new.class), update, ajax_options)
|
204
204
|
end
|
205
205
|
else
|
206
206
|
permission = if can_delete?(obj)
|
207
207
|
checkbox_attrs[:checked] = 'checked'
|
208
208
|
message ||= "Unsetting #{obj.class.name.titleize}"
|
209
209
|
class_name = obj.class.name.underscore
|
210
|
-
checkbox_attrs[:onclick] = ajax_updater(object_url(obj, "destroy"),
|
210
|
+
checkbox_attrs[:onclick] = ajax_updater(object_url(obj, "destroy"), update, {:message => message, :method => 'delete'})
|
211
211
|
end
|
212
212
|
end
|
213
213
|
element(:input, add_classes(attributes.merge(checkbox_attrs),
|
@@ -20,58 +20,73 @@
|
|
20
20
|
%></def>
|
21
21
|
|
22
22
|
|
23
|
-
<def tag="form" attrs="
|
23
|
+
<def tag="form" attrs="update, hidden-fields, action, method, web-method"><%=
|
24
24
|
ajax_attrs, html_attrs = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
25
25
|
|
26
|
-
|
26
|
+
new_record = this.try.new_record?
|
27
27
|
|
28
|
-
new_record = this.respond_to?(:new_record?) && this.new_record?
|
29
|
-
|
30
28
|
method = if method.nil?
|
31
29
|
(action || web_method || new_record) ? "post" : "put"
|
32
30
|
else
|
33
31
|
method.downcase
|
34
32
|
end
|
35
|
-
if method == "put"
|
36
|
-
http_method_hidden = hidden_field_tag("_method", "PUT")
|
37
|
-
html_attrs[:method] = "post"
|
38
|
-
else
|
39
|
-
html_attrs[:method] = method
|
40
|
-
end
|
41
|
-
|
42
|
-
if update || !ajax_attrs.empty?
|
43
|
-
message ||= "Creating #{this.class.name.titleize}" if new_record
|
44
|
-
# add an onsubmit to convert to an ajax form if `update` is given
|
45
|
-
function = ajax_updater(:post_form, message, update, ajax_attrs)
|
46
|
-
html_attrs[:onsubmit] = [html_attrs[:onsubmit], "#{function}; return false;"].compact.join("; ")
|
47
|
-
end
|
48
33
|
|
49
|
-
|
50
|
-
scope[:in_form] = true
|
51
|
-
with_form_context { parameters.default }
|
52
|
-
end
|
53
|
-
|
54
|
-
hiddens = hidden_fields(:fields => hidden_fields, :skip => field_names) if new_record
|
55
|
-
|
56
|
-
auth_token = if request_forgery_protection_token.nil?
|
57
|
-
''
|
58
|
-
else
|
59
|
-
element(:input, :type => "hidden",
|
60
|
-
:name => request_forgery_protection_token.to_s,
|
61
|
-
:value => form_authenticity_token)
|
62
|
-
end
|
63
|
-
|
64
|
-
page_path_hidden = hidden_field_tag("page_path", view_name)
|
65
|
-
|
66
|
-
body = [http_method_hidden, page_path_hidden, auth_token, hiddens, body].join
|
34
|
+
html_attrs[:action] = action || object_url(this, web_method, :method => method)
|
67
35
|
|
68
|
-
if
|
69
|
-
|
36
|
+
if html_attrs[:action].nil? || (new_record && !this.user_can_create?(current_user))
|
37
|
+
Hobo::Dryml.last_if = false
|
38
|
+
""
|
70
39
|
else
|
71
|
-
|
40
|
+
if method == "put"
|
41
|
+
# browsers don't support put -- use post and add the Rails _method hack
|
42
|
+
http_method_hidden = hidden_field_tag("_method", "PUT")
|
43
|
+
html_attrs[:method] = "post"
|
44
|
+
else
|
45
|
+
html_attrs[:method] = method
|
46
|
+
end
|
47
|
+
|
48
|
+
if update || !ajax_attrs.empty?
|
49
|
+
# add an onsubmit to convert to an ajax form if `update` is given
|
50
|
+
function = ajax_updater(:post_form, update, ajax_attrs)
|
51
|
+
html_attrs[:onsubmit] = [html_attrs[:onsubmit], "#{function}; return false;"].compact.join("; ")
|
52
|
+
end
|
53
|
+
|
54
|
+
body, field_names = scope.new_scope do
|
55
|
+
scope[:in_form] = true
|
56
|
+
with_form_context { parameters.default }
|
57
|
+
end
|
58
|
+
|
59
|
+
hiddens = hidden_fields(:fields => hidden_fields, :skip => field_names) if new_record
|
60
|
+
|
61
|
+
auth_token = if request_forgery_protection_token.nil?
|
62
|
+
''
|
63
|
+
else
|
64
|
+
element(:input, :type => "hidden",
|
65
|
+
:name => request_forgery_protection_token.to_s,
|
66
|
+
:value => form_authenticity_token)
|
67
|
+
end
|
68
|
+
|
69
|
+
page_path = if request.post? || request.put? && params[:page_path]
|
70
|
+
params[:page_path]
|
71
|
+
else
|
72
|
+
view_name.sub(Hobo::Dryml::EMPTY_PAGE, params[:action])
|
73
|
+
end
|
74
|
+
page_path_hidden = hidden_field_tag("page_path", page_path) unless method == "get"
|
75
|
+
|
76
|
+
body = [http_method_hidden, page_path_hidden, auth_token, hiddens, body].join
|
77
|
+
|
78
|
+
|
79
|
+
if action.nil? # don't add automatic css classes if the action was specified
|
80
|
+
if web_method
|
81
|
+
add_classes!(html_attrs, "#{type_id}_#{web_method}_form")
|
82
|
+
else
|
83
|
+
add_classes!(html_attrs, "#{'new_' if new_record}#{type_id}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Hobo::Dryml.last_if = true
|
88
|
+
element("form", html_attrs, body)
|
72
89
|
end
|
73
|
-
|
74
|
-
element("form", html_attrs, body)
|
75
90
|
%></def>
|
76
91
|
|
77
92
|
|
@@ -89,19 +104,18 @@
|
|
89
104
|
elsif !can_edit?
|
90
105
|
view
|
91
106
|
else
|
92
|
-
attrs = add_classes(attributes, type_and_field)
|
93
|
-
the_input = if
|
94
|
-
if
|
107
|
+
attrs = add_classes(attributes, type_id, type_and_field)
|
108
|
+
the_input = if (refl = this_field_reflection)
|
109
|
+
if refl.macro == :belongs_to
|
95
110
|
belongs_to_input(attrs)
|
96
|
-
elsif
|
97
|
-
if
|
111
|
+
elsif refl.macro == :has_many
|
112
|
+
if refl.options[:through]
|
98
113
|
has_many_through_input(attrs)
|
99
114
|
else
|
100
115
|
has_many_input(attrs)
|
101
116
|
end
|
102
117
|
end
|
103
118
|
else
|
104
|
-
add_classes!(attrs, type_id)
|
105
119
|
attrs[:name] ||= param_name_for_this
|
106
120
|
the_input = call_polymorphic_tag('input', attrs) or
|
107
121
|
raise HoboError, ("No input tag for #{this_field}:#{this_type} (this=#{this.inspect})")
|
@@ -132,12 +146,12 @@
|
|
132
146
|
</def>
|
133
147
|
|
134
148
|
<def tag="input" for="date" attrs="order">
|
135
|
-
<% order = order.nil? ? [:year, :month, :day] : comma_split(order)
|
149
|
+
<% order = order.nil? ? [:year, :month, :day] : comma_split(order).*.to_sym -%>
|
136
150
|
<%= select_date(this || Time.now, attributes.merge(:prefix => param_name_for_this, :order => order)) %>
|
137
151
|
</def>
|
138
152
|
|
139
153
|
<def tag="input" for="datetime" attrs="order">
|
140
|
-
<% order = order.nil? ? [:year, :month, :day, :hour, :minute] : comma_split(order)
|
154
|
+
<% order = order.nil? ? [:year, :month, :day, :hour, :minute] : comma_split(order).*.to_sym -%>
|
141
155
|
<%= select_datetime(this || Time.now, attributes.merge(:prefix => param_name_for_this, :order => order)) %>
|
142
156
|
</def>
|
143
157
|
|
@@ -157,7 +171,7 @@
|
|
157
171
|
<%= text_field_tag(name, this, attributes) %>
|
158
172
|
</def>
|
159
173
|
|
160
|
-
<def tag="input" for="
|
174
|
+
<def tag="input" for="HoboFields::EnumString" attrs="labels,titleize">
|
161
175
|
<% labels ||= {} %>
|
162
176
|
<% titleize = true if titleize.nil? %>
|
163
177
|
<select name="#{param_name_for_this}" merge-attrs>
|
@@ -176,15 +190,15 @@
|
|
176
190
|
|
177
191
|
<!--- Buttons --->
|
178
192
|
|
179
|
-
<def tag="remote-method-button" attrs="method, update,
|
193
|
+
<def tag="remote-method-button" attrs="method, update, label"><%=
|
180
194
|
ajax_attributes, html_attributes = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
181
195
|
|
182
196
|
url = object_url(this, method)
|
183
197
|
add_classes!(html_attributes, "button remote-method-button #{method}-button")
|
184
|
-
if update || result_update
|
185
|
-
|
186
|
-
|
187
|
-
|
198
|
+
if update || result_update || !ajax_attrs.empty?
|
199
|
+
label ||= method.titleize
|
200
|
+
ajax_attributes[:message] ||= label
|
201
|
+
func = ajax_updater(url, update, ajax_attributes)
|
188
202
|
html_attributes.update(:onclick => "var e = this; " + func, :type =>'button', :value => label)
|
189
203
|
element(:input, html_attributes)
|
190
204
|
else
|
@@ -193,10 +207,10 @@
|
|
193
207
|
%></def>
|
194
208
|
|
195
209
|
|
196
|
-
<def tag="update-button" attrs="label,
|
210
|
+
<def tag="update-button" attrs="label, update, fields, params"><%=
|
197
211
|
raise HoboError.new("no update specified") unless update
|
198
|
-
message ||= label
|
199
|
-
func = ajax_updater(object_url(this),
|
212
|
+
ajax_attributes[:message] ||= label
|
213
|
+
func = ajax_updater(object_url(this), update,
|
200
214
|
:params => { this.class.name.underscore => fields }.merge(params || {}),
|
201
215
|
:method => :put)
|
202
216
|
element :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
@@ -204,8 +218,10 @@
|
|
204
218
|
</def>
|
205
219
|
|
206
220
|
|
207
|
-
<def tag="delete-button" attrs="label,
|
208
|
-
if
|
221
|
+
<def tag="delete-button" attrs="label, update, in-place, image, confirm, fade, subsite"><%=
|
222
|
+
in_place = false if in_place.nil? && this == @this
|
223
|
+
url = object_url(this, :method => :delete, :subsite => subsite)
|
224
|
+
if (Hobo::Dryml.last_if = url && can_delete?)
|
209
225
|
attributes = attributes.merge(if image
|
210
226
|
{ :type => "image", :src => "#{base_url}/images/#{image}" }
|
211
227
|
else
|
@@ -217,15 +233,17 @@
|
|
217
233
|
add_classes!(attributes,
|
218
234
|
image ? "image-button" : "button",
|
219
235
|
"delete-button delete-#{this.class.name.underscore.dasherize}-button")
|
220
|
-
url
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
236
|
+
if url
|
237
|
+
if in_place == false
|
238
|
+
attributes[:confirm] = confirm if confirm
|
239
|
+
attributes[:method] = :delete
|
240
|
+
button_to(label, url, attributes)
|
241
|
+
else
|
242
|
+
fade = true if fade.nil?
|
243
|
+
attributes[:value] = label
|
244
|
+
attributes[:onclick] = "Hobo.removeButton(this, '#{url}', #{js_updates(update)}, {fade:#{fade}, confirm: #{confirm.inspect}})"
|
245
|
+
element(:input, attributes)
|
246
|
+
end
|
229
247
|
end
|
230
248
|
else
|
231
249
|
""
|
@@ -233,14 +251,14 @@
|
|
233
251
|
%></def>
|
234
252
|
|
235
253
|
|
236
|
-
<def tag="create-button" attrs="model, update, label,
|
254
|
+
<def tag="create-button" attrs="model, update, label, fields, message"><%=
|
237
255
|
raise HoboError.new("no update specified") unless update
|
238
256
|
|
239
257
|
fields ||= {}
|
240
258
|
class_or_assoc = if model
|
241
259
|
model.is_a?(String) ? model.constantize : model
|
242
260
|
elsif Hobo.simple_has_many_association?(this)
|
243
|
-
fields[
|
261
|
+
fields[this_field_reflection.primary_key_name] = this.proxy_owner.id
|
244
262
|
this
|
245
263
|
else
|
246
264
|
raise HoboError.new("invalid context for <create-button>")
|
@@ -249,12 +267,12 @@
|
|
249
267
|
new.set_creator(current_user)
|
250
268
|
if can_create?(new)
|
251
269
|
label ||= "New #{new.class.name.titleize}"
|
252
|
-
message
|
270
|
+
ajax_attributes = { :message => message }
|
271
|
+
ajax_attributes[:params] = { class_name => fields } unless fields.empty?
|
253
272
|
class_name = new.class.name.underscore
|
254
|
-
func = ajax_updater(object_url(new.class), message, update,
|
255
|
-
({:params => { class_name => fields }} unless fields.empty?))
|
273
|
+
func = ajax_updater(object_url(new.class), message, update, ajax_attributes)
|
256
274
|
element :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
257
|
-
|
275
|
+
"button create-button create-#{class_name}-button")
|
258
276
|
end
|
259
277
|
%></def>
|
260
278
|
|
@@ -263,8 +281,9 @@
|
|
263
281
|
raise HoboError.new("Not allowed to edit") unless can_edit?
|
264
282
|
|
265
283
|
blank_message ||= "(No #{this_type.name.to_s.titleize})"
|
266
|
-
|
267
|
-
|
284
|
+
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this, this_field_reflection).conditions
|
285
|
+
options ||= this_field_reflection.klass.find(:all, :conditions => conditions).select {|x| can_view?(x)}
|
286
|
+
#Todo: switch to autocompleter for id_name when too many records, and id_name supported
|
268
287
|
select_options = options.map { |x|
|
269
288
|
[ name(:with => x, :no_wrapper => true), x.id ]
|
270
289
|
}.sort
|
@@ -281,7 +300,7 @@
|
|
281
300
|
<% refl = this_type
|
282
301
|
completer_model ||= refl.klass
|
283
302
|
completer_attr ||= refl.klass.id_name_column
|
284
|
-
id ||=
|
303
|
+
id ||= dom_id + "_completer"
|
285
304
|
where_attributes = attributes.select_hash {|k,v| k.to_s.starts_with? "where_"}
|
286
305
|
url = object_url(completer_model, :completions, { :for => completer_attr }.update(where_attributes))
|
287
306
|
%>
|
@@ -345,6 +364,19 @@
|
|
345
364
|
</def>
|
346
365
|
|
347
366
|
|
348
|
-
<def tag="after-submit" attrs="uri">
|
349
|
-
|
367
|
+
<def tag="after-submit" attrs="uri, stay-here, go-back">
|
368
|
+
<% uri = request.request_uri if stay_here %>
|
369
|
+
<% uri = session[:previous_uri] if go_back %>
|
370
|
+
<input type="hidden" value="¶ms[:after_submit] || uri" name="after_submit" if="&uri"/>
|
371
|
+
</def>
|
372
|
+
|
373
|
+
|
374
|
+
<def tag="hidden-field" attrs="name, value"><input type="hidden" name="&name" value="&value" merge-attrs/></def>
|
375
|
+
|
376
|
+
|
377
|
+
<def tag="select-menu" attrs="options, selected, first-option, first-value">
|
378
|
+
<select merge-attrs param="default">
|
379
|
+
<option value="#{first_value}" unless="&first_option.nil?"><first-option/></option>
|
380
|
+
<do param="options"><%= options_for_select(options, selected) %></do>
|
381
|
+
</select>
|
350
382
|
</def>
|