hobo_rapid 1.4.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +5 -0
- data/VERSION +1 -0
- data/app/controllers/dev_controller.rb +25 -0
- data/app/helpers/hobo_rapid_helper.rb +197 -0
- data/hobo_rapid.gemspec +26 -0
- data/lib/hobo_rapid/railtie.rb +6 -0
- data/lib/hobo_rapid.rb +13 -0
- data/taglibs/buttons/buttons.dryml +1 -0
- data/taglibs/buttons/create_button.dryml +40 -0
- data/taglibs/buttons/delete-button.dryml +75 -0
- data/taglibs/buttons/remote_method_button.dryml +34 -0
- data/taglibs/buttons/transition_button.dryml +71 -0
- data/taglibs/buttons/transition_link.dryml +22 -0
- data/taglibs/buttons/update_button.dryml +29 -0
- data/taglibs/cache/cache.dryml +1 -0
- data/taglibs/cache/nested_cache.dryml +332 -0
- data/taglibs/cards/card.dryml +7 -0
- data/taglibs/cards/cards.dryml +1 -0
- data/taglibs/cards/search_card.dryml +4 -0
- data/taglibs/editors/click_editor.dryml +60 -0
- data/taglibs/editors/editors.dryml +27 -0
- data/taglibs/editors/live_editor.dryml +37 -0
- data/taglibs/forms/error_messages.dryml +21 -0
- data/taglibs/forms/form.dryml +101 -0
- data/taglibs/forms/formlet.dryml +48 -0
- data/taglibs/forms/forms.dryml +5 -0
- data/taglibs/forms/submit.dryml +14 -0
- data/taglibs/hobo_rapid.dryml +14 -0
- data/taglibs/html/a.dryml +156 -0
- data/taglibs/html/aside.dryml +5 -0
- data/taglibs/html/doctype.dryml +39 -0
- data/taglibs/html/empty_tag.dryml +23 -0
- data/taglibs/html/footer.dryml +5 -0
- data/taglibs/html/header.dryml +5 -0
- data/taglibs/html/html.dryml +18 -0
- data/taglibs/html/if_ie.dryml +11 -0
- data/taglibs/html/image.dryml +11 -0
- data/taglibs/html/javascript.dryml +12 -0
- data/taglibs/html/section.dryml +12 -0
- data/taglibs/html/section_group.dryml +11 -0
- data/taglibs/html/stylesheet.dryml +5 -0
- data/taglibs/html/table.dryml +174 -0
- data/taglibs/i18n/ht.dryml +48 -0
- data/taglibs/i18n/human_attribute_name +18 -0
- data/taglibs/i18n/human_collection_name.dryml +69 -0
- data/taglibs/i18n/i18n.dryml +1 -0
- data/taglibs/i18n/model_name_human.dryml +16 -0
- data/taglibs/i18n/t.dryml +12 -0
- data/taglibs/inputs/after_submit.dryml +32 -0
- data/taglibs/inputs/check_many.dryml +25 -0
- data/taglibs/inputs/collection_input.dryml +10 -0
- data/taglibs/inputs/hidden_field.dryml +48 -0
- data/taglibs/inputs/hot_input.dryml +50 -0
- data/taglibs/inputs/input.dryml +76 -0
- data/taglibs/inputs/input_all.dryml +14 -0
- data/taglibs/inputs/input_for.dryml +38 -0
- data/taglibs/inputs/input_for_date.dryml +86 -0
- data/taglibs/inputs/input_for_enum_string.dryml +26 -0
- data/taglibs/inputs/input_many.dryml +131 -0
- data/taglibs/inputs/inputs.dryml +1 -0
- data/taglibs/inputs/name_one.dryml +74 -0
- data/taglibs/inputs/or_cancel.dryml +8 -0
- data/taglibs/inputs/select_input.dryml +13 -0
- data/taglibs/inputs/select_many.dryml +58 -0
- data/taglibs/inputs/select_menu.dryml +23 -0
- data/taglibs/inputs/select_one.dryml +46 -0
- data/taglibs/inputs/sortable_input_many.dryml +31 -0
- data/taglibs/inputs/sti_type_input.dryml +6 -0
- data/taglibs/lists/collection.dryml +26 -0
- data/taglibs/lists/empty_collection_message.dryml +13 -0
- data/taglibs/lists/feckless_fieldset.dryml +94 -0
- data/taglibs/lists/field_list.dryml +21 -0
- data/taglibs/lists/field_list_v1.dryml +64 -0
- data/taglibs/lists/labelled_item_list.dryml +11 -0
- data/taglibs/lists/lists.dryml +2 -0
- data/taglibs/lists/with_fields.dryml +98 -0
- data/taglibs/pages/account.dryml +30 -0
- data/taglibs/pages/account_disabled.dryml +19 -0
- data/taglibs/pages/flash_message.dryml +23 -0
- data/taglibs/pages/forgot_password.dryml +62 -0
- data/taglibs/pages/login.dryml +57 -0
- data/taglibs/pages/not_found_page.dryml +18 -0
- data/taglibs/pages/page_nav.dryml +17 -0
- data/taglibs/pages/pages.dryml +12 -0
- data/taglibs/pages/permission_denied_page.dryml +24 -0
- data/taglibs/plus/collection_preview.dryml +23 -0
- data/taglibs/plus/filter_menu.dryml +103 -0
- data/taglibs/plus/gravatar.dryml +12 -0
- data/taglibs/plus/live_search.dryml +40 -0
- data/taglibs/plus/plus.dryml +1 -0
- data/taglibs/plus/sortable_collection.dryml +36 -0
- data/taglibs/plus/table_plus.dryml +63 -0
- data/taglibs/views/a_or_an.dryml +10 -0
- data/taglibs/views/collection_name.dryml +28 -0
- data/taglibs/views/comma_list.dryml +2 -0
- data/taglibs/views/count.dryml +99 -0
- data/taglibs/views/links_for_collection.dryml +2 -0
- data/taglibs/views/name.dryml +30 -0
- data/taglibs/views/nil_view.dryml +10 -0
- data/taglibs/views/record_flags.dryml +5 -0
- data/taglibs/views/type_name.dryml +24 -0
- data/taglibs/views/view.dryml +79 -0
- data/taglibs/views/view_for.dryml +42 -0
- data/taglibs/views/views.dryml +1 -0
- data/taglibs/views/you.dryml +150 -0
- data/vendor/assets/javascripts/hobo_rapid.js +1 -0
- data/vendor/assets/stylesheets/feckless-fieldset.css +40 -0
- data/vendor/assets/stylesheets/hobo-rapid.css +94 -0
- data/vendor/assets/stylesheets/hobo_rapid.css +1 -0
- metadata +174 -0
data/README.markdown
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.4.0.pre2
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class DevController < ActionController::Base
|
2
|
+
|
3
|
+
hobo_controller
|
4
|
+
|
5
|
+
before_filter :developer_modes_only
|
6
|
+
|
7
|
+
def set_current_user
|
8
|
+
model = params[:model] || Hobo::Model::UserBase.default_user_model
|
9
|
+
self.current_user = if params[:login]
|
10
|
+
model.where(model.login_attribute => params[:login]).first
|
11
|
+
else
|
12
|
+
model.find(params[:id])
|
13
|
+
end
|
14
|
+
redirect_to(request.env["HTTP_REFERER"] ? :back : home_page)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def developer_modes_only
|
20
|
+
# Belt and braces. In addition to this check, the routes only get
|
21
|
+
# defined when developer_features is true
|
22
|
+
render :text => "Permission Denied", :status => 403 unless Rails.application.config.hobo.developer_features
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module HoboRapidHelper
|
2
|
+
AJAX_CALLBACKS = [ :success, :failure, :complete, :before ]
|
3
|
+
|
4
|
+
AJAX_UPDATE_ATTRS = [ :update, :updates, :ajax ]
|
5
|
+
|
6
|
+
AJAX_EFFECT_ATTRS = [ :hide, :show ]
|
7
|
+
|
8
|
+
AJAX_SPINNER_ATTRS = [:spinner_next_to, :spinner_options, :spinner_at, :no_spinner, :message]
|
9
|
+
|
10
|
+
AJAX_PUSHSTATE_ATTRS = [:push_state, :new_title]
|
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 ]
|
15
|
+
|
16
|
+
def app_name(add_subsite=true)
|
17
|
+
an = Rails.application.config.hobo.app_name
|
18
|
+
if add_subsite && subsite
|
19
|
+
subsite_name = t 'hobo.admin.subsite_name', :default => subsite.titleize
|
20
|
+
an = an + " - #{subsite_name}"
|
21
|
+
end
|
22
|
+
an
|
23
|
+
end
|
24
|
+
|
25
|
+
def comma_split(x)
|
26
|
+
case x
|
27
|
+
when nil
|
28
|
+
[]
|
29
|
+
when String
|
30
|
+
x.strip.split(/\s*,\s*/)
|
31
|
+
else
|
32
|
+
x.compact.map{|e| comma_split(e)}.flatten
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def a_or_an(word)
|
37
|
+
if word =~ /^[aeiouh]/
|
38
|
+
"an #{word}"
|
39
|
+
else
|
40
|
+
"a #{word}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def no_break(s)
|
46
|
+
s = new_context { yield } if block_given?
|
47
|
+
s.gsub(' ', ' ')
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns the number of items in the collection. See LH #889
|
51
|
+
def collection_count
|
52
|
+
this.try.to_int || this.try.total_entries || (this.try.loaded? && this.try.length) || this.try.count || this.try.length
|
53
|
+
end
|
54
|
+
|
55
|
+
def through_collection_names(object=this)
|
56
|
+
object.class.reflections.values.select do |refl|
|
57
|
+
refl.macro == :has_many && refl.options[:through]
|
58
|
+
end.map {|x| x.options[:through]}
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def non_through_collections(object=this)
|
63
|
+
names = object.class.reflections.values.select do |refl|
|
64
|
+
refl.macro == :has_many
|
65
|
+
end.*.name
|
66
|
+
|
67
|
+
names - through_collection_names
|
68
|
+
end
|
69
|
+
|
70
|
+
def standard_fields(model, include_timestamps=false)
|
71
|
+
fields = model.attr_order.*.to_s & model.content_columns.*.name
|
72
|
+
fields -= %w{created_at updated_at created_on updated_on deleted_at} unless include_timestamps
|
73
|
+
fields.reject! { |f| model.never_show? f }
|
74
|
+
fields
|
75
|
+
end
|
76
|
+
|
77
|
+
def current_time
|
78
|
+
Time.zone ? Time.zone.now : Time.now
|
79
|
+
end
|
80
|
+
|
81
|
+
# provides the meat for hidden-fields for-query-string and anybody
|
82
|
+
# else who wants a list of relevant parameters. options: :skip, :only
|
83
|
+
def query_parameters_filtered(options = {})
|
84
|
+
query_params = (request.query_parameters | request.request_parameters)
|
85
|
+
if options[:only]
|
86
|
+
query_params = query_params & options[:only]
|
87
|
+
else
|
88
|
+
query_params = query_params - [:render, :render_options, :"_", :page_path, :authenticity_token]
|
89
|
+
if form_field_path
|
90
|
+
query_params = query_params - [form_field_path[0]]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
query_params = query_params - options[:skip] if options[:skip]
|
94
|
+
query_params
|
95
|
+
end
|
96
|
+
|
97
|
+
# this function provides the meat for the form and formlet tags. It
|
98
|
+
# returns a tuple of:
|
99
|
+
# body: html body
|
100
|
+
# html_attrs: class, id, etc.
|
101
|
+
# ajax_attrs: update, spinner-next-to, etc
|
102
|
+
# form_attrs: action, method, enctype
|
103
|
+
def form_helper(attributes, parameters)
|
104
|
+
attrs, other_attrs = attributes.partition_hash([:hidden_fields, :action, :method, :web_method, :lifecycle, :owner, :multipart])
|
105
|
+
ajax_attrs, html_attrs = other_attrs.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
106
|
+
form_attrs = {}
|
107
|
+
|
108
|
+
if html_attrs[:confirm]
|
109
|
+
if ajax_attrs.blank?
|
110
|
+
html_attrs["data-confirm"] = html_attrs.delete(:confirm) # rely on rails_ujs
|
111
|
+
else
|
112
|
+
ajax_attrs[:confirm] = html_attrs.delete(:confirm)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
form_attrs[:enctype] = html_attrs[:enctype] if html_attrs[:enctype]
|
117
|
+
form_attrs[:enctype] ||= "multipart/form-data" if attrs[:multipart]
|
118
|
+
|
119
|
+
new_record = self.this.try.new_record?
|
120
|
+
|
121
|
+
method = if attrs[:method].nil?
|
122
|
+
(attrs[:action] || attrs[:web_method] || new_record) ? "post" : "put"
|
123
|
+
else
|
124
|
+
attrs[:method].downcase
|
125
|
+
end
|
126
|
+
|
127
|
+
form_attrs[:action] = attrs[:action] ||
|
128
|
+
begin
|
129
|
+
target = if attrs[:owner]
|
130
|
+
collection_name = this.class.reverse_reflection(attrs[:owner]).name
|
131
|
+
this.send(attrs[:owner]).send(collection_name)
|
132
|
+
else
|
133
|
+
this
|
134
|
+
end
|
135
|
+
attrs[:action] = attrs[:web_method] || attrs[:lifecycle]
|
136
|
+
object_url(target, attrs[:action], :method => method)
|
137
|
+
end
|
138
|
+
|
139
|
+
if attrs[:action].nil? && (form_attrs[:action].nil? ||
|
140
|
+
(attrs[:lifecycle].nil? && new_record && !this.creatable_by?(current_user)) ||
|
141
|
+
(attrs[:lifecycle].nil? && !new_record && !can_edit?))
|
142
|
+
Dryml.last_if = false
|
143
|
+
logger.info("unable to render form")
|
144
|
+
return nil
|
145
|
+
else
|
146
|
+
if method == "put" || method == "delete"
|
147
|
+
# browsers don't support put -- use post and add the Rails _method hack
|
148
|
+
http_method_hidden = hidden_field_tag("_method", method.upcase)
|
149
|
+
form_attrs[:method] = "post"
|
150
|
+
else
|
151
|
+
http_method_hidden = ""
|
152
|
+
form_attrs[:method] = method
|
153
|
+
end
|
154
|
+
|
155
|
+
hiddens = ""
|
156
|
+
body = with_form_context do
|
157
|
+
# It is important to evaluate parameters.default first, in order to populate scope.form_field_names
|
158
|
+
b = parameters.default
|
159
|
+
hiddens = self.hidden_fields(:fields => attrs[:hidden_fields]) if new_record
|
160
|
+
b
|
161
|
+
end
|
162
|
+
|
163
|
+
auth_token = if method.nil? || method == 'get' || !protect_against_forgery?
|
164
|
+
''
|
165
|
+
else
|
166
|
+
element(:input, {:type => "hidden",
|
167
|
+
:name => request_forgery_protection_token.to_s,
|
168
|
+
:value => form_authenticity_token}, nil, true, true)
|
169
|
+
end
|
170
|
+
|
171
|
+
unless method == "get"
|
172
|
+
page_path = if (request.post? || request.put? || request.delete?) && params[:page_path]
|
173
|
+
params[:page_path]
|
174
|
+
else
|
175
|
+
request.fullpath
|
176
|
+
end
|
177
|
+
page_path_hidden = hidden_field_tag("page_path", page_path)
|
178
|
+
end
|
179
|
+
|
180
|
+
hiddens_div = element(:div, {:class => "hidden-fields"}, [http_method_hidden, page_path_hidden, auth_token, hiddens].safe_join)
|
181
|
+
|
182
|
+
body = [hiddens_div, body].safe_join
|
183
|
+
|
184
|
+
if attrs[:action].nil? # don't add automatic css classes if the action was specified
|
185
|
+
if attrs[:web_method]
|
186
|
+
add_classes!(html_attrs, "#{type_id.dasherize}-#{web_method}-form")
|
187
|
+
else
|
188
|
+
add_classes!(html_attrs, "#{'new ' if new_record}#{type_id.dasherize}")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
Dryml.last_if = true
|
193
|
+
[body, html_attrs, ajax_attrs, form_attrs]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
data/hobo_rapid.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
name = File.basename( __FILE__, '.gemspec' )
|
2
|
+
version = File.read(File.expand_path('../VERSION', __FILE__)).strip
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
s.authors = ['Tom Locke, Bryan Larsen']
|
8
|
+
s.email = 'tom@tomlocke.com'
|
9
|
+
s.homepage = 'http://hobocentral.net'
|
10
|
+
s.rubyforge_project = 'hobo'
|
11
|
+
s.summary = 'The RAPID tag library for Hobo'
|
12
|
+
s.description = 'The RAPID tag library for Hobo'
|
13
|
+
|
14
|
+
s.add_runtime_dependency('hobo', ["= #{version}"])
|
15
|
+
|
16
|
+
s.files = `git ls-files -x #{name}/* -z`.split("\0")
|
17
|
+
|
18
|
+
s.name = name
|
19
|
+
s.version = version
|
20
|
+
s.date = Date.today.to_s
|
21
|
+
|
22
|
+
s.required_rubygems_version = ">= 1.3.6"
|
23
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
24
|
+
s.require_paths = ["lib", "vendor"]
|
25
|
+
|
26
|
+
end
|
data/lib/hobo_rapid.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module HoboRapid
|
2
|
+
|
3
|
+
VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
|
4
|
+
@@root = Pathname.new File.expand_path('../..', __FILE__)
|
5
|
+
def self.root; @@root; end
|
6
|
+
|
7
|
+
EDIT_LINK_BASE = "https://github.com/tablatom/hobo_tree_table/edit/master/hobo_rapid"
|
8
|
+
|
9
|
+
require 'hobo_rapid/railtie' if defined?(Rails)
|
10
|
+
|
11
|
+
class Engine < ::Rails::Engine
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<!-- Buttons that do stuff. -->
|
@@ -0,0 +1,40 @@
|
|
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).
|
4
|
+
|
5
|
+
### Attributes
|
6
|
+
|
7
|
+
- model: The class to instantiate, pass either the class name or the class object.
|
8
|
+
|
9
|
+
-->
|
10
|
+
<def tag="create-button" attrs="model, update, label, fields, message"><%=
|
11
|
+
raise Hobo::Error.new("no update specified") unless update
|
12
|
+
|
13
|
+
fields ||= {}
|
14
|
+
class_or_assoc = if model
|
15
|
+
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
|
+
else
|
21
|
+
raise Hobo::Error.new("invalid context for <create-button>")
|
22
|
+
end
|
23
|
+
new = class_or_assoc.new(fields)
|
24
|
+
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>
|
@@ -0,0 +1,75 @@
|
|
1
|
+
<!-- Provides either an ajax or non-ajax delete button to send a
|
2
|
+
RESTful "DELETE". The context should be a record for which you to
|
3
|
+
want provide a delete button.
|
4
|
+
|
5
|
+
There are three possible types of `delete-button` created.
|
6
|
+
|
7
|
+
### Non-Ajax
|
8
|
+
|
9
|
+
No Ajax is used if
|
10
|
+
|
11
|
+
- the `update`, `updates` and `ajax` attributes are not set AND EITHER
|
12
|
+
- `in-place` is explicitly set false OR
|
13
|
+
- the context for the delete is the same as the top-level context for the page. In other words, if you're trying to delete the entire page.
|
14
|
+
|
15
|
+
### Standard form Ajax
|
16
|
+
|
17
|
+
If you set the `update`, `updates` or `ajax` attributes, standard form/part AJAX is used. It's assumed that the part you're specifying includes the item to be deleted so that it will be removed from the page by the update.
|
18
|
+
|
19
|
+
### "Magic" Ajax
|
20
|
+
|
21
|
+
If:
|
22
|
+
|
23
|
+
- the `update`, `updates` and `ajax` attributes are not set AND EITHER
|
24
|
+
- `in-place` is explicitly set true OR
|
25
|
+
- the context for the delete is not the same as the top-level context for the page. In other words, if you're not trying to delete the entire page.
|
26
|
+
|
27
|
+
then `delete-button` performs an Ajax delete and then attempts to fix up the page. It does this by removing all items on the page that have their hobo-rapid-context set to the item being deleted. If said deletion results in an empty list, it shows the `.empty-collection-message`. This procedure should work with `<collection>`, `<table>` and their children (`<sortable-collection>`, `<table-plus>`, etc.).
|
28
|
+
|
29
|
+
### Attributes
|
30
|
+
|
31
|
+
All the standard ajax attributes *except the callbacks* are supported (see the main taglib documention for Rapid Forms).
|
32
|
+
|
33
|
+
- label: The label for the button. Default: "Remove". (Alternately, use the hobo.actions.remove translation to customize)
|
34
|
+
|
35
|
+
- in-place: see above
|
36
|
+
|
37
|
+
- image: URL of an image for the button.
|
38
|
+
|
39
|
+
- fade: Perform the fade effect (true/false)? Default: true
|
40
|
+
|
41
|
+
- confirm: has a default value of "Are you sure?" or hobo.messages.confirm translated. You must explicitly set this to false if you don't want a confirm message.
|
42
|
+
|
43
|
+
-->
|
44
|
+
<def tag="delete-button" attrs="label, in-place, image, confirm, fade, subsite"><%
|
45
|
+
url = object_url(this, :method => :delete, :subsite => subsite)
|
46
|
+
if url && can_delete?
|
47
|
+
in_place = !(this == @this && request.method.downcase == "get") if in_place.nil?
|
48
|
+
update_attrs, attributes = attributes.partition_hash(HoboRapidHelper::AJAX_UPDATE_ATTRS)
|
49
|
+
ajax_attrs, attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
50
|
+
attributes[src] = "#{base_url}/images/#{image}" if image
|
51
|
+
label ||= t("hobo.actions.remove", :default=>"Remove")
|
52
|
+
confirm = t("hobo.messages.confirm", :default=>"Are you sure?") if confirm.nil?
|
53
|
+
ajax_attrs[:confirm] = confirm if confirm
|
54
|
+
|
55
|
+
add_classes!(attributes,
|
56
|
+
image ? "image-button" : "button",
|
57
|
+
"delete-button delete-#{this.class.name.underscore.dasherize}-button")
|
58
|
+
|
59
|
+
if in_place && update_attrs.blank?
|
60
|
+
data_rapid = data_rapid(:delete_button)
|
61
|
+
ajax_attrs[:update] ||= "" # force form ajax
|
62
|
+
elsif !update_attrs.blank?
|
63
|
+
ajax_attrs.merge!(update_attrs)
|
64
|
+
data_rapid = nil
|
65
|
+
else
|
66
|
+
data_rapid = nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
%>
|
70
|
+
<if test="&url && can_delete?">
|
71
|
+
<form method="delete" action="&url" class="button_to" merge-attrs="&ajax_attrs" data-rapid="&data_rapid" data-rapid-context="&typed_id">
|
72
|
+
<input type="submit" value="&label" merge/>
|
73
|
+
</form>
|
74
|
+
</if>
|
75
|
+
</def>
|
@@ -0,0 +1,34 @@
|
|
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.
|
5
|
+
|
6
|
+
The URL that the call is POSTed to is the `object_url` of `this`, plus the method name
|
7
|
+
|
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.
|
10
|
+
|
11
|
+
### Attributes
|
12
|
+
|
13
|
+
- method: the name of the web-method to call
|
14
|
+
|
15
|
+
- label: the label on the button
|
16
|
+
|
17
|
+
-->
|
18
|
+
<def tag="remote-method-button" attrs="method, update, label, confirm, url"><%=
|
19
|
+
ajax_attributes, html_attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
20
|
+
|
21
|
+
url ||= object_url(this, method.to_s.gsub('-', '_'), :method => :post)
|
22
|
+
raise ArgumentError, "no such web method '#{method}' on #{this.typed_id}" unless url
|
23
|
+
|
24
|
+
add_classes!(html_attributes, "button remote-method-button #{method}-button")
|
25
|
+
label ||= method.titleize
|
26
|
+
if update || !ajax_attributes.empty?
|
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)
|
31
|
+
else
|
32
|
+
button_to(label, url, html_attributes.merge(:confirm => confirm))
|
33
|
+
end
|
34
|
+
%></def>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<!-- A push-button to invoke a lifecycle transition either as a page-reload or as an ajax call.
|
2
|
+
|
3
|
+
### Attributes
|
4
|
+
|
5
|
+
- `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
|
+
- `label` - the label on the button. Defaults to the name of the transition
|
8
|
+
|
9
|
+
All of the [standard ajax attributes](/api_taglibs/rapid_forms) are also supported.
|
10
|
+
|
11
|
+
### Warning
|
12
|
+
|
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.
|
14
|
+
|
15
|
+
### Invalid transitions
|
16
|
+
|
17
|
+
If the transition could not be found, the user does not have permissions for the transition or the object is not in the correct state for the transition, the transition-button displays nothing. You can use an `<else>` to display an appropriate message.
|
18
|
+
|
19
|
+
<transition-button transition="mogrify"/><else>Cannot mogrify</else>
|
20
|
+
|
21
|
+
-->
|
22
|
+
<def tag="transition-button" attrs="transition, update, label"><%=
|
23
|
+
if transition.is_a?(String)
|
24
|
+
transition = this.lifecycle.find_transition(transition, current_user)
|
25
|
+
end
|
26
|
+
if transition.nil?
|
27
|
+
Dryml.last_if = false
|
28
|
+
return ""
|
29
|
+
end
|
30
|
+
transition_name = transition.name
|
31
|
+
has_params = !transition.options[:params].blank?
|
32
|
+
ajax_attributes, html_attributes = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS)
|
33
|
+
|
34
|
+
html_attributes[:method] ||= has_params ? :get : :put
|
35
|
+
add_classes!(html_attributes, "transition-button #{transition_name}-button")
|
36
|
+
label = t("activerecord.attributes.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}", :default => (label || transition_name.to_s.titleize))
|
37
|
+
title = t("activerecord.attribute_help.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}")
|
38
|
+
html_attributes.update(:title => title) unless title.empty?
|
39
|
+
url = object_url(this, transition_name, :method => html_attributes[:method])
|
40
|
+
|
41
|
+
if (update || !ajax_attributes.empty?) && !has_params
|
42
|
+
ajax_attributes[:message] ||= label
|
43
|
+
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)
|
49
|
+
end
|
50
|
+
%>
|
51
|
+
</def>
|
52
|
+
|
53
|
+
<!-- Renders a div containing transition buttons for every transition available to the current user.
|
54
|
+
|
55
|
+
For example, you could use this on a `Friendship` card: the person invited to have friendship would automatically see 'Accept' and 'Decline' buttons, while the person initiating the invite would see 'Retract'.
|
56
|
+
|
57
|
+
This tag behaves similarly to repeat: an else tag may be used to handle the case of no buttons:
|
58
|
+
|
59
|
+
<transition-buttons/><else>Sorry, no buttons to press.</else>
|
60
|
+
-->
|
61
|
+
<def tag="transition-buttons">
|
62
|
+
<% ajax_attrs, html_attrs = attributes.partition_hash(HoboRapidHelper::AJAX_ATTRS) %>
|
63
|
+
<div merge-attrs="&html_attrs" class="transitions">
|
64
|
+
<% transitions = this.lifecycle.publishable_transitions_for(current_user) %>
|
65
|
+
<if test="&transitions">
|
66
|
+
<% transitions.each do |t| %>
|
67
|
+
<transition-button merge-attrs="&ajax_attrs" transition="&t"/>
|
68
|
+
<% end %>
|
69
|
+
</if>
|
70
|
+
</div>
|
71
|
+
</def>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!-- Displays a link to a lifecycle transition page if the transition is valid. If the transition is valid, this is equivalent to:
|
2
|
+
|
3
|
+
<a action="&transition" ...
|
4
|
+
|
5
|
+
If the transition is invalid, you may use the `<else>` tag to display an appropriate message:
|
6
|
+
|
7
|
+
<transition-link transition="mogrify">Mogrify</transition-link>
|
8
|
+
<else>Cannot mogrify</else>
|
9
|
+
|
10
|
+
### Attributes
|
11
|
+
|
12
|
+
All attributes and parameters for the `<a>` tag are also valid.
|
13
|
+
|
14
|
+
- `transition` - the name of the transition to invoke. Required
|
15
|
+
-->
|
16
|
+
<def tag="transition-link" attrs="transition"><%
|
17
|
+
trans = this.lifecycle.find_transition(transition, current_user) %>
|
18
|
+
<if test="&trans">
|
19
|
+
<a action="&transition" merge/>
|
20
|
+
</if>
|
21
|
+
</def>
|
22
|
+
|
@@ -0,0 +1,29 @@
|
|
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.
|
3
|
+
|
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.
|
6
|
+
|
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
|
17
|
+
|
18
|
+
-->
|
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 %>
|
29
|
+
</def>
|
@@ -0,0 +1 @@
|
|
1
|
+
<!-- Tags for caching -->
|