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 CHANGED
@@ -1 +1 @@
1
- 1.4.0.pre8
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
- [:params, :errors_ok,
14
- :reset_form, :refocus_form ]
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 an ajax create button that will send a RESTful "POST" to the server to create a new resource.
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
- - model: The class to instantiate, pass either the class name or the class object.
5
+ All standard ajax attributes are supported, plus:
8
6
 
9
- -->
10
- <def tag="create-button" attrs="model, update, label, fields, message"><%=
11
- raise Hobo::Error.new("no update specified") unless update
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
- raise Hobo::Error.new("invalid context for <create-button>")
31
+ this
22
32
  end
23
33
  new = class_or_assoc.new(fields)
24
34
  new.set_creator(current_user)
25
- if can_create?(new)
26
- label ||= ht("#{new.class.to_s.underscore}.actions.new", :default=>"New #{new.class.model_name.human}")
27
- class_name = new.class.name.underscore
28
- params ||= params || {}
29
- params = params.merge(class_name => fields) unless fields.blank?
30
-
31
- ajax_attributes, html_attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
32
-
33
- ajax_attributes.reverse_merge!(:message => message, :params => params)
34
- func = ajax_updater(object_url(new.class, :method => :post), update, ajax_attributes)
35
- html_attributes.reverse_merge!(:type =>'button', :onclick => func, :value => label)
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 documention for Rapid Forms).
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
- <!-- Provides either an ajax or non-ajax button to invoke a "remote method" or "web method" declared in the controller.
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
- The URL that the call is POSTed to is the `object_url` of `this`, plus the method name
3
+ You can replace remote-method-button with something like:
7
4
 
8
- `<remote-method-button>` supports all of the standard ajax attributes (see the main taglib documention for Rapid
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, update, label, confirm, url"><%=
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 update || !ajax_attributes.empty?
26
+ if !ajax_attributes.empty?
27
27
  ajax_attributes[:message] ||= label
28
- func = ajax_updater(url, update, ajax_attributes.merge(:confirm => confirm))
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-button to invoke a lifecycle transition either as a page-reload or as an ajax call.
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
- Transitions with parameters are implemented using a form. HTML does not allow forms to be nested, so a transitions with parameters should not be placed inside of a form.
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, update, label"><%=
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 (update || !ajax_attributes.empty?) && !has_params
51
+ if (!ajax_attributes.empty?) && !has_params
42
52
  ajax_attributes[:message] ||= label
43
53
  ajax_attributes[:method] = html_attributes[:method]
44
- func = ajax_updater(url, update, ajax_attributes)
45
- html_attributes.update(:onclick => "var e = this; " + func, :type =>'button', :value => label)
46
- element(:input, html_attributes, nil, true, true)
47
- else
48
- button_to(label, url, html_attributes)
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
- <!-- Provides an ajax button to send a RESTful update or "PUT" to the server. i.e. to udate one or more fields of a
2
- record.
1
+ <!-- This tag is no longer supported in Hobo 1.4.
3
2
 
4
- Note that unlike simliar tags, `<update-button>` does not support both ajax and non-ajax modes at this time. It only
5
- does ajax.
3
+ You can replace it with something like:
6
4
 
7
- `<update-button>` supports all of the standard ajax attributes (see the main taglib documention for Rapid Forms).
8
-
9
- ### Attributes
10
-
11
- - label: The label on the button.
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("no update specified") unless update
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>
@@ -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._?.merge(:subsite => subsite))
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, (params || {}).merge(:subsite => subsite)) unless (action.nil? && target.try.new_record?)
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="id, position-column, template">
18
- <% this_id = this_parent.id || rand(100000) -%>
19
- <% id ||= "sortable-input-many-#{this_parent.class.name.underscore.dasherize}-#{this_id}-#{this_field_reflection.name}" -%>
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 id="&id" class="sortable-input-many" template="&template" more-skip="&position_column">
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?">&uarr;<br/>&darr;</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
- fields.nil? || associations.nil? or raise ArgumentError, "with-fields -- specify either fields or associations but not both"
21
-
22
- field_names = if associations == "has_many"
23
- this.class.reflections.values.select { |refl| refl.macro == :has_many }.map { |refl| refl.name.to_s }
24
-
25
- elsif fields.nil? || fields == "*" || fields.is_a?(Class)
26
- klass = fields.is_a?(Class) ? fields : this.class
27
- columns = standard_fields(klass, include_timestamps)
28
-
29
- if skip_associations == "has_many"
30
- assocs = this.class.reflections.values.reject {|r| r.macro == :has_many }.map &its.name.to_s
31
- columns + assocs
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
- - `fields` - set to one of:
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" attrs="fields, skip, skip-associations, include-timestamps"><%=
71
- field_names = if fields.nil? || fields == "*" || fields.is_a?(Class)
72
- klass = fields.is_a?(Class) ? fields : this.member_class
73
- columns = klass.content_columns.*.name
74
- columns -= %w{created_at updated_at created_on updated_on deleted_at} unless include_timestamps
75
-
76
- if skip_associations == "has_many"
77
- assocs = this.reflections.values.reject {|r| r.macro == :has_many }.map &its.name.to_s
78
- columns + assocs
79
- elsif skip_associations
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
- 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`.
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
- TODO: currently you have to press 'return' to initiate the search. This should be easy to fix in hjq-live-search.js - the hard part will probably be in doing it in a way that works in all possible browsers.
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="&{:my => 'right top'}" width="&600" height="&800" id="search-results-box" with="&nil" title="&title" param="box">
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 (`<a>`), or "(none)" if the list is empty -->
2
- <def tag="links-for-collection"><%= this.empty? ? "(none)" : context_map { a }.safe_join(", ") %></def>
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: 1.4.0.pre8
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-08-01 00:00:00.000000000 Z
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: 1.4.0.pre8
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: 1.4.0.pre8
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>