hobo 1.3.0.RC2 → 1.3.0.RC3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|