jqmobile_helpers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/Gemfile +13 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +6 -0
  4. data/Rakefile +29 -0
  5. data/lib/jqmobile_helpers.rb +1 -0
  6. data/lib/jqmobile_helpers/action_view_extensions/form_helper.rb +54 -0
  7. data/lib/jqmobile_helpers/buttons_helper.rb +639 -0
  8. data/lib/jqmobile_helpers/form_builder.rb +301 -0
  9. data/lib/jqmobile_helpers/list_views_helper.rb +326 -0
  10. data/lib/jqmobile_helpers/railtie.rb +23 -0
  11. data/lib/jqmobile_helpers/toolbars_helper.rb +115 -0
  12. data/rdoc/JqmobileHelpers.html +185 -0
  13. data/rdoc/JqmobileHelpers/ActionViewExtensions.html +160 -0
  14. data/rdoc/JqmobileHelpers/ActionViewExtensions/FormHelper.html +231 -0
  15. data/rdoc/JqmobileHelpers/ButtonsHelper.html +1502 -0
  16. data/rdoc/JqmobileHelpers/FormBuilder.html +816 -0
  17. data/rdoc/JqmobileHelpers/ListViewsHelper.html +952 -0
  18. data/rdoc/JqmobileHelpers/Railtie.html +177 -0
  19. data/rdoc/JqmobileHelpers/ToolbarsHelper.html +416 -0
  20. data/rdoc/README_rdoc.html +109 -0
  21. data/rdoc/created.rid +9 -0
  22. data/rdoc/index.html +180 -0
  23. data/rdoc/js/darkfish.js +116 -0
  24. data/rdoc/js/jquery.js +32 -0
  25. data/rdoc/js/quicksearch.js +114 -0
  26. data/rdoc/js/thickbox-compressed.js +10 -0
  27. data/rdoc/lib/jqmobile_helpers/action_view_extensions/form_helper_rb.html +52 -0
  28. data/rdoc/lib/jqmobile_helpers/buttons_helper_rb.html +52 -0
  29. data/rdoc/lib/jqmobile_helpers/form_builder_rb.html +52 -0
  30. data/rdoc/lib/jqmobile_helpers/list_views_helper_rb.html +52 -0
  31. data/rdoc/lib/jqmobile_helpers/railtie_rb.html +62 -0
  32. data/rdoc/lib/jqmobile_helpers/toolbars_helper_rb.html +52 -0
  33. data/rdoc/lib/jqmobile_helpers_rb.html +54 -0
  34. data/rdoc/rdoc.css +706 -0
  35. data/test/buttons_helper_test.rb +112 -0
  36. data/test/dummy/Rakefile +7 -0
  37. data/test/dummy/app/controllers/application_controller.rb +3 -0
  38. data/test/dummy/app/controllers/buttons_controller.rb +9 -0
  39. data/test/dummy/app/controllers/forms_controller.rb +71 -0
  40. data/test/dummy/app/controllers/posts_controller.rb +83 -0
  41. data/test/dummy/app/controllers/toolbars_controller.rb +16 -0
  42. data/test/dummy/app/helpers/application_helper.rb +2 -0
  43. data/test/dummy/app/helpers/posts_helper.rb +2 -0
  44. data/test/dummy/app/helpers/toolbars_helper.rb +2 -0
  45. data/test/dummy/app/models/post.rb +2 -0
  46. data/test/dummy/app/models/toolbar.rb +2 -0
  47. data/test/dummy/app/views/buttons/index.html.erb +168 -0
  48. data/test/dummy/app/views/forms/_form.html.erb +20 -0
  49. data/test/dummy/app/views/forms/edit.html.erb +6 -0
  50. data/test/dummy/app/views/forms/index.html.erb +7 -0
  51. data/test/dummy/app/views/forms/new.html.erb +5 -0
  52. data/test/dummy/app/views/forms/show.html.erb +24 -0
  53. data/test/dummy/app/views/layouts/application.html.erb +49 -0
  54. data/test/dummy/app/views/posts/_form.html.erb +29 -0
  55. data/test/dummy/app/views/posts/edit.html.erb +6 -0
  56. data/test/dummy/app/views/posts/index.html.erb +128 -0
  57. data/test/dummy/app/views/posts/new.html.erb +5 -0
  58. data/test/dummy/app/views/posts/show.html.erb +24 -0
  59. data/test/dummy/app/views/toolbars/index.html.erb +25 -0
  60. data/test/dummy/config.ru +4 -0
  61. data/test/dummy/config/application.rb +45 -0
  62. data/test/dummy/config/boot.rb +10 -0
  63. data/test/dummy/config/database.yml +22 -0
  64. data/test/dummy/config/environment.rb +5 -0
  65. data/test/dummy/config/environments/development.rb +26 -0
  66. data/test/dummy/config/environments/production.rb +49 -0
  67. data/test/dummy/config/environments/test.rb +35 -0
  68. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  69. data/test/dummy/config/initializers/inflections.rb +10 -0
  70. data/test/dummy/config/initializers/mime_types.rb +5 -0
  71. data/test/dummy/config/initializers/secret_token.rb +7 -0
  72. data/test/dummy/config/initializers/session_store.rb +8 -0
  73. data/test/dummy/config/locales/en.yml +5 -0
  74. data/test/dummy/config/routes.rb +69 -0
  75. data/test/dummy/db/development.sqlite3 +0 -0
  76. data/test/dummy/db/migrate/20110218095442_create_posts.rb +15 -0
  77. data/test/dummy/db/migrate/20110223031713_create_toolbars.rb +12 -0
  78. data/test/dummy/db/schema.rb +29 -0
  79. data/test/dummy/db/test.sqlite3 +0 -0
  80. data/test/dummy/log/development.log +7446 -0
  81. data/test/dummy/log/production.log +0 -0
  82. data/test/dummy/log/server.log +0 -0
  83. data/test/dummy/log/test.log +2278 -0
  84. data/test/dummy/public/404.html +26 -0
  85. data/test/dummy/public/422.html +26 -0
  86. data/test/dummy/public/500.html +26 -0
  87. data/test/dummy/public/favicon.ico +0 -0
  88. data/test/dummy/public/images/ajax-loader.png +0 -0
  89. data/test/dummy/public/images/form-check-off.png +0 -0
  90. data/test/dummy/public/images/form-check-on.png +0 -0
  91. data/test/dummy/public/images/form-radio-off.png +0 -0
  92. data/test/dummy/public/images/form-radio-on.png +0 -0
  93. data/test/dummy/public/images/icon-search-black.png +0 -0
  94. data/test/dummy/public/images/icons-18-black.png +0 -0
  95. data/test/dummy/public/images/icons-18-white.png +0 -0
  96. data/test/dummy/public/images/icons-36-black.png +0 -0
  97. data/test/dummy/public/images/icons-36-white.png +0 -0
  98. data/test/dummy/public/javascripts/application.js +2 -0
  99. data/test/dummy/public/javascripts/jquery-1.5.min.js +8176 -0
  100. data/test/dummy/public/javascripts/jquery-ui-1.8.9.custom.min.js +781 -0
  101. data/test/dummy/public/javascripts/jquery.mobile-1.0a3.min.js +121 -0
  102. data/test/dummy/public/javascripts/rails.js +175 -0
  103. data/test/dummy/public/stylesheets/images/ajax-loader.png +0 -0
  104. data/test/dummy/public/stylesheets/images/form-check-off.png +0 -0
  105. data/test/dummy/public/stylesheets/images/form-check-on.png +0 -0
  106. data/test/dummy/public/stylesheets/images/form-radio-off.png +0 -0
  107. data/test/dummy/public/stylesheets/images/form-radio-on.png +0 -0
  108. data/test/dummy/public/stylesheets/images/icon-search-black.png +0 -0
  109. data/test/dummy/public/stylesheets/images/icons-18-black.png +0 -0
  110. data/test/dummy/public/stylesheets/images/icons-18-white.png +0 -0
  111. data/test/dummy/public/stylesheets/images/icons-36-black.png +0 -0
  112. data/test/dummy/public/stylesheets/images/icons-36-white.png +0 -0
  113. data/test/dummy/public/stylesheets/jquery-ui-1.8.9.custom.css +573 -0
  114. data/test/dummy/public/stylesheets/jquery.mobile-1.0a3.min.css +16 -0
  115. data/test/dummy/public/stylesheets/scaffold.css +56 -0
  116. data/test/dummy/script/rails +6 -0
  117. data/test/dummy/tmp/pids/server.pid +1 -0
  118. data/test/form_helper_test.rb +13 -0
  119. data/test/integration/navigation_test.rb +7 -0
  120. data/test/list_views_helper_test.rb +65 -0
  121. data/test/support/integration_case.rb +5 -0
  122. data/test/support/misc_helpers.rb +18 -0
  123. data/test/support/mock_controller.rb +15 -0
  124. data/test/support/mock_response.rb +14 -0
  125. data/test/support/models.rb +135 -0
  126. data/test/test_helper.rb +92 -0
  127. data/test/toolbars_helper_test.rb +21 -0
  128. 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
+