hobo 1.3.0.RC2 → 1.3.0.RC3
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/VERSION +1 -1
- data/lib/generators/hobo/rapid/templates/hobo-rapid.js +3 -1
- data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/clean.css +1 -0
- data/lib/generators/hobo/routes/router.rb +1 -1
- data/lib/hobo.rb +1 -1
- data/lib/hobo/controller/model.rb +10 -8
- data/lib/hobo/controller/{user.rb → user_base.rb} +2 -2
- data/lib/hobo/extensions/action_controller/hobo_methods.rb +1 -1
- data/lib/hobo/extensions/active_record/associations/collection.rb +12 -3
- data/lib/hobo/extensions/active_record/associations/reflection.rb +1 -1
- data/lib/hobo/helper.rb +6 -1
- data/lib/hobo/helper/translations.rb +1 -1
- data/lib/hobo/model.rb +24 -14
- data/lib/hobo/rapid/generators/rapid/forms.dryml.erb +1 -0
- data/lib/hobo/rapid/generators/rapid/pages.dryml.erb +9 -10
- data/lib/hobo/rapid/helper.rb +4 -3
- data/lib/hobo/rapid/taglibs/rapid_core.dryml +12 -4
- data/lib/hobo/rapid/taglibs/rapid_editing.dryml +35 -15
- data/lib/hobo/rapid/taglibs/rapid_forms.dryml +27 -18
- data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +1 -1
- data/lib/hobo/rapid/taglibs/rapid_plus.dryml +1 -1
- metadata +7 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.0.
|
1
|
+
1.3.0.RC3
|
@@ -34,6 +34,7 @@ var Hobo = {
|
|
34
34
|
var params = Hobo.fieldSetParam(el, val)
|
35
35
|
var p = el.getAttribute("hobo-ajax-params")
|
36
36
|
if (p) params = params + "&" + p
|
37
|
+
params = params + '&_method=PUT'
|
37
38
|
|
38
39
|
var opts = Object.merge(options || {}, { params: params, message: el.getAttribute("hobo-ajax-message")})
|
39
40
|
Hobo.ajaxRequest(Hobo.putUrl(el), updates, opts)
|
@@ -257,8 +258,9 @@ var Hobo = {
|
|
257
258
|
|
258
259
|
|
259
260
|
putUrl: function(el) {
|
261
|
+
/* we used to append _method=put here, but it doesn't work in Rails 3 */
|
260
262
|
var spec = Hobo.modelSpecForElement(el)
|
261
|
-
return urlBase + "/" + Hobo.pluralise(spec.name) + "/" + spec.id
|
263
|
+
return urlBase + "/" + Hobo.pluralise(spec.name) + "/" + spec.id
|
262
264
|
},
|
263
265
|
|
264
266
|
|
@@ -14,6 +14,7 @@ body {color: #193440; background: url(../images/300-ACD3E6-fff.png) repeat-x #ff
|
|
14
14
|
.section.content {background: #FCFFF5;}
|
15
15
|
.button {color: white; background: #5B8BA0;}
|
16
16
|
.button:hover {background-color: #193440;}
|
17
|
+
.button[disabled] { background-color: #CCCCCC; }
|
17
18
|
.add-to-collection {background: #E6E7DE;}
|
18
19
|
.aside { background: #E5E5E5;}
|
19
20
|
|
@@ -92,7 +92,7 @@ module Generators
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def user_routes
|
95
|
-
return [] unless controller < ::Hobo::Controller::
|
95
|
+
return [] unless controller < ::Hobo::Controller::UserBase
|
96
96
|
prefix = records == "users" ? "" : "#{record}_"
|
97
97
|
[
|
98
98
|
link("match '#{prefix}login(.:format)' => '#{records}#login', :as => '#{record}_login'", 'login'),
|
data/lib/hobo.rb
CHANGED
@@ -129,13 +129,15 @@ module Hobo
|
|
129
129
|
def auto_actions(*args)
|
130
130
|
options = args.extract_options!
|
131
131
|
|
132
|
-
@auto_actions =
|
132
|
+
@auto_actions = args.map do |arg|
|
133
|
+
case arg
|
133
134
|
when :all then available_auto_actions
|
134
|
-
when :write_only then available_auto_write_actions
|
135
|
-
when :read_only then available_auto_read_actions
|
136
|
-
when :lifecycle then available_auto_lifecycle_actions
|
137
|
-
else
|
138
|
-
|
135
|
+
when :write_only then available_auto_write_actions
|
136
|
+
when :read_only then available_auto_read_actions
|
137
|
+
when :lifecycle then available_auto_lifecycle_actions
|
138
|
+
else arg
|
139
|
+
end
|
140
|
+
end.flatten.uniq
|
139
141
|
|
140
142
|
except = Array(options[:except])
|
141
143
|
except_actions = except.map do |arg|
|
@@ -143,9 +145,9 @@ module Hobo
|
|
143
145
|
when :lifecycle then available_auto_lifecycle_actions
|
144
146
|
else arg
|
145
147
|
end
|
146
|
-
end
|
148
|
+
end.flatten.uniq
|
147
149
|
|
148
|
-
@auto_actions -= except_actions
|
150
|
+
@auto_actions -= except_actions
|
149
151
|
|
150
152
|
def_auto_actions
|
151
153
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Hobo
|
2
2
|
module Controller
|
3
|
-
|
3
|
+
module UserBase
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def included(base)
|
@@ -12,7 +12,7 @@ module Hobo
|
|
12
12
|
alias_method_chain :def_auto_actions, :user_actions
|
13
13
|
end
|
14
14
|
|
15
|
-
skip_before_filter :login_required, :only => [:login, :signup, :forgot_password, :reset_password, :do_reset_password,
|
15
|
+
skip_before_filter :login_required, :only => [:login, :signup, :do_signup, :forgot_password, :reset_password, :do_reset_password,
|
16
16
|
:accept_invitation, :do_accept_invitation]
|
17
17
|
|
18
18
|
include_taglib "rapid_user_pages", :plugin => "hobo"
|
@@ -28,12 +28,17 @@ module ActiveRecord
|
|
28
28
|
# DO NOT call super here - AssociationProxy's version loads the collection, and that's bad.
|
29
29
|
# TODO: this really belongs in Rails; migrate it there ASAP
|
30
30
|
def respond_to?(*args)
|
31
|
-
|
31
|
+
return super if has_one_collection?
|
32
|
+
proxy_respond_to?(*args) || [].respond_to?(*args)
|
32
33
|
end
|
33
34
|
|
34
|
-
# TODO: send this patch into Rails. There's no reason to load the collection just to find out it acts like an array.
|
35
35
|
def is_a?(klass)
|
36
|
-
|
36
|
+
if has_one_collection?
|
37
|
+
load_target
|
38
|
+
@target.is_a?(klass)
|
39
|
+
else
|
40
|
+
[].is_a?(klass)
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
def member_class
|
@@ -52,6 +57,10 @@ module ActiveRecord
|
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
60
|
+
def has_one_collection?
|
61
|
+
proxy_reflection.macro == :has_one
|
62
|
+
end
|
63
|
+
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
begin
|
10
10
|
klass_without_create_polymorphic_class
|
11
11
|
rescue NameError => e
|
12
|
-
Object.class_eval "class #{e.missing_name} < ActiveRecord::Base; set_table_name '#{active_record.name.tableize}'; end"
|
12
|
+
Object.class_eval "class #{e.missing_name} < ActiveRecord::Base; set_table_name '#{active_record.name.tableize}'; def self.hobo_shim?; true; end; end"
|
13
13
|
e.missing_name.constantize
|
14
14
|
end
|
15
15
|
else
|
data/lib/hobo/helper.rb
CHANGED
@@ -179,6 +179,10 @@ module Hobo
|
|
179
179
|
object.respond_to?(:typed_id) ? "model::#{typed_id(object, attribute).to_s.dasherize}" : ""
|
180
180
|
end
|
181
181
|
|
182
|
+
def update_elements_class(updates)
|
183
|
+
'update::'+comma_split(updates).join(':') unless updates.blank?
|
184
|
+
end
|
185
|
+
|
182
186
|
def can_create?(object=this)
|
183
187
|
if object.is_a?(Class) and object < ActiveRecord::Base
|
184
188
|
object = object.new
|
@@ -248,7 +252,8 @@ module Hobo
|
|
248
252
|
# TODO: Man does this need a big cleanup!
|
249
253
|
|
250
254
|
if args.empty?
|
251
|
-
if
|
255
|
+
# if we're repeating over an array, this_field ends up with the current index. Is this useful to anybody?
|
256
|
+
if this_parent && this_field && !this_field.is_a?(Integer)
|
252
257
|
object = this_parent
|
253
258
|
field = this_field
|
254
259
|
else
|
@@ -42,7 +42,7 @@ en:
|
|
42
42
|
raise Hobo::I18nError, %(wrong model name: "#{model_name}" (extracted from translation key: "#{key}"). You might want to use the translate/t tag/method instead.)
|
43
43
|
end
|
44
44
|
options[:default].unshift("hobo.#{keys.join(".")}".to_sym)
|
45
|
-
options[:model] = model_class.model_name.human(:count=>options[:count]||1)
|
45
|
+
options[:model] = model_class.model_name.human(:count=>(options[:count] || 1).to_i)
|
46
46
|
translate key.to_sym, options
|
47
47
|
end
|
48
48
|
alias_method :ht, :hobo_translate
|
data/lib/hobo/model.rb
CHANGED
@@ -33,17 +33,6 @@ module Hobo
|
|
33
33
|
alias_method_chain :attr_accessor, :creator_metadata
|
34
34
|
|
35
35
|
alias_method_chain :has_one, :new_method
|
36
|
-
|
37
|
-
# eval avoids the ruby 1.9.2 "super from singleton method ..." error
|
38
|
-
eval %(
|
39
|
-
def inherited(klass)
|
40
|
-
super
|
41
|
-
fields(false) do
|
42
|
-
Hobo.register_model(klass)
|
43
|
-
field(klass.inheritance_column, :string)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
)
|
47
36
|
end
|
48
37
|
|
49
38
|
base.fields(false) # force hobo_fields to load
|
@@ -172,6 +161,18 @@ module Hobo
|
|
172
161
|
send(:login_attribute=, name.to_sym, validate) if options.delete(:login) && respond_to?(:login_attribute=)
|
173
162
|
end
|
174
163
|
|
164
|
+
# eval avoids the ruby 1.9.2 "super from singleton method ..." error
|
165
|
+
eval %(
|
166
|
+
def inherited(klass)
|
167
|
+
super
|
168
|
+
Hobo::Model.register_model(klass)
|
169
|
+
# TODO: figure out when this is needed, as Hobofields already does this
|
170
|
+
fields(false) do
|
171
|
+
field(klass.inheritance_column, :string)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
)
|
175
|
+
|
175
176
|
private
|
176
177
|
|
177
178
|
def attrib_names
|
@@ -188,22 +189,27 @@ module Hobo
|
|
188
189
|
def belongs_to_with_test_methods(name, options={}, &block)
|
189
190
|
belongs_to_without_test_methods(name, options, &block)
|
190
191
|
refl = reflections[name]
|
192
|
+
id_method = refl.options[:primary_key] || refl.klass.primary_key
|
191
193
|
if options[:polymorphic]
|
192
194
|
# TODO: the class lookup in _is? below is incomplete; a polymorphic association to an STI base class
|
193
195
|
# will fail to match an object of a derived type
|
194
196
|
# (ie X belongs_to Y (polymorphic), Z is a subclass of Y; @x.y_is?(some_z) will never pass)
|
195
197
|
class_eval %{
|
196
198
|
def #{name}_is?(target)
|
197
|
-
target.class.name == self.#{refl.options[:foreign_type]} && target
|
199
|
+
target.class.name == self.#{refl.options[:foreign_type]} && target.#{id_method} == self.#{refl.primary_key_name}
|
198
200
|
end
|
199
201
|
def #{name}_changed?
|
200
202
|
#{refl.primary_key_name}_changed? || #{refl.options[:foreign_type]}_changed?
|
201
203
|
end
|
202
204
|
}
|
203
205
|
else
|
206
|
+
id_method = refl.options[:primary_key] || refl.klass.primary_key
|
204
207
|
class_eval %{
|
205
208
|
def #{name}_is?(target)
|
206
|
-
|
209
|
+
our_id = self.#{refl.primary_key_name}
|
210
|
+
# if our_id is nil, only return true if target is nil
|
211
|
+
return target.nil? unless our_id
|
212
|
+
target.class <= ::#{refl.klass.name} && target.#{id_method} == our_id
|
207
213
|
end
|
208
214
|
def #{name}_changed?
|
209
215
|
#{refl.primary_key_name}_changed?
|
@@ -464,7 +470,11 @@ module Hobo
|
|
464
470
|
if parts.include?(0)
|
465
471
|
nil
|
466
472
|
else
|
467
|
-
|
473
|
+
begin
|
474
|
+
Date.new(*parts)
|
475
|
+
rescue ArgumentError => ex
|
476
|
+
Time.time_with_datetime_fallback(ActiveRecord::Base.default_timezone, *parts).to_date
|
477
|
+
end
|
468
478
|
end
|
469
479
|
else
|
470
480
|
value
|
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
|
14
14
|
<% each_controller do -%>
|
15
|
-
|
15
|
+
<% next unless @controller < Hobo::Controller::Model %>
|
16
16
|
<!-- ====== <%= model.name %> Pages ====== -->
|
17
17
|
<%
|
18
18
|
new_link = linkable?(:new)
|
@@ -124,11 +124,10 @@ end
|
|
124
124
|
|
125
125
|
unless model.view_hints.secondary_children.empty?
|
126
126
|
aside_collections = model.view_hints.secondary_children.map { |c| [model.reflections[c], model.reverse_reflection(c)] }
|
127
|
-
aside_collections.reject! { |refl, reverse| reverse.nil? }
|
128
127
|
end
|
129
128
|
-%>
|
130
129
|
<def tag="show-page" for="<%= model.name %>">
|
131
|
-
<page merge title="#{ht '<%=model_key %>.show.title', :default=>['<%=sq_escape model_name %>'] }">
|
130
|
+
<page merge title="#{ht '<%=model_key %>.show.title', :default=>['<%=sq_escape model_name %>'], :name => name(:no_wrapper => true) }">
|
132
131
|
|
133
132
|
<body: class="show-page <%= model_class %>" param/>
|
134
133
|
|
@@ -142,8 +141,8 @@ end
|
|
142
141
|
<a:<%= back_link %> param="parent-link">« <ht key="<%= model_key %>.actions.back_to_parent" parent="<%= back_link_human_name %>" name="&this">Back to <name/></ht></a:<%= back_link %>>
|
143
142
|
<% end -%>
|
144
143
|
<h2 param="heading">
|
145
|
-
<ht key="<%= model_key %>.show.heading" name="
|
146
|
-
<name/>
|
144
|
+
<ht key="<%= model_key %>.show.heading" name="#{name(:no_wrapper => true)}">
|
145
|
+
<%= model_name %> <name/>
|
147
146
|
</ht>
|
148
147
|
</h2>
|
149
148
|
<% if boolean_fields -%>
|
@@ -160,7 +159,7 @@ end
|
|
160
159
|
<% if edit_link -%>
|
161
160
|
|
162
161
|
<a action="edit" if="&can_edit?" param="edit-link">
|
163
|
-
<ht key="<%= model_key %>.actions.edit" name="
|
162
|
+
<ht key="<%= model_key %>.actions.edit" name="#{name(:no_wrapper => true)}">
|
164
163
|
Edit <%= model_name %>
|
165
164
|
</ht>
|
166
165
|
</a>
|
@@ -169,7 +168,7 @@ end
|
|
169
168
|
|
170
169
|
<section param="content-body">
|
171
170
|
<% if main_content -%>
|
172
|
-
<view:<%= main_content %> param="description"/>
|
171
|
+
<view:<%= main_content %> param="description" />
|
173
172
|
<% end -%>
|
174
173
|
<% if show_fields.any? -%>
|
175
174
|
<field-list fields="<%= show_fields * ', ' %>" param/>
|
@@ -216,7 +215,7 @@ end
|
|
216
215
|
|
217
216
|
<aside param>
|
218
217
|
<% for refl, reverse_refl in aside_collections -%>
|
219
|
-
<% if linkable?(refl.klass, :"index_for_#{reverse_refl.name}") -%>
|
218
|
+
<% if reverse_refl && linkable?(refl.klass, :"index_for_#{reverse_refl.name}") -%>
|
220
219
|
<collection-preview:<%= refl.name %>.recent param="<%= refl.name %>-preview">
|
221
220
|
<heading-content:><human-collection-name with="&this.origin" collection="<%= refl.name %>" your/></heading-content:>
|
222
221
|
</collection-preview:<%= refl.name %>.recent>
|
@@ -244,14 +243,14 @@ end
|
|
244
243
|
name_attribute = model.name_attribute
|
245
244
|
-%>
|
246
245
|
<def tag="edit-page" for="<%= model.name %>">
|
247
|
-
<page merge title="#{ht '<%= model_key %>.edit.title', :default=>['Edit <%= sq_escape model_name %>'] }">
|
246
|
+
<page merge title="#{ht '<%= model_key %>.edit.title', :default=>['Edit <%= sq_escape model_name %>'], :name => name(:no_wrapper => true) }">
|
248
247
|
|
249
248
|
<body: class="edit-page <%= model_class %>" param/>
|
250
249
|
|
251
250
|
<content:>
|
252
251
|
<section param="content-header">
|
253
252
|
<h2 param="heading">
|
254
|
-
<ht key="<%= model_key %>.edit.heading" name="
|
253
|
+
<ht key="<%= model_key %>.edit.heading" name="#{name(:no_wrapper => true)}">
|
255
254
|
Edit <%= model_name %>
|
256
255
|
</ht>
|
257
256
|
</h2>
|
data/lib/hobo/rapid/helper.rb
CHANGED
@@ -120,15 +120,16 @@ module Hobo
|
|
120
120
|
edit_text = this._?.to_s
|
121
121
|
attributes.update(:hobo_edit_text => edit_text) unless edit_text.nil?
|
122
122
|
|
123
|
-
update = attributes.delete(:update)
|
124
|
-
|
123
|
+
if update = attributes.delete(:update)
|
124
|
+
attributes = add_classes(attributes, update_elements_class(update))
|
125
|
+
end
|
125
126
|
|
126
127
|
view(attributes)
|
127
128
|
end
|
128
129
|
|
129
130
|
|
130
131
|
|
131
|
-
AJAX_CALLBACKS = [ :
|
132
|
+
AJAX_CALLBACKS = [ :success, :failure, :complete ]
|
132
133
|
|
133
134
|
AJAX_ATTRS = AJAX_CALLBACKS + [ :update, :type, :method,
|
134
135
|
:script, :form, :params, :confirm, :message,
|
@@ -93,7 +93,15 @@ This will use `<input/>` as the tag in each table cell instead of `<view/>`
|
|
93
93
|
<table fields="name, created_at, description">
|
94
94
|
<controls:/>
|
95
95
|
</table>
|
96
|
-
|
96
|
+
|
97
|
+
The controls can be further customised using the "edit-link" and "delete-button" parameters:
|
98
|
+
|
99
|
+
<table fields="name, created_at, description">
|
100
|
+
<controls:/>
|
101
|
+
<delete-button: label="Nuke Me"/>
|
102
|
+
</table>
|
103
|
+
|
104
|
+
or by providing completely new content for the control column:
|
97
105
|
|
98
106
|
<table fields="name, created_at, description">
|
99
107
|
<controls:>my controls!</controls:>
|
@@ -681,8 +689,8 @@ The "titleize" attribute is deprecated: use "capitalize" instead.
|
|
681
689
|
</if>
|
682
690
|
<else>
|
683
691
|
<do param="default">
|
684
|
-
<%= s = t("tags.you.other_user.#{k || attributes.keys.first || 'default'}", :name=>
|
685
|
-
:default=>"#{
|
692
|
+
<%= s = t("tags.you.other_user.#{k || attributes.keys.first || 'default'}", :name=>name(:no_wrapper => true),
|
693
|
+
:default=>"#{name(:no_wrapper => true)} #{'has' if attributes[:have]}#{'is' if attributes[:are]}#{'does' if attributes[:do]}")
|
686
694
|
(titleize||capitalize) ? s.sub(/^./){|c| c.upcase} : s %>
|
687
695
|
</do>
|
688
696
|
</else>
|
@@ -750,7 +758,7 @@ Notes
|
|
750
758
|
attrs = {}
|
751
759
|
attributes.each_pair{|k,v| attrs[k.to_sym] = v}
|
752
760
|
d = "#{your_default} #{all_parameters.default}"
|
753
|
-
options = {:default=>[d], :count=>(attrs[:count]||1), :name=>
|
761
|
+
options = {:default=>[d], :count=>(attrs[:count]||1), :name=>name(:no_wrapper => true)}
|
754
762
|
your_key = key.split('.').last
|
755
763
|
unless key.eql?(your_key) || attrs.has_key?(your_key.to_sym)
|
756
764
|
options[your_key.to_sym] = t(key, :count=>options[:count], :default=>your_key.titleize)
|
@@ -81,25 +81,45 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
81
81
|
|
82
82
|
### Attributes
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
-
|
89
|
-
|
90
|
-
|
84
|
+
- `include-none` - whether to include a 'none' option (i.e. set the foreign key to null). If this value is not supplied, the default is "true" if the current value is nil; otherwise the default is "false". One implication of this is that the default may change when the form is re-rendered due to a validation failure. Setting this value explicitly is recommended.
|
85
|
+
- `blank-message` - the message for the 'none' option. Defaults to "(No `<model-name>`)", e.g. "(No Product)"
|
86
|
+
- `options` - an array of records to include in the menu. Defaults to the all the records in the target table that match any `:conditions` declared on the `belongs_to` (subject to `limit`)
|
87
|
+
- `sort` - whether to sort the array of options. Defaults to no sorting.
|
88
|
+
- `limit` - if `options` is not specified, this limits the number of records. Default: 100
|
89
|
+
- `text_method` - The method to call on each record to get the text for the option. Multiple methods are supported ie "institution.name"
|
90
|
+
- `update` - one or more DOM ID's (comma separated string or an array) to be updated as part of the ajax call.
|
91
91
|
|
92
92
|
NOTE: yes that's *DOM ID's* not part-names. A common source of confusion because by default the part name and DOM ID are the same.
|
93
93
|
|
94
94
|
-->
|
95
|
-
<def tag="select-one-editor" attrs="include-none, blank-message, sort,
|
95
|
+
<def tag="select-one-editor" attrs="include-none, blank-message, options, sort, limit, text-method, update"><%
|
96
96
|
raise Hobo::Error.new("Not allowed to edit") unless can_edit?
|
97
97
|
blank_message ||= ht("#{this_type.name.to_s.underscore}.select_one_editor.blank_message", :count => 0, :default => "(No #{this_type.name.to_s.titleize})")
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
limit ||= 100
|
99
|
+
|
100
|
+
if options.blank? || !options.first.respond_to?(:first)
|
101
|
+
options ||= begin
|
102
|
+
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).send(:conditions)
|
103
|
+
order = this_field_reflection.klass.default_order
|
104
|
+
this_field_reflection.klass.all(:conditions => conditions, :limit => limit, :order => order).select {|x| can_view?(x)}
|
105
|
+
end
|
106
|
+
|
107
|
+
id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
|
108
|
+
if text_method.nil?
|
109
|
+
select_options = options.map { |x| [name(:with => x, :no_wrapper => true), x.send(id_method)] }
|
110
|
+
else
|
111
|
+
select_options = options.map do |x|
|
112
|
+
[ text_method.split(".").inject(x) { |v, method| v.send(method) },
|
113
|
+
x.send(id_method) ]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
else
|
117
|
+
# handle the old style, where options could be passed an options_for_select style array
|
118
|
+
select_options = options
|
119
|
+
end
|
120
|
+
select_options = select_options.sort if sort
|
121
|
+
select_options.insert(0, [blank_message, ""]) if include_none || (this.nil? && include_none != false)
|
122
|
+
|
103
123
|
f = ajax_updater(object_url(this_parent, :method => :put),
|
104
124
|
update,
|
105
125
|
:method => "put",
|
@@ -108,7 +128,7 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
108
128
|
} })
|
109
129
|
%>
|
110
130
|
<select onchange="#{f}" merge-attrs>
|
111
|
-
<%= options_for_select(
|
131
|
+
<%= options_for_select(select_options, this ? this.send(id_method) : "") %>
|
112
132
|
</select>
|
113
133
|
</def>
|
114
134
|
|
@@ -216,7 +236,7 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
216
236
|
-->
|
217
237
|
<def tag="integer-select-editor" attrs="options, min, max, update, nil-option, message">
|
218
238
|
<% options ||= (min.to_i..max.to_i).to_a %>
|
219
|
-
<select class="integer editor #{
|
239
|
+
<select class="integer editor #{update_elements_class(update)} #{model_id_class(this_parent, this_field)}"
|
220
240
|
merge-attrs="&message ? attributes.merge(:hobo_message => message) : attributes">
|
221
241
|
<if test="&this.nil?"><option value=""><%= nil_option || "Choose a value" %></option></if>
|
222
242
|
<%= options_for_select(options.*.to_s, this.to_s) %>
|
@@ -32,8 +32,6 @@ Several of the tags in this taglib support the following set of ajax attributes:
|
|
32
32
|
The following attributes are also supported by all the ajax tags. Set them to fragments of javascript to have that script
|
33
33
|
executed at various points in the ajax request cycle:
|
34
34
|
|
35
|
-
- before: script to run before the request
|
36
|
-
|
37
35
|
- success: script to run on successful completion of the request
|
38
36
|
|
39
37
|
- failure: script to run on a request failure
|
@@ -635,7 +633,8 @@ All of the standard ajax attributes are supported (see the main taglib documenti
|
|
635
633
|
class_or_assoc = if model
|
636
634
|
model.is_a?(String) ? model.constantize : model
|
637
635
|
elsif Hobo.simple_has_many_association?(this)
|
638
|
-
|
636
|
+
id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
|
637
|
+
fields[this_field_reflection.primary_key_name] = this.proxy_owner.send(id_method)
|
639
638
|
this
|
640
639
|
else
|
641
640
|
raise Hobo::Error.new("invalid context for <create-button>")
|
@@ -644,11 +643,17 @@ All of the standard ajax attributes are supported (see the main taglib documenti
|
|
644
643
|
new.set_creator(current_user)
|
645
644
|
if can_create?(new)
|
646
645
|
label ||= ht("#{new.class.to_s.underscore}.actions.new", :default=>"New #{new.class.model_name.human}")
|
647
|
-
ajax_attributes = { :message => message }
|
648
646
|
class_name = new.class.name.underscore
|
649
|
-
|
647
|
+
params ||= params || {}
|
648
|
+
params = params.merge(class_name => fields) unless fields.blank?
|
649
|
+
|
650
|
+
ajax_attributes, html_attributes = attributes.partition_hash(Hobo::Rapid::Helper::AJAX_ATTRS)
|
651
|
+
|
652
|
+
ajax_attributes.reverse_merge!(:message => message, :params => params)
|
650
653
|
func = ajax_updater(object_url(new.class, :method => :post), update, ajax_attributes)
|
651
|
-
|
654
|
+
html_attributes.reverse_merge!(:type =>'button', :onclick => func, :value => label)
|
655
|
+
|
656
|
+
element :input, add_classes(html_attributes,
|
652
657
|
"button create-button create-#{class_name}-button"), nil, true, true
|
653
658
|
end
|
654
659
|
%></def>
|
@@ -663,6 +668,7 @@ This is the default input that Rapid uses for `belongs_to` associations. The men
|
|
663
668
|
- `include-none` - whether to include a 'none' option (i.e. set the foreign key to null). If this value is not supplied, the default is "true" if the current value is nil; otherwise the default is "false". One implication of this is that the default may change when the form is re-rendered due to a validation failure. Setting this value explicitly is recommended.
|
664
669
|
- `blank-message` - the message for the 'none' option. Defaults to "(No `<model-name>`)", e.g. "(No Product)"
|
665
670
|
- `options` - an array of records to include in the menu. Defaults to the all the records in the target table that match any `:conditions` declared on the `belongs_to` (subject to `limit`)
|
671
|
+
- `sort` - whether to sort the array of options. Defaults to no sorting.
|
666
672
|
- `limit` - if `options` is not specified, this limits the number of records. Default: 100
|
667
673
|
- `text_method` - The method to call on each record to get the text for the option. Multiple methods are supported ie "institution.name"
|
668
674
|
|
@@ -682,12 +688,13 @@ For situations where there are too many target records to practically include in
|
|
682
688
|
this_field_reflection.klass.all(:conditions => conditions, :limit => limit, :order => order).select {|x| can_view?(x)}
|
683
689
|
end
|
684
690
|
|
691
|
+
id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
|
685
692
|
if text_method.nil?
|
686
|
-
select_options = options.map { |x| [x
|
693
|
+
select_options = options.map { |x| [name(:with => x, :no_wrapper => true), x.send(id_method)] }
|
687
694
|
else
|
688
695
|
select_options = options.map do |x|
|
689
696
|
[ text_method.split(".").inject(x) { |v, method| v.send(method) },
|
690
|
-
x.
|
697
|
+
x.send(id_method) ]
|
691
698
|
end
|
692
699
|
end
|
693
700
|
select_options = select_options.sort if sort
|
@@ -695,7 +702,7 @@ For situations where there are too many target records to practically include in
|
|
695
702
|
attributes = add_classes(attributes, "input", "belongs_to", type_and_field)
|
696
703
|
-%>
|
697
704
|
<select name="#{param_name_for_this(true)}" merge-attrs="&attributes.except :name">
|
698
|
-
<%= options_for_select(select_options, this ? this.
|
705
|
+
<%= options_for_select(select_options, this ? this.send(id_method) : "") %>
|
699
706
|
</select>
|
700
707
|
</def>
|
701
708
|
|
@@ -766,11 +773,13 @@ If you wish to set `min-chars` to 0, you will require this [patch to controls.js
|
|
766
773
|
min_chars ||= 1
|
767
774
|
value = name(:no_wrapper => true, :if_present => true)
|
768
775
|
-%>
|
769
|
-
<
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
776
|
+
<wrap tag="span" class="field-with-errors" when="&!this_parent.errors[this_field].empty?">
|
777
|
+
<input type="text" name="#{param_name_for_this}"
|
778
|
+
class="autocompleter #{type_and_field._?.dasherize} #{css_data :complete_on, typed_id(complete_target), completer} #{css_data :min_chars, min_chars} #{'nil-value' if value==''}"
|
779
|
+
value="#{value=='' ? nil_value : value}"
|
780
|
+
merge-attrs/>
|
781
|
+
<div class="completions-popup" style="display:none"></div>
|
782
|
+
</wrap>
|
774
783
|
</def>
|
775
784
|
|
776
785
|
|
@@ -877,7 +886,7 @@ Use the `stay-here` attribute to remain on the current page:
|
|
877
886
|
...
|
878
887
|
</form>
|
879
888
|
|
880
|
-
Use the `go-back` option to return to the
|
889
|
+
Use the `go-back` option to return to the page in `session[:previous_uri]`:
|
881
890
|
|
882
891
|
<form>
|
883
892
|
<after-submit go-back/>
|
@@ -919,7 +928,7 @@ Use the `uri` option to specify a redirect location:
|
|
919
928
|
<select merge-attrs param="default">
|
920
929
|
<% selected=this if selected.nil? %>
|
921
930
|
<option value="#{first_value}" unless="&first_option.nil?"><first-option/></option>
|
922
|
-
<do param="options"
|
931
|
+
<do param="options"><%= options_for_select(options, selected) %></do>
|
923
932
|
</select>
|
924
933
|
</def>
|
925
934
|
|
@@ -944,8 +953,8 @@ Use the `uri` option to specify a redirect location:
|
|
944
953
|
<input type="hidden" name="#{param_name}[]" value=""/><% # ensure all items are removed when nothing checked
|
945
954
|
%>
|
946
955
|
<li repeat="&options" param>
|
947
|
-
<input type="checkbox" name="#{param_name}[]" value="@#{this.id}" checked="&this.in?(collection)" disabled="&disabled"/>
|
948
|
-
<name param
|
956
|
+
<input id="#{dom_id(this, :check_many)}" type="checkbox" name="#{param_name}[]" value="@#{this.id}" checked="&this.in?(collection)" disabled="&disabled"/>
|
957
|
+
<label for="#{dom_id(this, :check_many)}"><name param/></label>
|
949
958
|
</li>
|
950
959
|
</ul>
|
951
960
|
</def>
|
@@ -98,7 +98,7 @@ With the `your` attribute and in the special case the context is a Hobo::Model::
|
|
98
98
|
attrs = {}
|
99
99
|
all_attributes.each_pair{|k,v| attrs[k.to_sym] = v} -%>
|
100
100
|
<% if your && belong_class < Hobo::Model::UserBase && this.kind_of?(Hobo::Model::UserBase) && I18n.locale == :en -%>
|
101
|
-
<your key="&collection" merge-attrs="&{:name=>
|
101
|
+
<your key="&collection" merge-attrs="&{:name=>name(:no_wrapper => true)}.merge(attrs)" capitalize>
|
102
102
|
<%= belong_class.human_attribute_name(collection.to_sym, attrs) %>
|
103
103
|
</your>
|
104
104
|
<% else -%>
|
@@ -13,7 +13,7 @@ An [worked example](/tutorials/agility#improve_the_project_page_with_a_searchabl
|
|
13
13
|
<div class="table-plus" merge-attrs="&attributes - attrs_for(:with_fields) - attrs_for(:table)">
|
14
14
|
<div class="header" param="header">
|
15
15
|
<div class="search">
|
16
|
-
<form param="search-form" method="get" action="">
|
16
|
+
<form param="search-form" method="get" action="" with="&nil">
|
17
17
|
<hidden-fields for-query-string skip="page, search"/>
|
18
18
|
<span><t key="hobo.table_plus.search">Search</t></span>
|
19
19
|
<input class="search" type="search" name="search" value="¶ms[:search]"/>
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: hobo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 1.3.0.
|
5
|
+
version: 1.3.0.RC3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tom Locke
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-10-25 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - "="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 1.3.0.
|
24
|
+
version: 1.3.0.RC3
|
25
25
|
type: :runtime
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 1.3.0.
|
35
|
+
version: 1.3.0.RC3
|
36
36
|
type: :runtime
|
37
37
|
version_requirements: *id002
|
38
38
|
- !ruby/object:Gem::Dependency
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
requirements:
|
44
44
|
- - "="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 1.3.0.
|
46
|
+
version: 1.3.0.RC3
|
47
47
|
type: :runtime
|
48
48
|
version_requirements: *id003
|
49
49
|
- !ruby/object:Gem::Dependency
|
@@ -228,7 +228,7 @@ files:
|
|
228
228
|
- lib/hobo/controller.rb
|
229
229
|
- lib/hobo/controller/authentication_support.rb
|
230
230
|
- lib/hobo/controller/model.rb
|
231
|
-
- lib/hobo/controller/
|
231
|
+
- lib/hobo/controller/user_base.rb
|
232
232
|
- lib/hobo/engine.rb
|
233
233
|
- lib/hobo/extensions/action_controller/hobo_methods.rb
|
234
234
|
- lib/hobo/extensions/action_mailer/helper.rb
|
@@ -341,7 +341,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
341
341
|
requirements: []
|
342
342
|
|
343
343
|
rubyforge_project: hobo
|
344
|
-
rubygems_version: 1.
|
344
|
+
rubygems_version: 1.6.2
|
345
345
|
signing_key:
|
346
346
|
specification_version: 3
|
347
347
|
summary: The web app builder for Rails
|