jqmobile_helpers 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +13 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +6 -0
- data/Rakefile +29 -0
- data/lib/jqmobile_helpers.rb +1 -0
- data/lib/jqmobile_helpers/action_view_extensions/form_helper.rb +54 -0
- data/lib/jqmobile_helpers/buttons_helper.rb +639 -0
- data/lib/jqmobile_helpers/form_builder.rb +301 -0
- data/lib/jqmobile_helpers/list_views_helper.rb +326 -0
- data/lib/jqmobile_helpers/railtie.rb +23 -0
- data/lib/jqmobile_helpers/toolbars_helper.rb +115 -0
- data/rdoc/JqmobileHelpers.html +185 -0
- data/rdoc/JqmobileHelpers/ActionViewExtensions.html +160 -0
- data/rdoc/JqmobileHelpers/ActionViewExtensions/FormHelper.html +231 -0
- data/rdoc/JqmobileHelpers/ButtonsHelper.html +1502 -0
- data/rdoc/JqmobileHelpers/FormBuilder.html +816 -0
- data/rdoc/JqmobileHelpers/ListViewsHelper.html +952 -0
- data/rdoc/JqmobileHelpers/Railtie.html +177 -0
- data/rdoc/JqmobileHelpers/ToolbarsHelper.html +416 -0
- data/rdoc/README_rdoc.html +109 -0
- data/rdoc/created.rid +9 -0
- data/rdoc/index.html +180 -0
- data/rdoc/js/darkfish.js +116 -0
- data/rdoc/js/jquery.js +32 -0
- data/rdoc/js/quicksearch.js +114 -0
- data/rdoc/js/thickbox-compressed.js +10 -0
- data/rdoc/lib/jqmobile_helpers/action_view_extensions/form_helper_rb.html +52 -0
- data/rdoc/lib/jqmobile_helpers/buttons_helper_rb.html +52 -0
- data/rdoc/lib/jqmobile_helpers/form_builder_rb.html +52 -0
- data/rdoc/lib/jqmobile_helpers/list_views_helper_rb.html +52 -0
- data/rdoc/lib/jqmobile_helpers/railtie_rb.html +62 -0
- data/rdoc/lib/jqmobile_helpers/toolbars_helper_rb.html +52 -0
- data/rdoc/lib/jqmobile_helpers_rb.html +54 -0
- data/rdoc/rdoc.css +706 -0
- data/test/buttons_helper_test.rb +112 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/buttons_controller.rb +9 -0
- data/test/dummy/app/controllers/forms_controller.rb +71 -0
- data/test/dummy/app/controllers/posts_controller.rb +83 -0
- data/test/dummy/app/controllers/toolbars_controller.rb +16 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/posts_helper.rb +2 -0
- data/test/dummy/app/helpers/toolbars_helper.rb +2 -0
- data/test/dummy/app/models/post.rb +2 -0
- data/test/dummy/app/models/toolbar.rb +2 -0
- data/test/dummy/app/views/buttons/index.html.erb +168 -0
- data/test/dummy/app/views/forms/_form.html.erb +20 -0
- data/test/dummy/app/views/forms/edit.html.erb +6 -0
- data/test/dummy/app/views/forms/index.html.erb +7 -0
- data/test/dummy/app/views/forms/new.html.erb +5 -0
- data/test/dummy/app/views/forms/show.html.erb +24 -0
- data/test/dummy/app/views/layouts/application.html.erb +49 -0
- data/test/dummy/app/views/posts/_form.html.erb +29 -0
- data/test/dummy/app/views/posts/edit.html.erb +6 -0
- data/test/dummy/app/views/posts/index.html.erb +128 -0
- data/test/dummy/app/views/posts/new.html.erb +5 -0
- data/test/dummy/app/views/posts/show.html.erb +24 -0
- data/test/dummy/app/views/toolbars/index.html.erb +25 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +45 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +26 -0
- data/test/dummy/config/environments/production.rb +49 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +69 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20110218095442_create_posts.rb +15 -0
- data/test/dummy/db/migrate/20110223031713_create_toolbars.rb +12 -0
- data/test/dummy/db/schema.rb +29 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +7446 -0
- data/test/dummy/log/production.log +0 -0
- data/test/dummy/log/server.log +0 -0
- data/test/dummy/log/test.log +2278 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/images/ajax-loader.png +0 -0
- data/test/dummy/public/images/form-check-off.png +0 -0
- data/test/dummy/public/images/form-check-on.png +0 -0
- data/test/dummy/public/images/form-radio-off.png +0 -0
- data/test/dummy/public/images/form-radio-on.png +0 -0
- data/test/dummy/public/images/icon-search-black.png +0 -0
- data/test/dummy/public/images/icons-18-black.png +0 -0
- data/test/dummy/public/images/icons-18-white.png +0 -0
- data/test/dummy/public/images/icons-36-black.png +0 -0
- data/test/dummy/public/images/icons-36-white.png +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/jquery-1.5.min.js +8176 -0
- data/test/dummy/public/javascripts/jquery-ui-1.8.9.custom.min.js +781 -0
- data/test/dummy/public/javascripts/jquery.mobile-1.0a3.min.js +121 -0
- data/test/dummy/public/javascripts/rails.js +175 -0
- data/test/dummy/public/stylesheets/images/ajax-loader.png +0 -0
- data/test/dummy/public/stylesheets/images/form-check-off.png +0 -0
- data/test/dummy/public/stylesheets/images/form-check-on.png +0 -0
- data/test/dummy/public/stylesheets/images/form-radio-off.png +0 -0
- data/test/dummy/public/stylesheets/images/form-radio-on.png +0 -0
- data/test/dummy/public/stylesheets/images/icon-search-black.png +0 -0
- data/test/dummy/public/stylesheets/images/icons-18-black.png +0 -0
- data/test/dummy/public/stylesheets/images/icons-18-white.png +0 -0
- data/test/dummy/public/stylesheets/images/icons-36-black.png +0 -0
- data/test/dummy/public/stylesheets/images/icons-36-white.png +0 -0
- data/test/dummy/public/stylesheets/jquery-ui-1.8.9.custom.css +573 -0
- data/test/dummy/public/stylesheets/jquery.mobile-1.0a3.min.css +16 -0
- data/test/dummy/public/stylesheets/scaffold.css +56 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/form_helper_test.rb +13 -0
- data/test/integration/navigation_test.rb +7 -0
- data/test/list_views_helper_test.rb +65 -0
- data/test/support/integration_case.rb +5 -0
- data/test/support/misc_helpers.rb +18 -0
- data/test/support/mock_controller.rb +15 -0
- data/test/support/mock_response.rb +14 -0
- data/test/support/models.rb +135 -0
- data/test/test_helper.rb +92 -0
- data/test/toolbars_helper_test.rb +21 -0
- metadata +182 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
module JqmobileHelpers
|
|
2
|
+
# = JqmobileHelpers Form Helper
|
|
3
|
+
#
|
|
4
|
+
# Credits to https://github.com/alexreisner for his Informant formbuilder
|
|
5
|
+
#
|
|
6
|
+
# Provides a set of helper methods for jquery-mobile form elements
|
|
7
|
+
#
|
|
8
|
+
# Displays rails helpers fields within a div tag, label on one line, field below it.
|
|
9
|
+
# Simplify your form code by encapsulating all
|
|
10
|
+
# aspects of a field (label, description, etc) in a single method call.
|
|
11
|
+
#
|
|
12
|
+
# All field methods accept an options hash like the standard Rails FormBuilder methods
|
|
13
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
|
14
|
+
# Declare some options as custom (don't pass to built-in form helpers).
|
|
15
|
+
@@custom_field_options = [:label, :required, :description, :decoration]
|
|
16
|
+
@@custom_label_options = [:required, :colon, :label_for]
|
|
17
|
+
|
|
18
|
+
@@custom_options = @@custom_field_options + @@custom_label_options
|
|
19
|
+
|
|
20
|
+
# Run already-defined helpers through our "shell".
|
|
21
|
+
# See ActionView::Helpers::FormBuilder.field_helpers
|
|
22
|
+
helpers = field_helpers +
|
|
23
|
+
%w(select time_zone_select date_select) -
|
|
24
|
+
%w(hidden_field fields_for label)
|
|
25
|
+
helpers.each do |h|
|
|
26
|
+
define_method h do |field, *args|
|
|
27
|
+
options = args.detect { |a| a.is_a?(Hash) } || {}
|
|
28
|
+
case h
|
|
29
|
+
when 'check_box'
|
|
30
|
+
template = "check_box_field"
|
|
31
|
+
options[:colon] = false
|
|
32
|
+
when 'radio_button'
|
|
33
|
+
template = "radio_button_choice"
|
|
34
|
+
options[:colon] = false
|
|
35
|
+
else
|
|
36
|
+
template = "default_field"
|
|
37
|
+
end
|
|
38
|
+
build_shell(field, options, template) { super(field, *args) }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Render a set of radio buttons. Takes a method name, an array of
|
|
43
|
+
# choices (just like a +select+ field), and an options hash.
|
|
44
|
+
#
|
|
45
|
+
def radio_buttons(method, choices, options = {})
|
|
46
|
+
choices.map!{ |i| i.is_a?(Array) ? i : [i] }
|
|
47
|
+
build_shell(method, options, "radio_buttons_field") do
|
|
48
|
+
choices.map{ |c| radio_button method, c[1], :label => c[0],
|
|
49
|
+
:label_for => [object_name, method, c[1].to_s.downcase].join('_') }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Render a set of check boxes for selecting HABTM-associated objects.
|
|
54
|
+
# Takes a method name (eg, category_ids), an array of
|
|
55
|
+
# choices (just like a +select+ field), and an options hash.
|
|
56
|
+
# In the default template the check boxes are enclosed in a <div> with
|
|
57
|
+
# CSS class <tt>habtm_check_boxes</tt> which can be styled thusly to
|
|
58
|
+
# achieve a scrolling list:
|
|
59
|
+
#
|
|
60
|
+
# .habtm_check_boxes {
|
|
61
|
+
# overflow: auto;
|
|
62
|
+
# height: 150px;
|
|
63
|
+
# }
|
|
64
|
+
#
|
|
65
|
+
# A hidden field is included which eliminates the need to handle the
|
|
66
|
+
# no-boxes-checked case in the controller, for example:
|
|
67
|
+
#
|
|
68
|
+
# <input type="hidden" name="article[categories][]" value="" />
|
|
69
|
+
#
|
|
70
|
+
# This ensures that un-checking all boxes will work as expected.
|
|
71
|
+
# Unfortunately the check_box template is not applied to each check box
|
|
72
|
+
# (because the standard method of querying the @object for the field's
|
|
73
|
+
# value does not work--ie, there is no "categories[]" method).
|
|
74
|
+
#
|
|
75
|
+
# ==== Examples
|
|
76
|
+
# <%= f.habtm_check_boxes :feature_ids,Feature.all.map{ |m| [m.name, m.id] } %>
|
|
77
|
+
#
|
|
78
|
+
def habtm_check_boxes(method, choices, options = {}) #:nodoc:
|
|
79
|
+
choices.map!{ |i| i.is_a?(Array) ? i : [i] }
|
|
80
|
+
base_id = "#{object_name}_#{method}"
|
|
81
|
+
base_name = "#{object_name}[#{method}]"
|
|
82
|
+
|
|
83
|
+
@template.hidden_field_tag(
|
|
84
|
+
"#{base_name}[]", "", :id => "#{base_id}_empty") +
|
|
85
|
+
build_shell(method, options, "habtm_check_boxes_field") do
|
|
86
|
+
choices.map do |c|
|
|
87
|
+
field_id = "#{base_id}_#{c[1].to_s.downcase}"
|
|
88
|
+
@template.content_tag(:div, :class => "field") do
|
|
89
|
+
@template.check_box_tag(
|
|
90
|
+
"#{base_name}[]", c[1],
|
|
91
|
+
@object.send(method).include?(c[1]),
|
|
92
|
+
:id => field_id
|
|
93
|
+
) + @template.label_tag(field_id, c[0])
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Standard Rails date selector.
|
|
100
|
+
#
|
|
101
|
+
def date_select(method, options = {})
|
|
102
|
+
options[:include_blank] ||= false
|
|
103
|
+
options[:start_year] ||= 1801
|
|
104
|
+
options[:end_year] ||= Time.now.year
|
|
105
|
+
options[:label_for] = "#{object_name}_#{method}_1i"
|
|
106
|
+
build_shell(method, options) { super }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# This differs from the Rails-default date_select in that it
|
|
111
|
+
# submits three distinct fields for storage in three separate attributes.
|
|
112
|
+
# This allows for partial dates (eg, "1984" or "October 1984").
|
|
113
|
+
# See {FlexDate}[http://github.com/alexreisner/flex_date] for
|
|
114
|
+
# storing and manipulating partial dates.
|
|
115
|
+
#
|
|
116
|
+
def multipart_date_select(method, options = {})
|
|
117
|
+
options[:include_blank] ||= false
|
|
118
|
+
options[:start_year] ||= 1801
|
|
119
|
+
options[:end_year] ||= Time.now.year
|
|
120
|
+
options[:prefix] = object_name # for date helpers
|
|
121
|
+
options[:label_for] = "#{object_name}_#{method}_y"
|
|
122
|
+
build_shell(method, options) do
|
|
123
|
+
[['y', 'year'], ['m', 'month'], ['d', 'day']].map{ |p|
|
|
124
|
+
i,j = p
|
|
125
|
+
value = @object.send(method.to_s + '_' + i)
|
|
126
|
+
options[:field_name] = method.to_s + '_' + i
|
|
127
|
+
eval("@template.select_#{j}(#{value.inspect}, options)")
|
|
128
|
+
}.join(' ')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Year select field. Takes options <tt>:start_year</tt> and
|
|
133
|
+
# <tt>:end_year</tt>, and <tt>:step</tt>.
|
|
134
|
+
#
|
|
135
|
+
def year_select(method, options = {})
|
|
136
|
+
options[:first] = options[:start_year] || 1801
|
|
137
|
+
options[:last] = options[:end_year] || Date.today.year
|
|
138
|
+
integer_select(method, options)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Integer select field.
|
|
142
|
+
# Takes options <tt>:first</tt>, <tt>:last</tt>, and <tt>:step</tt>.
|
|
143
|
+
#
|
|
144
|
+
def integer_select(method, options = {})
|
|
145
|
+
options[:step] ||= 1
|
|
146
|
+
choices = []; i = 0
|
|
147
|
+
(options[:first]..options[:last]).each do |n|
|
|
148
|
+
choices << n if i % options[:step] == 0
|
|
149
|
+
i += 1
|
|
150
|
+
end
|
|
151
|
+
select method, choices, options
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Submit button with smart default text (if +value+ is nil uses "Create"
|
|
155
|
+
# for new record or "Update" for old record).
|
|
156
|
+
#
|
|
157
|
+
def submit(value = nil, options = {})
|
|
158
|
+
value = (@object.new_record?? "Create" : "Update") if value.nil?
|
|
159
|
+
build_shell(value, options, 'submit_button') { super }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Render a field label.
|
|
163
|
+
#
|
|
164
|
+
def label(method, text = nil, options = {})
|
|
165
|
+
colon = false if options[:colon].nil?
|
|
166
|
+
options[:for] = options[:label_for]
|
|
167
|
+
required = options[:required]
|
|
168
|
+
|
|
169
|
+
# remove special options
|
|
170
|
+
options.delete :colon
|
|
171
|
+
options.delete :label_for
|
|
172
|
+
options.delete :required
|
|
173
|
+
|
|
174
|
+
text = @template.send(:h, text.blank?? method.to_s.humanize : text.to_s)
|
|
175
|
+
text << ':'.html_safe if colon
|
|
176
|
+
text << @template.content_tag(:span, "*", :class => "required") if required
|
|
177
|
+
super
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Render a field set (HTML fieldset tag). Takes the legend (optional), an
|
|
181
|
+
# options hash, and a block in which fields are rendered.
|
|
182
|
+
#
|
|
183
|
+
def field_set(legend = nil, options = nil, &block)
|
|
184
|
+
@template.content_tag(:fieldset, options) do
|
|
185
|
+
(legend.blank?? "" : @template.content_tag(:legend, legend)) +
|
|
186
|
+
@template.capture(&block)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
private # ---------------------------------------------------------------
|
|
191
|
+
|
|
192
|
+
# Insert a field into its HTML "shell".
|
|
193
|
+
#
|
|
194
|
+
def build_shell(method, options, template = 'default_field') #:nodoc:
|
|
195
|
+
|
|
196
|
+
# Build new options hash for custom label options.
|
|
197
|
+
label_options = options.reject{ |i,j| !@@custom_label_options.include? i }
|
|
198
|
+
|
|
199
|
+
# Build new options hash for custom field options.
|
|
200
|
+
field_options = options.reject{ |i,j| !@@custom_field_options.include? i }
|
|
201
|
+
|
|
202
|
+
# Remove custom options from options hash so things like
|
|
203
|
+
# <tt>include_blank</tt> aren't added as HTML attributes.
|
|
204
|
+
options.reject!{ |i,j| @@custom_options.include? i }
|
|
205
|
+
|
|
206
|
+
locals = {
|
|
207
|
+
:element => yield,
|
|
208
|
+
:label => label(method, field_options[:label], label_options),
|
|
209
|
+
:description => field_options[:description],
|
|
210
|
+
:div_id => "#{@object_name}_#{method}_field",
|
|
211
|
+
:required => field_options[:required],
|
|
212
|
+
:decoration => field_options[:decoration] || nil
|
|
213
|
+
}
|
|
214
|
+
send("#{template}_template", locals).html_safe
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Render default field template for all the following field methods:
|
|
218
|
+
# "fields_for", "label", "text_field", "password_field", "hidden_field", "file_field", "text_area",
|
|
219
|
+
# "search_field", "telephone_field", "phone_field", "url_field",
|
|
220
|
+
# "email_field", "number_field", "range_field"
|
|
221
|
+
#
|
|
222
|
+
# ==== Examples
|
|
223
|
+
# <%= jq_form_for(@post) do |f| %>
|
|
224
|
+
# <%= f.text_field :name %>
|
|
225
|
+
# <% end %>
|
|
226
|
+
#
|
|
227
|
+
# # =>(Ommiting form_for results)
|
|
228
|
+
# <div data-role="fieldcontain" id="post_name_field" class="field">
|
|
229
|
+
# label for="post_name">Name</label><br />
|
|
230
|
+
# <input id="post_name" name="post[name]" size="30" type="text" />
|
|
231
|
+
# </div>
|
|
232
|
+
#
|
|
233
|
+
# You can pass a few other options for your input fields.
|
|
234
|
+
#
|
|
235
|
+
# ==== Examples
|
|
236
|
+
# <%= f.text_field :name, :description => "Fill in your name", :required => true,
|
|
237
|
+
# :label => "Your Name", :decoration => 'basically a field' %>
|
|
238
|
+
# # => <div data-role="fieldcontain" id="post_name_field" class="field">
|
|
239
|
+
# label for="post_name">Your Name<span class="required">*</span></label><br />
|
|
240
|
+
# <input id="post_name" name="post[name]" size="30" type="text" />basically a field
|
|
241
|
+
# </div>
|
|
242
|
+
#
|
|
243
|
+
def default_field_template(l = {})
|
|
244
|
+
<<-END
|
|
245
|
+
<div data-role="fieldcontain" id="#{l[:div_id]}" class="field">
|
|
246
|
+
#{l[:label]}<br />
|
|
247
|
+
#{l[:element]}#{l[:decoration]}
|
|
248
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
|
249
|
+
</div>
|
|
250
|
+
END
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Render check box field template.
|
|
254
|
+
#
|
|
255
|
+
def check_box_field_template(l = {})
|
|
256
|
+
<<-END
|
|
257
|
+
<div data-role="fieldcontain" id="#{l[:div_id]}" class="field">
|
|
258
|
+
#{l[:element]} #{l[:label]} #{l[:decoration]}<br />
|
|
259
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
|
260
|
+
</div>
|
|
261
|
+
END
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# Render single radio button. Note that this is the only field
|
|
265
|
+
# template without an enclosing <tt><div class="field"></tt> because it
|
|
266
|
+
# is intended for use only within the radio_buttons_template (plural).
|
|
267
|
+
#
|
|
268
|
+
def radio_button_choice_template(l = {})
|
|
269
|
+
<<-END
|
|
270
|
+
#{l[:element]} #{l[:label]}
|
|
271
|
+
END
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Render a group of radio buttons.
|
|
275
|
+
#
|
|
276
|
+
def radio_buttons_field_template(l = {})
|
|
277
|
+
default_field_template(l)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Render a group of HABTM check boxes.
|
|
281
|
+
#
|
|
282
|
+
def habtm_check_boxes_field_template(l = {})
|
|
283
|
+
<<-END
|
|
284
|
+
<div data-role="fieldcontain" id="#{l[:div_id]}" class="field">
|
|
285
|
+
#{l[:label]}<br />
|
|
286
|
+
<div class="habtm_check_boxes">#{l[:element]}</div>#{l[:decoration]}
|
|
287
|
+
#{"<p class=\"field_description\">#{l[:description]}</p>" unless l[:description].blank?}
|
|
288
|
+
</div>
|
|
289
|
+
END
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# Render submit button template.
|
|
293
|
+
#
|
|
294
|
+
def submit_button_template(l = {})
|
|
295
|
+
<<-END
|
|
296
|
+
<div class="button">#{l[:element]}</div>
|
|
297
|
+
END
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
end
|
|
301
|
+
end
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
module JqmobileHelpers
|
|
2
|
+
# = JqmobileHelpers List View Helpers
|
|
3
|
+
# Provides a set of methods for making list views
|
|
4
|
+
# for jquery-mobile markup
|
|
5
|
+
module ListViewsHelper
|
|
6
|
+
# html5 data attributes options value
|
|
7
|
+
mattr_accessor :default_options
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# ====================================== BASIC LIST ===========================================================
|
|
11
|
+
# Creates a simple unordered list containing linked list items
|
|
12
|
+
# with a data-role="listview" attribute
|
|
13
|
+
#
|
|
14
|
+
# ==== Options
|
|
15
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
16
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
17
|
+
#
|
|
18
|
+
# ==== Examples
|
|
19
|
+
# basic_list(@posts.map{|x| x.title})
|
|
20
|
+
# # => <ul data-role="listview" data-inset="true"><li>Title 1</li><li>test2</li></ul>
|
|
21
|
+
#
|
|
22
|
+
# basic_list(@posts.map{|x| link_to(x.title, post_path(x))}, {'data-inset'=>'false', 'data-theme'=>'b'})
|
|
23
|
+
# # => <ul data-role="listview" data-inset="false" data-theme="b"> \\
|
|
24
|
+
# <li><a href='/posts/1'>Title 1</a></li><li><a href="/posts/2">test2</a></li></ul>
|
|
25
|
+
#
|
|
26
|
+
def basic_list(collection, options = {})
|
|
27
|
+
html_attributes_options(options)
|
|
28
|
+
list = collection.map {|item| content_tag("li", item)}
|
|
29
|
+
content_tag(:ul, list.join.html_safe, default_options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# ====================================== NUMBERED LIST ===========================================================
|
|
33
|
+
# Creates ordered lists (ol) which is useful when presented items that are in a sequence.
|
|
34
|
+
# When the enhanced markup is applied to the list view, jQuery Mobile will try to first use CSS to add numbers
|
|
35
|
+
# to the list and, if not supported, will fall back to injecting numbers with JavaScript
|
|
36
|
+
#
|
|
37
|
+
# ==== Options
|
|
38
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
39
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
40
|
+
#
|
|
41
|
+
# ==== Examples
|
|
42
|
+
# basic_list(@posts.map{|x| x.title})
|
|
43
|
+
# # => <ol data-role="listview" data-inset="true"><li>Title 1</li><li>test2</li></ol>
|
|
44
|
+
#
|
|
45
|
+
# basic_list(@posts.map{|x| link_to(x.title, post_path(x))}, {'data-inset'=>'false', 'data-theme'=>'b'})
|
|
46
|
+
# # => <ol data-role="listview" data-inset="false" data-theme="b"> \\
|
|
47
|
+
# <li><a href='/posts/1'>Title 1</a></li><li><a href="/posts/2">test2</a></li></ol>
|
|
48
|
+
#
|
|
49
|
+
def numbered_list(collection, options = {})
|
|
50
|
+
html_attributes_options(options)
|
|
51
|
+
list = collection.map {|item| content_tag("li", item)}
|
|
52
|
+
content_tag(:ol, list.join.html_safe, self.default_options)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# ======================================NESTED LIST ===========================================================
|
|
57
|
+
# By nesting child ul of ol inside list items, you can create nested lists.
|
|
58
|
+
# When a list item with a child list is clicked, the framework will generate a new ui-page populated
|
|
59
|
+
# with the title of the parent in the header and the list of child elements.
|
|
60
|
+
#
|
|
61
|
+
#
|
|
62
|
+
# ==== Options
|
|
63
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
64
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
65
|
+
#
|
|
66
|
+
# ==== Examples
|
|
67
|
+
# <%= nested_list @posts.map{|x| link_to(x.title, post_path(x))} %>
|
|
68
|
+
# # => <ul data-inset="true" data-role="listview"><li><ul><li><a href="/birds/1">Bird</a></li></ul></li></ul>
|
|
69
|
+
#
|
|
70
|
+
#
|
|
71
|
+
def nested_list(collection, options = {})
|
|
72
|
+
html_attributes_options(options)
|
|
73
|
+
list = collection.map {|item| content_tag("li", content_tag("ul", content_tag("li", item)))}
|
|
74
|
+
content_tag :ul, list.join.html_safe, self.default_options
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# ====================================== SPLIT-BUTTON LIST ===========================================================
|
|
78
|
+
# In cases where there is more than one possible action per list item,
|
|
79
|
+
# a split button can be used to offer two independently clickable items -- the list item and a small arrow icon in the far right
|
|
80
|
+
# The framework will add a vertical divider line and sets the title attribute of the link to the text the link for accessibility.
|
|
81
|
+
#
|
|
82
|
+
#
|
|
83
|
+
# ==== Options
|
|
84
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
85
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
86
|
+
#
|
|
87
|
+
# ==== Examples
|
|
88
|
+
# <%= split_button_list "Split Button List", post_path(@posts) %>
|
|
89
|
+
# # => <ul data-role="listview" data-split-icon="gear" data-split-theme="d"><li><a data-rel="dialog" data-transition="slideup" href="/posts/1">Split Button List</a></li></ul>
|
|
90
|
+
#
|
|
91
|
+
# ======for collections of data that have more than one.
|
|
92
|
+
# <% @posts.each do |post|
|
|
93
|
+
# <%= split_button_list(post.name, post_path(post)) %>
|
|
94
|
+
# <% end %>
|
|
95
|
+
#
|
|
96
|
+
def split_button_list(name,link, options={})
|
|
97
|
+
html_attributes_options(options)
|
|
98
|
+
default_split_options = {'data-icon' => "gear"}
|
|
99
|
+
split_options = {'data-rel' => "dialog", 'data-transition' => "slideup"}
|
|
100
|
+
list = content_tag("li", content_tag(:a, name, {:href => link}.merge(split_options)))
|
|
101
|
+
#list = content_tag("li", content_tag(:a, data, {:href => link}.merge(split_options)))
|
|
102
|
+
content_tag(:ul, list, self.default_options.merge(default_split_options))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# ====================================== SPLIT-BUTTON LIST ===========================================================
|
|
107
|
+
# In cases where there is more than one possible action per list item,
|
|
108
|
+
# a split button can be used to offer two independently clickable items -- the list item and a small arrow icon in the far right
|
|
109
|
+
# The framework will add a vertical divider line and sets the title attribute of the link to the text the link for accessibility.
|
|
110
|
+
#
|
|
111
|
+
#
|
|
112
|
+
# ==== Options
|
|
113
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
114
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
115
|
+
#
|
|
116
|
+
# ==== Examples
|
|
117
|
+
# <%= split_button_list "Split Button List", post_path(@posts) %>
|
|
118
|
+
# # => <ul data-role="listview" data-split-icon="gear" data-split-theme="d"><li><a data-rel="dialog" data-transition="slideup" href="/posts/1">Split Button List</a></li></ul>
|
|
119
|
+
#
|
|
120
|
+
# ======for collections of data that have more than one.
|
|
121
|
+
# <% @posts.each do |post|
|
|
122
|
+
# <%= split_button_list(post.name, post_path(post)) %>
|
|
123
|
+
# <% end %>
|
|
124
|
+
#
|
|
125
|
+
def count_bubble(collection, options = {})
|
|
126
|
+
html_attributes_options(options)
|
|
127
|
+
list = collection.map do |item|
|
|
128
|
+
if item.is_a?(Array)
|
|
129
|
+
if item[1].blank?
|
|
130
|
+
item[1] = content_tag(:a, "No item description", :href => "")
|
|
131
|
+
end
|
|
132
|
+
content_tag("li", "#{item[1]}<span class=ui-li-count>#{item.size}</span>".html_safe)
|
|
133
|
+
else
|
|
134
|
+
content_tag("li", item)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
content_tag(:ul, list.join.html_safe, self.default_options)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# To add thumbnails to the left of a list item, the first element in your collection must have a image_tag.
|
|
141
|
+
# The framework will scale the image to 80 pixels square.
|
|
142
|
+
#
|
|
143
|
+
# Items in your collection must also be constructed inside an array with 3 elements inside
|
|
144
|
+
#
|
|
145
|
+
# ==== Examples
|
|
146
|
+
# <%= thumbnail_list(@posts.collect do |x|
|
|
147
|
+
# [image_tag('/images/sample-pic.jpg'), link_to(x.title, post_path(x)), x.title]
|
|
148
|
+
# end) %>
|
|
149
|
+
# # => <ul data-inset="false" data-role="listview">
|
|
150
|
+
# <li>
|
|
151
|
+
# <img alt="Album-bb" src="/images/album-bb.jpg" />
|
|
152
|
+
# <h3><a href="/posts/1">Title 1</a></h3><p>Title 1</p>
|
|
153
|
+
# </li>
|
|
154
|
+
# </ul>
|
|
155
|
+
#
|
|
156
|
+
def thumbnail_list(collection, options={})
|
|
157
|
+
html_attributes_options(options)
|
|
158
|
+
list = collection.map do |item|
|
|
159
|
+
if item.is_a?(Array)
|
|
160
|
+
if item[1].blank?
|
|
161
|
+
item[1] = content_tag(:a, "No item description", :href => "")
|
|
162
|
+
end
|
|
163
|
+
content_tag("li", item[0] + "<h3>#{item[1]}</h3><p>#{item[2]}</p>".html_safe)
|
|
164
|
+
else
|
|
165
|
+
content_tag("li", item)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
content_tag(:ul, list.join.html_safe, default_options.update('data-inset' => 'false'))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# ====================================== ICON LIST ===========================================================
|
|
172
|
+
# To add thumbnails to the left of a list item, the first element in your collection must have a image_tag.
|
|
173
|
+
# The framework will scale the image to 80 pixels square.
|
|
174
|
+
#
|
|
175
|
+
# Items in your collection must also be constructed inside an array with 3 elements inside
|
|
176
|
+
#
|
|
177
|
+
# ==== Examples
|
|
178
|
+
# <%= icon_list(@posts.collect do |x|
|
|
179
|
+
# [image_tag('/images/sample-pic.jpg'), link_to(x.title, post_path(x))]
|
|
180
|
+
# end) %>
|
|
181
|
+
# # => <ul data-inset="false" data-role="listview">
|
|
182
|
+
# <li><img alt="Gb" class="ui-li-icon" src="https://github.com/jquery/jquery-mobile/blob/master/docs/lists/images/gb.png" />
|
|
183
|
+
# <a href="/posts/1">First Title </a>
|
|
184
|
+
# <span class=ui-li-count>2</span>
|
|
185
|
+
# </li>
|
|
186
|
+
# </ul>
|
|
187
|
+
#
|
|
188
|
+
def icon_list(collection, options = {})
|
|
189
|
+
html_attributes_options(options)
|
|
190
|
+
list = collection.map do |item|
|
|
191
|
+
if item.is_a?(Array)
|
|
192
|
+
if item[1].blank?
|
|
193
|
+
item[1] = content_tag(:a, "No item description", :href => "")
|
|
194
|
+
end
|
|
195
|
+
content_tag("li", item[0] + "#{item[1]}<span class=ui-li-count>#{item.size}</span>".html_safe)
|
|
196
|
+
else
|
|
197
|
+
content_tag("li", item)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
content_tag(:ul, list.join.html_safe, default_options.update('data-inset' => 'false'))
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# ====================================== SEARCH FILTER LIST ===========================================================
|
|
204
|
+
# jQuery Mobile provides a very easy way to filter a list with a simple client-side search feature.
|
|
205
|
+
# To make a list filterable, simply add the data-filter="true" attribute to the list.
|
|
206
|
+
# The framework will then append a search box above the list
|
|
207
|
+
# and add the behavior to filter out list items that don't contain the current search string as the user types.
|
|
208
|
+
#
|
|
209
|
+
# ==== Examples
|
|
210
|
+
# <%= search_filter_list(@posts.map{|x| link_to(x.title, post_path(x))}) %>
|
|
211
|
+
# # => <ul data-inset="false" data-role="listview" data-filter="true">
|
|
212
|
+
# <li>
|
|
213
|
+
# <a href="/posts/1">Title 1</a></h3><p>Title 1</p>
|
|
214
|
+
# </li>
|
|
215
|
+
# </ul>
|
|
216
|
+
#
|
|
217
|
+
def search_filter_list(collection, options = {})
|
|
218
|
+
html_attributes_options(options)
|
|
219
|
+
list = collection.map{|item| content_tag("li", item)}
|
|
220
|
+
content_tag(:ul, list.join.html_safe, default_options.update('data-filter' => 'true', 'data-inset' => 'false'))
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
# ====================================== LIST FORMATTING LIST ===========================================================
|
|
225
|
+
# jQuery Mobile provides a very easy way to filter a list with a simple client-side search feature.
|
|
226
|
+
# To make a list filterable, simply add the data-filter="true" attribute to the list.
|
|
227
|
+
# The framework will then append a search box above the list
|
|
228
|
+
# and add the behavior to filter out list items that don't contain the current search string as the user types.
|
|
229
|
+
#
|
|
230
|
+
# ==== Examples
|
|
231
|
+
# <%= search_filter_list(@posts.map{|x| link_to(x.title, post_path(x))}) %>
|
|
232
|
+
# # => <ul data-inset="false" data-role="listview" data-filter="true">
|
|
233
|
+
# <li>
|
|
234
|
+
# <a href="/posts/1">Title 1</a></h3><p>Title 1</p>
|
|
235
|
+
# </li>
|
|
236
|
+
# </ul>
|
|
237
|
+
#
|
|
238
|
+
def list_formatting(collection, options = {})
|
|
239
|
+
html_attributes_options(options)
|
|
240
|
+
#html_li_attributes_options(options)
|
|
241
|
+
divider =collection.map{|item| content_tag(:li, item, {'data-role' => 'list-divider'}) << collection.map{|item| content_tag("li",item)}}
|
|
242
|
+
content_tag(:ul, divider.join.html_safe, self.default_options)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# ====================================== LIST DIVIDER ===========================================================
|
|
247
|
+
# jQuery Mobile provides a very easy way to filter a list with a simple client-side search feature.
|
|
248
|
+
# To make a list filterable, simply add the data-filter="true" attribute to the list.
|
|
249
|
+
# The framework will then append a search box above the list
|
|
250
|
+
# and add the behavior to filter out list items that don't contain the current search string as the user types.
|
|
251
|
+
#
|
|
252
|
+
# ==== Examples
|
|
253
|
+
# <%= search_filter_list(@posts.map{|x| link_to(x.title, post_path(x))}) %>
|
|
254
|
+
# # => <ul data-inset="false" data-role="listview" data-filter="true">
|
|
255
|
+
# <li>
|
|
256
|
+
# <a href="/posts/1">Title 1</a></h3><p>Title 1</p>
|
|
257
|
+
# </li>
|
|
258
|
+
# </ul>
|
|
259
|
+
#
|
|
260
|
+
def list_divider(collection, collection1, options = {})
|
|
261
|
+
html_attributes_options(options)
|
|
262
|
+
#html_li_attributes_options(options)
|
|
263
|
+
list = collection.map{|item| content_tag(:li, item, {'data-role' => 'list-divider'}) << content_tag("li", collection1.map{|x| x})}
|
|
264
|
+
content_tag(:ul, list.join.html_safe, self.default_options)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# ====================================== INSET LIST ===========================================================
|
|
268
|
+
#
|
|
269
|
+
# ==== Options
|
|
270
|
+
# # => 'data-inset' => 'true' (Default data-inset is set to true)
|
|
271
|
+
# # => 'data-theme' => 'c' (Default data-theme is set to c)
|
|
272
|
+
#
|
|
273
|
+
# ==== Examples
|
|
274
|
+
# inset_list(@posts.map{|x| x.title})
|
|
275
|
+
# # => <ul data-role="listview" data-inset="true"><li>Title 1</li><li>test2</li></ul>
|
|
276
|
+
#
|
|
277
|
+
# ==== Examples
|
|
278
|
+
# ol_inset_list(@posts.map{|x| x.title}, {'data-theme' => "a"} )
|
|
279
|
+
# # => <ol data-role="listview" data-inset="true" data-theme="a"><li>Title 1</li><li>test2</li></ul>
|
|
280
|
+
#
|
|
281
|
+
def inset_list(collection, options = {})
|
|
282
|
+
html_attributes_options(options)
|
|
283
|
+
list = collection.map {|item| content_tag("li", item)}
|
|
284
|
+
content_tag(:ul, list.join.html_safe, default_options)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def ol_inset_list(collection, options = {})
|
|
288
|
+
html_attributes_options(options)
|
|
289
|
+
list = collection.map {|item| content_tag("li", item)}
|
|
290
|
+
content_tag(:ol, list.join.html_safe, default_options)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
private
|
|
294
|
+
|
|
295
|
+
# Default html5 data attributes for list view in jquery-mobile
|
|
296
|
+
def html_attributes_options(options)
|
|
297
|
+
html_options = options.stringify_keys!
|
|
298
|
+
self.default_options = {'data-role' => "listview", 'data-inset' => "true"}
|
|
299
|
+
|
|
300
|
+
if html_options.has_key?('data-inset')
|
|
301
|
+
self.default_options = default_options.merge({'data-inset' => html_options['data-inset']})
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
if html_options.has_key?('data-theme')
|
|
305
|
+
self.default_options = default_options.merge({'data-theme' => html_options['data-theme']})
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
if html_options.has_key?('data-rel')
|
|
309
|
+
self.default_options = default_options.merge({'data-rel' => html_options['data-rel']})
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
if html_options.has_key?('data-transition')
|
|
313
|
+
self.default_options = default_options.merge({'data-transition' => html_options['data-transition']})
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def html_li_attributes_options(options)
|
|
319
|
+
html_options = options.stringify_keys!
|
|
320
|
+
self.li_options = {'data-role' => "list-divider"}
|
|
321
|
+
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|