hobo_rapid 1.4.0.pre8 → 2.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/app/helpers/hobo_rapid_helper.rb +30 -3
- data/taglibs/buttons/create_button.dryml +33 -28
- data/taglibs/buttons/delete-button.dryml +1 -1
- data/taglibs/buttons/remote_method_button.dryml +10 -12
- data/taglibs/buttons/transition_button.dryml +27 -11
- data/taglibs/buttons/update_button.dryml +11 -24
- data/taglibs/forms/form.dryml +4 -1
- data/taglibs/html/a.dryml +8 -2
- data/taglibs/inputs/input_many.dryml +1 -1
- data/taglibs/inputs/select_many.dryml +2 -2
- data/taglibs/inputs/sortable_input_many.dryml +10 -6
- data/taglibs/lists/with_fields.dryml +23 -75
- data/taglibs/plus/filter_menu.dryml +1 -1
- data/taglibs/plus/live_search.dryml +8 -4
- data/taglibs/views/links_for_collection.dryml +2 -2
- metadata +4 -5
- data/taglibs/inputs/name_one.dryml +0 -74
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0.pre1
|
@@ -9,9 +9,9 @@ module HoboRapidHelper
|
|
9
9
|
|
10
10
|
AJAX_PUSHSTATE_ATTRS = [:push_state, :new_title]
|
11
11
|
|
12
|
-
AJAX_ATTRS = AJAX_CALLBACKS + AJAX_UPDATE_ATTRS + AJAX_EFFECT_ATTRS + AJAX_SPINNER_ATTRS + AJAX_PUSHSTATE_ATTRS
|
13
|
-
|
14
|
-
|
12
|
+
AJAX_ATTRS = AJAX_CALLBACKS + AJAX_UPDATE_ATTRS + AJAX_EFFECT_ATTRS + AJAX_SPINNER_ATTRS + AJAX_PUSHSTATE_ATTRS +
|
13
|
+
[:params, :errors_ok,
|
14
|
+
:reset_form, :refocus_form ]
|
15
15
|
|
16
16
|
def app_name(add_subsite=true)
|
17
17
|
an = Rails.application.config.hobo.app_name
|
@@ -194,4 +194,31 @@ module HoboRapidHelper
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
# the meat of with-fields, with-field-names, with-fields-grouped.
|
198
|
+
# returns the list of field names
|
199
|
+
def with_fields_helper(attrs)
|
200
|
+
attrs[:fields].nil? || attrs[:associations].nil? or raise ArgumentError, "with-fields -- specify either fields or associations but not both"
|
201
|
+
|
202
|
+
field_names = if attrs[:associations] == "has_many"
|
203
|
+
this.class.reflections.values.select { |refl| refl.macro == :has_many }.map { |refl| refl.name.to_s }
|
204
|
+
|
205
|
+
elsif attrs[:fields].nil? || attrs[:fields] == "*" || attrs[:fields].is_a?(Class)
|
206
|
+
klass = attrs[:fields].is_a?(Class) ? attrs[:fields] : this.class
|
207
|
+
columns = standard_fields(klass, attrs[:include_timestamps])
|
208
|
+
|
209
|
+
if attrs[:skip_associations] == "has_many"
|
210
|
+
assocs = this.class.reflections.values.reject {|r| r.macro == :has_many }.map &its.name.to_s
|
211
|
+
columns + assocs
|
212
|
+
elsif attrs[:skip_associations]
|
213
|
+
columns
|
214
|
+
else
|
215
|
+
assocs = klass.reflections.values.map &its.name.to_s
|
216
|
+
columns + assocs
|
217
|
+
end
|
218
|
+
else
|
219
|
+
comma_split(attrs[:fields].gsub('-', '_'))
|
220
|
+
end
|
221
|
+
field_names -= comma_split(attrs[:skip]) if attrs[:skip]
|
222
|
+
field_names
|
223
|
+
end
|
197
224
|
end
|
@@ -1,40 +1,45 @@
|
|
1
|
-
<!-- Provides
|
2
|
-
|
3
|
-
All of the standard ajax attributes are supported (see the main taglib documention for Rapid Forms).
|
1
|
+
<!-- Provides a button that will create a new resource. This is normally used with ajax attributes.
|
4
2
|
|
5
3
|
### Attributes
|
6
4
|
|
7
|
-
|
5
|
+
All standard ajax attributes are supported, plus:
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
- model: The class to instantiate, pass either the class name or the class object. If model is not supplied, the current context (aka this) must be a has-many association.
|
8
|
+
|
9
|
+
- label: the button label. Rather than using this attribute, the best way to customize this label is to set the i18n key `<class_name>.actions.new`
|
10
|
+
|
11
|
+
- fields: a hash containing fields and their values to set on the new object
|
12
|
+
|
13
|
+
### Example
|
12
14
|
|
15
|
+
<create-button update="foo" label="New" fields="&{name: 'Hello'}"/>
|
16
|
+
|
17
|
+
is equivalent to:
|
18
|
+
|
19
|
+
<form with="&this.new" update="foo">
|
20
|
+
<field-list: replace>
|
21
|
+
<hidden-field:name value="Hello"/>
|
22
|
+
</field-list:>
|
23
|
+
<submit: label="New"/>
|
24
|
+
</form>
|
25
|
+
-->
|
26
|
+
<def tag="create-button" attrs="model, label, fields"><%
|
13
27
|
fields ||= {}
|
14
28
|
class_or_assoc = if model
|
15
29
|
model.is_a?(String) ? model.constantize : model
|
16
|
-
elsif Hobo.simple_has_many_association?(this)
|
17
|
-
id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
|
18
|
-
fields[this_field_reflection.foreign_key] = this.proxy_owner.send(id_method)
|
19
|
-
this
|
20
30
|
else
|
21
|
-
|
31
|
+
this
|
22
32
|
end
|
23
33
|
new = class_or_assoc.new(fields)
|
24
34
|
new.set_creator(current_user)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
element :input, add_classes(html_attributes,
|
38
|
-
"button create-button create-#{class_name}-button"), nil, true, true
|
39
|
-
end
|
40
|
-
%></def>
|
35
|
+
label ||= ht("#{new.class.to_s.underscore}.actions.new", :default=>"New #{new.class.model_name.human}")
|
36
|
+
%>
|
37
|
+
<form with="&new" without-cancel param class="button_to" merge>
|
38
|
+
<submit: label="&label"/>
|
39
|
+
<field-list: replace>
|
40
|
+
<% fields.each do |field, val| %>
|
41
|
+
<hidden-field field="&field" value="&val"/>
|
42
|
+
<% end %>
|
43
|
+
</field-list:>
|
44
|
+
</form>
|
45
|
+
</def>
|
@@ -28,7 +28,7 @@ then `delete-button` performs an Ajax delete and then attempts to fix up the pag
|
|
28
28
|
|
29
29
|
### Attributes
|
30
30
|
|
31
|
-
All the standard ajax attributes *except the callbacks* are supported (see the main taglib
|
31
|
+
All the standard ajax attributes *except the callbacks* are supported (see the main taglib documentation for Rapid Forms).
|
32
32
|
|
33
33
|
- label: The label for the button. Default: "Remove". (Alternately, use the hobo.actions.remove translation to customize)
|
34
34
|
|
@@ -1,21 +1,21 @@
|
|
1
|
-
<!--
|
2
|
-
Web Methods provide support for the RPC model of client-server interaction, in contrast to the REST model. The
|
3
|
-
preference in Rails is to use REST as much as possible, but we are pragmatists, and sometimes you just to need a remote
|
4
|
-
procedure call.
|
1
|
+
<!-- DEPRECATED. remote-method-button is provided for backwards compatibility. Ajax functionality is no longer supported. This would be easy to fix, but testing is harder, so if you want to volunteer to test it, we can fix it for you.
|
5
2
|
|
6
|
-
|
3
|
+
You can replace remote-method-button with something like:
|
7
4
|
|
8
|
-
|
9
|
-
Forms). If any ajax attributes are given, the button becomes an ajax button, if not, Rails' `button_to` is used, which behaves similarly to a standard link.
|
5
|
+
<form action="method" method="POST"><submit/></form>
|
10
6
|
|
11
7
|
### Attributes
|
12
8
|
|
9
|
+
Either method or url must be specified.
|
10
|
+
|
13
11
|
- method: the name of the web-method to call
|
14
12
|
|
15
13
|
- label: the label on the button
|
16
14
|
|
15
|
+
- url: use this url instead of looking it up
|
16
|
+
|
17
17
|
-->
|
18
|
-
<def tag="remote-method-button" attrs="method,
|
18
|
+
<def tag="remote-method-button" attrs="method, label, url"><%=
|
19
19
|
ajax_attributes, html_attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
20
20
|
|
21
21
|
url ||= object_url(this, method.to_s.gsub('-', '_'), :method => :post)
|
@@ -23,11 +23,9 @@ Forms). If any ajax attributes are given, the button becomes an ajax button, if
|
|
23
23
|
|
24
24
|
add_classes!(html_attributes, "button remote-method-button #{method}-button")
|
25
25
|
label ||= method.titleize
|
26
|
-
if
|
26
|
+
if !ajax_attributes.empty?
|
27
27
|
ajax_attributes[:message] ||= label
|
28
|
-
|
29
|
-
html_attributes.update(:onclick => "var e = this; " + func, :type =>'button', :value => label)
|
30
|
-
element(:input, html_attributes, nil, true, true)
|
28
|
+
fail "UNSUPPORTED"
|
31
29
|
else
|
32
30
|
button_to(label, url, html_attributes.merge(:confirm => confirm))
|
33
31
|
end
|
@@ -1,16 +1,27 @@
|
|
1
|
-
<!-- A push
|
1
|
+
<!-- A push button to invoke a lifecycle transition.
|
2
|
+
|
3
|
+
If the transition has parameters or no ajax attributes are supplied, the push-button simply moves to the transition page. This is bad form, you probably should use `<transition-link>` instead.
|
4
|
+
|
5
|
+
If the transition has no parameters and ajax attributes are supplied, ajax is used to perform the transaction.
|
6
|
+
|
7
|
+
If your transition has parameters and/or you don't want to use ajax, use and parametrize the automatically generated transition form.
|
8
|
+
|
9
|
+
<transition-button transition="mogrify" ajax/>
|
10
|
+
|
11
|
+
is equivalent to
|
12
|
+
|
13
|
+
<mogrify-form without-cancel without-field-list ajax />
|
2
14
|
|
3
15
|
### Attributes
|
4
16
|
|
5
17
|
- `transition` - the name of the transition to invoke. Required
|
6
|
-
- `update` - one or more DOM IDs of ajax parts to update after the transition
|
7
18
|
- `label` - the label on the button. Defaults to the name of the transition
|
8
19
|
|
9
20
|
All of the [standard ajax attributes](/api_taglibs/rapid_forms) are also supported.
|
10
21
|
|
11
22
|
### Warning
|
12
23
|
|
13
|
-
|
24
|
+
Buttons are implemented using a form. HTML does not allow forms to be nested, so a transition-button should not be placed inside of a form.
|
14
25
|
|
15
26
|
### Invalid transitions
|
16
27
|
|
@@ -19,7 +30,7 @@ If the transition could not be found, the user does not have permissions for the
|
|
19
30
|
<transition-button transition="mogrify"/><else>Cannot mogrify</else>
|
20
31
|
|
21
32
|
-->
|
22
|
-
<def tag="transition-button" attrs="transition,
|
33
|
+
<def tag="transition-button" attrs="transition, label"><%
|
23
34
|
if transition.is_a?(String)
|
24
35
|
transition = this.lifecycle.find_transition(transition, current_user)
|
25
36
|
end
|
@@ -36,16 +47,17 @@ If the transition could not be found, the user does not have permissions for the
|
|
36
47
|
label = t("activerecord.attributes.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}", :default => (label || transition_name.to_s.titleize))
|
37
48
|
title = t("activerecord.attribute_help.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}")
|
38
49
|
html_attributes.update(:title => title) unless title.empty?
|
39
|
-
url = object_url(this, transition_name, :method => html_attributes[:method])
|
40
50
|
|
41
|
-
if (
|
51
|
+
if (!ajax_attributes.empty?) && !has_params
|
42
52
|
ajax_attributes[:message] ||= label
|
43
53
|
ajax_attributes[:method] = html_attributes[:method]
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
%><form lifecycle="&transition_name" merge-attrs="&ajax_attributes" class="button_to" param>
|
55
|
+
<input type="hidden" name="key" value="&this.lifecycle.provided_key" if="&this.lifecycle.provided_key"/>
|
56
|
+
<submit label="&label" merge-attributes="&html_attributes" param="button"/>
|
57
|
+
</form><%
|
58
|
+
else %><%=
|
59
|
+
url = object_url(this, transition_name, :method => html_attributes[:method])
|
60
|
+
button_to(label, url, html_attributes) %><%
|
49
61
|
end
|
50
62
|
%>
|
51
63
|
</def>
|
@@ -57,6 +69,10 @@ For example, you could use this on a `Friendship` card: the person invited to ha
|
|
57
69
|
This tag behaves similarly to repeat: an else tag may be used to handle the case of no buttons:
|
58
70
|
|
59
71
|
<transition-buttons/><else>Sorry, no buttons to press.</else>
|
72
|
+
|
73
|
+
### Attributes
|
74
|
+
|
75
|
+
Ajax attributes are passed through to the individual transition buttons. All other attributes are added to the surrounding div.
|
60
76
|
-->
|
61
77
|
<def tag="transition-buttons">
|
62
78
|
<% ajax_attrs, html_attrs = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS) %>
|
@@ -1,29 +1,16 @@
|
|
1
|
-
<!--
|
2
|
-
record.
|
1
|
+
<!-- This tag is no longer supported in Hobo 1.4.
|
3
2
|
|
4
|
-
|
5
|
-
does ajax.
|
3
|
+
You can replace it with something like:
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
- fields: A hash with new field values pairs to update the resource with. The items in the hash will be converted to
|
14
|
-
HTTP parameters.
|
15
|
-
|
16
|
-
- params: Another hash with additional HTTP parameters to include in the ajax request
|
5
|
+
<form without-cancel update="...">
|
6
|
+
<field-list: replace>
|
7
|
+
<hidden-input:foo value="17"/>
|
8
|
+
<hidden-input:bar value="92"/>
|
9
|
+
</field-list:>
|
10
|
+
</form>
|
17
11
|
|
18
12
|
-->
|
19
|
-
<def tag="update-button" attrs="label, update, fields, params"
|
20
|
-
raise Hobo::Error.new("
|
21
|
-
|
22
|
-
ajax_attributes, html_attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
23
|
-
params = (params || {}).merge(this.class.name.underscore => fields)
|
24
|
-
ajax_attributes.reverse_merge!(:message => label, :params => params, :method => :put)
|
25
|
-
func = ajax_updater(object_url(this), update, ajax_attributes)
|
26
|
-
html_attributes.reverse_merge!(:type =>'button', :onclick => func, :value => label)
|
27
|
-
|
28
|
-
element :input, add_classes(html_attributes, "button update-button update-#{this.class.name.underscore}-button"), nil, true, true %>
|
13
|
+
<def tag="update-button" attrs="label, update, fields, params"><%
|
14
|
+
raise Hobo::Error.new("unsupported")
|
15
|
+
%>
|
29
16
|
</def>
|
data/taglibs/forms/form.dryml
CHANGED
@@ -75,6 +75,8 @@ or on a standard generated page using a default form:
|
|
75
75
|
|
76
76
|
- refocus-form: Refocus the first form-field after submission (only makes sense for ajax forms)
|
77
77
|
|
78
|
+
- before-unload: If set to a message, the message is displayed if the user attempts to leave the page without submitting the form. Note that some browsers ignore the user's message and display their own in an attempt to stop mouse-trappers.
|
79
|
+
|
78
80
|
### Parameters
|
79
81
|
|
80
82
|
The standard form tag does not have any parameters, nor does it have any default content. However, Hobo does autogenerate polymorphic form tags for each of your models into `app/views/taglibs/auto/rapid/forms.dryml`. These forms have the following parameters:
|
@@ -90,11 +92,12 @@ The standard form tag does not have any parameters, nor does it have any default
|
|
90
92
|
- cancel
|
91
93
|
|
92
94
|
-->
|
93
|
-
<def tag="form" polymorphic >
|
95
|
+
<def tag="form" polymorphic attrs="before-unload">
|
94
96
|
<%
|
95
97
|
body, html_attrs, ajax_attrs, form_attrs = form_helper(attributes, parameters)
|
96
98
|
unless body.nil?
|
97
99
|
add_data_rapid!(html_attrs, :form, :ajax_attrs => ajax_attrs) unless ajax_attrs.empty?
|
100
|
+
add_data_rapid!(html_attrs, :before_unload, :message => before_unload) if before_unload
|
98
101
|
%>
|
99
102
|
<%= element("form", html_attrs.merge(form_attrs), body) if body %>
|
100
103
|
<% end %>
|
data/taglibs/html/a.dryml
CHANGED
@@ -83,6 +83,8 @@ The standard AJAX attributes are supported.
|
|
83
83
|
|
84
84
|
* method: "get", "put", "post" or "delete". "get" is the default
|
85
85
|
|
86
|
+
* only-path, protocol, host, subdomain, domain, tld-length, port, anchor, trailing-slash: In smart mode, passed through to Rails' polymorphic_url. For more information, see the Rails documentation for url_for.
|
87
|
+
|
86
88
|
-->
|
87
89
|
<def tag="a" attrs="action, to, params, query-params, href, format, subsite, force"><%=
|
88
90
|
content = parameters.default
|
@@ -107,6 +109,10 @@ The standard AJAX attributes are supported.
|
|
107
109
|
href += "?" + params.map { |n, v| "#{n}=#{v}" }.join('&') if !params.blank?
|
108
110
|
element(:a, attributes.update(:href => href), content)
|
109
111
|
else
|
112
|
+
url_options, attributes = attributes.partition_hash(%w(only_path protocol host subdomain domain tld_length port anchor trailing_slash))
|
113
|
+
url_options[:subsite] = subsite
|
114
|
+
params = url_options.merge(params || {})
|
115
|
+
|
110
116
|
target = to || this
|
111
117
|
|
112
118
|
if target.nil?
|
@@ -116,7 +122,7 @@ The standard AJAX attributes are supported.
|
|
116
122
|
# Link to a new object form
|
117
123
|
new_record = target.respond_to?(:build) ? target.build : target.new
|
118
124
|
new_record.set_creator(current_user)
|
119
|
-
href = object_url(target, "new", params
|
125
|
+
href = object_url(target, "new", params)
|
120
126
|
|
121
127
|
if href && (force || can_create?(new_record))
|
122
128
|
new_class_name = if target.respond_to?(:proxy_association)
|
@@ -138,7 +144,7 @@ The standard AJAX attributes are supported.
|
|
138
144
|
|
139
145
|
content = name if content.blank?
|
140
146
|
|
141
|
-
href = object_url(target, action,
|
147
|
+
href = object_url(target, action, params) unless (action.nil? && target.try.new_record?)
|
142
148
|
if href.nil?
|
143
149
|
# This target is registered with Hobo::Routes as not linkable
|
144
150
|
content
|
@@ -78,7 +78,7 @@ end
|
|
78
78
|
<% skip += ",#{more_skip}" if more_skip -%>
|
79
79
|
<% js_attrs = all_attributes.slice(:minimum, :add_hook, :remove_hook, :hide, :show) %>
|
80
80
|
<% js_attrs[:prefix] = param_name_for_this %>
|
81
|
-
<ul class="input-many #{this_field.dasherize}" data-rapid="#{data_rapid('input-many', js_attrs)}" merge-attrs>
|
81
|
+
<ul class="input-many #{this_field.dasherize}" data-rapid="#{data_rapid('input-many', js_attrs, attributes)}" merge-attrs>
|
82
82
|
<fake-field-context fake-field="-1" context="&template">
|
83
83
|
<li class="input-many-li input-many-template" id="#{underize param_name_for_this}">
|
84
84
|
<div class="input-many-item" param="default">
|
@@ -36,14 +36,14 @@ To use this tag, the model of the items the user is chosing *must* have unique n
|
|
36
36
|
</div>
|
37
37
|
<div class="items">
|
38
38
|
<div class="item" param="item" repeat>
|
39
|
-
<span><%= h this.to_s %></span>
|
39
|
+
<span param='item-label'><%= h this.to_s %></span>
|
40
40
|
<input type="hidden" name="#{name}[]" value="@#{h this.id}" disabled="&disabled"
|
41
41
|
param="hidden"/>
|
42
42
|
<input type="button" class="remove-item" value="#{remove_label}" disabled="&disabled"
|
43
43
|
param="remove-button"/>
|
44
44
|
</div>
|
45
45
|
</div>
|
46
|
-
<select merge-attrs="&{:disabled => disabled}">
|
46
|
+
<select merge-attrs="&{:disabled => disabled}" param>
|
47
47
|
<option value=""><prompt/></option>
|
48
48
|
<repeat with="&options">
|
49
49
|
<if test="&this.in?(values)">
|
@@ -8,18 +8,22 @@ The specified sort order may be maintained even without `acts_as_list`. The ite
|
|
8
8
|
|
9
9
|
### Attributes
|
10
10
|
|
11
|
-
- `id`: Due to a limitation in script.aculo.us, an id is required. If you do not supply one, one will be generated.
|
12
11
|
- `position-column`: The position column may be specified via `acts_as_list`, via a `position_column` method on your model or via this attribute.
|
13
|
-
- others: all other attributes are passed through to `<input-many
|
12
|
+
- others: all other attributes are passed through to [jQuery UI's Sortable](http://jqueryui.com/demos/sortable/) or to `<input-many>`, as appropriate.
|
14
13
|
|
14
|
+
The jQuery UI option `update` is used internally to update the order. If you modify this option, your function may call `$(this).hjq_sortable_input_many('update')` to retain this functionality.
|
15
15
|
-->
|
16
16
|
|
17
|
-
<def tag="sortable-input-many" attrs="
|
18
|
-
|
19
|
-
|
17
|
+
<def tag="sortable-input-many" attrs="position-column, template">
|
18
|
+
<%
|
19
|
+
options, attributes = attributes.partition_hash(['disabled', 'appendTo', 'axis', 'cancel', 'connectWith', 'containment', 'cursor', 'cursorAt', 'delay', 'distance', 'dropOnEmpty', 'forceHelperSize', 'forcePlaceholderSize', 'grid', 'handle', 'helper', 'items', 'opacity', 'placeholder', 'revert', 'scroll', 'scrollSensitivity', 'scrollSpeed', 'tolerance', 'zIndex'])
|
20
|
+
events, attributes = attributes.partition_hash(['create', 'start', 'sort', 'change', 'beforeStop', 'stop', 'update', 'receive', 'remove', 'over', 'out', 'activate', 'deactivate'])
|
21
|
+
|
22
|
+
data_rapid_options = { :options => options, :events => events }
|
23
|
+
%>
|
20
24
|
<% template ||= this.try.new_candidate || this.member_class.new %>
|
21
25
|
<% position_column ||= template.try.position_column -%>
|
22
|
-
<input-many merge
|
26
|
+
<input-many merge class="sortable-input-many" template="&template" more-skip="&position_column" data-rapid="&data_rapid('sortable-input-many', data_rapid_options)">
|
23
27
|
<default: replace>
|
24
28
|
<div class="ordering-handle" param="handle" if="&can_edit?">↑<br/>↓</div>
|
25
29
|
<if test="&position_column">
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<!-- Call with the context set to a record. Repeats the content of the tag with `this` and `this_field` set to the value and name of each of the record's fields in turn. E.g. this is useful for generating a form containing each of the fields. Tags like `<field-list>` and `<table>` forward their attributes to this tag and also have the features described here. For example, the `fields` attribute to `<field-list>` supports the same options as described here.
|
2
2
|
|
3
|
-
This tag is in need of a review - it's a bit funky.
|
4
|
-
|
5
3
|
### Attributes
|
6
4
|
|
7
5
|
- `fields` - set to one of:
|
@@ -17,82 +15,32 @@ This tag is in need of a review - it's a bit funky.
|
|
17
15
|
|
18
16
|
-->
|
19
17
|
<def tag="with-fields" attrs="fields, associations, skip, skip-associations, include-timestamps, force-all"><%
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
elsif skip_associations
|
33
|
-
columns
|
34
|
-
else
|
35
|
-
assocs = klass.reflections.values.map &its.name.to_s
|
36
|
-
columns + assocs
|
37
|
-
end
|
38
|
-
else
|
39
|
-
comma_split(fields.gsub('-', '_'))
|
40
|
-
end
|
41
|
-
field_names -= comma_split(skip) if skip
|
42
|
-
field_names = field_names.select {|f| can_view?(this, f)} unless force_all
|
43
|
-
field_names.each do |field|
|
44
|
-
%><set-scoped field-name="&field"><%
|
45
|
-
if field == "this"
|
46
|
-
%><do param="default"/><%
|
47
|
-
else
|
48
|
-
%><with field="&field"><do param="default"/></with><%
|
49
|
-
end
|
50
|
-
%></set-scoped><%
|
51
|
-
end
|
52
|
-
%></def>
|
18
|
+
field_names = with_fields_helper(all_attributes)
|
19
|
+
field_names = field_names.select {|f| can_view?(this, f)} unless force_all
|
20
|
+
field_names.each do |field|
|
21
|
+
%><set-scoped field-name="&field"><%
|
22
|
+
if field == "this"
|
23
|
+
%><do param="default"/><%
|
24
|
+
else
|
25
|
+
%><with field="&field"><do param="default"/></with><%
|
26
|
+
end
|
27
|
+
%></set-scoped><%
|
28
|
+
end
|
29
|
+
-%></def>
|
53
30
|
|
54
31
|
<!-- Call with the context set to a model class. Repeats the content of the tag with `this` set name of each of the model's fields in turn. E.g. this tag is used when generating the heading row in a `<table fields='...'/>`.
|
55
32
|
|
56
|
-
This tag is in need of a review - it's a bit funky.
|
57
|
-
|
58
33
|
### Attributes
|
59
34
|
|
60
|
-
|
61
|
-
- A model class - equivalent to listing all of the regular 'content columns' of that model
|
62
|
-
- '`*`' - equivalent to listing all of the regular 'content columns' of the current record
|
63
|
-
- A comma separated list of field names.
|
64
|
-
Defaults to '`*`'
|
65
|
-
- `skip` - comma separated list of field names to omit.
|
66
|
-
- `skip-associations` - set to `has-many` to omit all `has_many` associations.
|
67
|
-
- `include-timestamps` - whether or not to include the standard ActiveRecord timestamp fields such as `created_at` and `updated_at`. Defaults to false.
|
68
|
-
|
35
|
+
Supports the same attributes as `<with-fields>`
|
69
36
|
-->
|
70
|
-
<def tag="with-field-names"
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
columns
|
81
|
-
else
|
82
|
-
assocs = klass.reflections.values.map &its.name.to_s
|
83
|
-
columns + assocs
|
84
|
-
end
|
85
|
-
else
|
86
|
-
comma_split(fields)
|
87
|
-
end
|
88
|
-
|
89
|
-
field_names -= comma_split(skip) if skip
|
90
|
-
scope.new_scope :field_name => nil, :field_path => nil do
|
91
|
-
field_names.map do |n|
|
92
|
-
scope.field_name = n == "this" ? (this.member_class.try.name || 'this') : n.to_s.gsub("." , "_")
|
93
|
-
scope.field_path = n
|
94
|
-
parameters.default
|
95
|
-
end.safe_join
|
96
|
-
end
|
97
|
-
%>
|
98
|
-
</def>
|
37
|
+
<def tag="with-field-names"><%=
|
38
|
+
field_names = with_fields_helper(all_attributes)
|
39
|
+
scope.new_scope :field_name => nil, :field_path => nil do
|
40
|
+
field_names.map do |n|
|
41
|
+
scope.field_name = n == "this" ? (this.member_class.try.name || 'this') : n.to_s.gsub("." , "_")
|
42
|
+
scope.field_path = n
|
43
|
+
parameters.default
|
44
|
+
end.safe_join
|
45
|
+
end
|
46
|
+
%></def>
|
@@ -97,7 +97,7 @@ or
|
|
97
97
|
end
|
98
98
|
attributes['message'] ||= t("FIXME", :default => "Loading...") if HoboRapidHelper::AJAX_ATTRS.any?{|a| attributes.has_key?(a)}
|
99
99
|
%>
|
100
|
-
<form action="&request.path" method="get" class="filter-menu" merge-attrs="&attributes" data-rapid="&data_rapid('filter-menu')">
|
100
|
+
<form action="&request.path" method="get" class="filter-menu" merge-attrs="&attributes" data-rapid="&data_rapid('filter-menu')" with="&nil">
|
101
101
|
<div>
|
102
102
|
<% opt = options.first.kind_of?(Array) ? options.*.last : options
|
103
103
|
selected = opt.detect {|o| o.to_s==params[param_name.gsub('-', '_')] } %>
|
@@ -1,8 +1,10 @@
|
|
1
1
|
<!-- Provides an ajax-powered *find-as-you-type* live search field which is hooked up to Hobo's site-side search feature.
|
2
2
|
|
3
|
-
|
3
|
+
You can provide a completely custom set of results by changing the action parameter to your own controller action.
|
4
|
+
|
5
|
+
On the other hand, if you wish to slightly tweak the list of results you can adjust the search columns on each model through [set_search_columns](http://cookbook.hobocentral.net/manual/model#set_search_columns), To stop querying a model, simply set it's search_columns to an empty list.
|
4
6
|
|
5
|
-
|
7
|
+
Customizing the display of results can be done through customizing the "box" param and the `search-results` tag. The current definition of `<search-results>` expects results to be returned in `@search_results`.
|
6
8
|
|
7
9
|
### attributes
|
8
10
|
|
@@ -23,7 +25,7 @@ All other attributes are merged into the form, so standard form attributes are s
|
|
23
25
|
</form>
|
24
26
|
<% panel_tag ||= 'dialog-box' %>
|
25
27
|
<% title = t("hobo.live_search.results_label", :default => "Search Results") %>
|
26
|
-
<call-tag tag="&panel_tag" position="
|
28
|
+
<call-tag tag="&panel_tag" position="center" width="&600" height="&800" id="search-results-box" with="&nil" title="&title" param="box">
|
27
29
|
<do part="search-results-part">
|
28
30
|
<search-results/>
|
29
31
|
</do>
|
@@ -34,7 +36,9 @@ All other attributes are merged into the form, so standard form attributes are s
|
|
34
36
|
<!-- redefining or extending this tag will allow you to customize the display of search results -->
|
35
37
|
<def tag="search-results">
|
36
38
|
<section with="&@search_results || []" data-rapid='{"search-results": {}}'>
|
37
|
-
<collection
|
39
|
+
<collection param>
|
40
|
+
<search-card/>
|
41
|
+
</collection>
|
38
42
|
<else><t key="hobo.live_search.no_results">Your search returned no matches.</t></else>
|
39
43
|
</section>
|
40
44
|
</def>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<!-- Renders a comma separated list of links (`<
|
2
|
-
<def tag="links-for-collection"><%= this.empty? ? "(none)" : context_map {
|
1
|
+
<!-- Renders a comma separated list of links (`<view>`), or "(none)" if the list is empty -->
|
2
|
+
<def tag="links-for-collection"><%= this.empty? ? "(none)" : context_map { view }.safe_join(", ") %></def>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hobo_rapid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hobo
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 2.0.0.pre1
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 2.0.0.pre1
|
30
30
|
description: The RAPID tag library for Hobo
|
31
31
|
email: tom@tomlocke.com
|
32
32
|
executables: []
|
@@ -96,7 +96,6 @@ files:
|
|
96
96
|
- taglibs/inputs/input_for_enum_string.dryml
|
97
97
|
- taglibs/inputs/input_many.dryml
|
98
98
|
- taglibs/inputs/inputs.dryml
|
99
|
-
- taglibs/inputs/name_one.dryml
|
100
99
|
- taglibs/inputs/or_cancel.dryml
|
101
100
|
- taglibs/inputs/select_input.dryml
|
102
101
|
- taglibs/inputs/select_many.dryml
|
@@ -1,74 +0,0 @@
|
|
1
|
-
<!-- An `<input type="text">` with auto-completion. Allows the user to chose the target of a `belongs_to` association by name.
|
2
|
-
|
3
|
-
This tag relies on an autocompleter being defined in a controller. A simple example:
|
4
|
-
|
5
|
-
<form with="&ProjectMembership.new">
|
6
|
-
<name-one:user>
|
7
|
-
</form>
|
8
|
-
|
9
|
-
class ProjectMembership < ActiveRecord::Base
|
10
|
-
hobo_model
|
11
|
-
belongs_to :user
|
12
|
-
end
|
13
|
-
|
14
|
-
class User < ActiveRecord::Base
|
15
|
-
hobo_user_model
|
16
|
-
has_many :project_memberships, :accessible => true, :dependent => :destroy
|
17
|
-
end
|
18
|
-
|
19
|
-
class UsersController < ApplicationController
|
20
|
-
autocomplete
|
21
|
-
end
|
22
|
-
|
23
|
-
The route used by the autocompleter looks something like `/users/complete_name`. The first part of this route is specified by the `complete-target` attribute, and the second part is specified by the `completer` attribute.
|
24
|
-
|
25
|
-
`complete-target` specifies the controller for the route. It can be specified by either supplying a model class or a model. If a model is supplied, the id of the model is passed as a parameter to the controller. (`?id=7`, for example) The default for this attribute is the class of the context. In other words, the class that contains the `has_many / has_one`, not the class with the `belongs_to`.
|
26
|
-
|
27
|
-
`completer` specifies the action for the route. `name-one` prepends `complete_` to the value given here. This should be exactly the same as the first parameter to `autocomplete` in your controller. As an example: `autocomplete :email_address` would correspond to `completer="email_address"`. The default for this attribute is the name field for the model being searched, which is usually `name`, but not always.
|
28
|
-
|
29
|
-
The query string is passed to the controller in the `query` parameter. (`?query=hello` for example).
|
30
|
-
|
31
|
-
For more information on how to customize the controller, see the [controller manual](http://cookbook.hobocentral.net/manual/controllers#autocompleters)
|
32
|
-
|
33
|
-
Here's a more complex example. This used to be a part of [agility](http://cookbook.hobocentral.net/tutorials/agility) until it was simplified.
|
34
|
-
|
35
|
-
class ProjectsController < ApplicationController
|
36
|
-
autocomplete :new_member_name do
|
37
|
-
project = find_instance
|
38
|
-
hobo_completions :name, User.without_project(project).is_not(project.owner)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
Note that this was added to the projects controller, rather than the users controller as in the first example. You can read this as: create an auto-complete action called `new_member_name` that finds users that are not already members of the project, and not the owner of the project, and completes the :name field.
|
43
|
-
|
44
|
-
<name-one:user complete-target="&@project" completer="new_member_name"/>
|
45
|
-
|
46
|
-
We're using an object as the complete-target rather than a class. This allows the `find_instance` in our controller action to function.
|
47
|
-
|
48
|
-
There's another example of `<name-one>` use in the [recipes](http://cookbook.hobocentral.net/recipes/36-using-a-name-one-one-a).
|
49
|
-
|
50
|
-
### Attributes:
|
51
|
-
|
52
|
-
- `complete-target`, `completer`: see above
|
53
|
-
- `min-chars`: The minimum number of characters that must be entered in the input field before an Ajax request is made.
|
54
|
-
- `nil-value`: If there is no current value, this text will appear greyed out inside the control, and will disappear on focus.
|
55
|
-
|
56
|
-
### Note:
|
57
|
-
|
58
|
-
If you wish to set `min-chars` to 0, you will require this [patch to controls.js](http://github.com/bryanlarsen/scriptaculous/commit/3915b7b). 'controls.js' was added to your project via the rails generator, not via Hobo.
|
59
|
-
|
60
|
-
-->
|
61
|
-
<def tag="name-one" attrs="complete-target, completer, min-chars, nil-value"><%
|
62
|
-
complete_target ||= this_field_reflection.klass
|
63
|
-
completer ||= (complete_target.is_a?(Class) ? complete_target : complete_target.class).name_attribute
|
64
|
-
min_chars ||= 1
|
65
|
-
value = name(:no_wrapper => true, :if_present => true)
|
66
|
-
-%>
|
67
|
-
<wrap tag="span" class="field-with-errors" when="&!this_parent.nil? && !this_parent.errors[this_field].empty?">
|
68
|
-
<input type="text" name="#{param_name_for_this}"
|
69
|
-
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==''}"
|
70
|
-
value="#{value=='' ? nil_value : value}"
|
71
|
-
merge-attrs/>
|
72
|
-
<div class="completions-popup" style="display:none"></div>
|
73
|
-
</wrap>
|
74
|
-
</def>
|