hanami-helpers 1.0.0.beta1 → 1.0.0.beta2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9a4372126c3d3cc4666a281f370b709108ce7522
4
- data.tar.gz: a906c5adc94f6e22df677efde17f28ce529fc35c
3
+ metadata.gz: eb48b89f222fd007b68eb1e8637adf33f9f9013b
4
+ data.tar.gz: ee5532b3500215c3855678a4f994f4c079ff55cc
5
5
  SHA512:
6
- metadata.gz: 5f713e2872f9b0d40d2e51980e3563500b33f1ee8b54c278258cd37cad97361420bf56c35e5a5f61552c205075283e3a483fb28f84313f8de0e411a353b7ca6e
7
- data.tar.gz: fa35b8534b30d4cd19698fe3b6cd7e82951bdf341e7831a196b190165f5476b382d4ced07d1099d11a9326a86ca14df1e19282b30f2cf87dda80e484cb9efac3
6
+ metadata.gz: 50494ab76fe2656faa81fbc6e7d03e2c44533a97e240fa803a55d379b43d4418e77041de9a89c1a193170570a47b76a4fad6cb65cb4b9a07a58466ab9f164bd9
7
+ data.tar.gz: 7d90a5493c27e27e5a824b7da06d07c6a1f413a1b2f004e4490878706c6daa12fd27f388a881538a7cfa8da4d221dfc08ade6a56192c131d364c49fa3c45d2a6
@@ -1,6 +1,18 @@
1
1
  # Hanami::Helpers
2
2
  View helpers for Ruby web applications
3
3
 
4
+ ## v1.0.0.beta2 - 2017-03-17
5
+ ### Added
6
+ - [Luca Guidi] Added `time_field` form helper
7
+ - [Luca Guidi] Added `month_field` form helper
8
+ - [Luca Guidi] Added `week_field` form helper
9
+ - [Luca Guidi] Added `range_field` form helper
10
+ - [Luca Guidi] Added `search_field` form helper
11
+ - [Luca Guidi] Added `url_field` form helper
12
+ - [Luca Guidi] Added `tel_field` form helper
13
+ - [Luca Guidi] Added `image_button` form helper
14
+ - [Luca Guidi] Added support for `<dialog>`, `<hgroup>`, `<rtc>`, `<slot>`, and `<var>` HTML5 tags
15
+
4
16
  ## v1.0.0.beta1 - 2017-02-14
5
17
  ### Added
6
18
  - [Luca Guidi] Official support for Ruby: MRI 2.4
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2016 Luca Guidi
1
+ Copyright (c) 2014-2017 Luca Guidi
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -384,6 +384,6 @@ __Hanami::Helpers__ uses [Semantic Versioning 2.0.0](http://semver.org)
384
384
 
385
385
  ## Copyright
386
386
 
387
- Copyright © 2014-2016 Luca Guidi – Released under MIT License
387
+ Copyright © 2014-2017 Luca Guidi – Released under MIT License
388
388
 
389
389
  This project was formerly known as Lotus (`lotus-helpers`).
@@ -6,6 +6,7 @@ require 'hanami/helpers/link_to_helper'
6
6
  require 'hanami/helpers/form_helper'
7
7
  require 'hanami/helpers/number_formatting_helper'
8
8
 
9
+ # @since 0.1.0
9
10
  module Hanami
10
11
  # View helpers for Ruby applications
11
12
  #
@@ -74,9 +74,8 @@ module Hanami
74
74
  # end
75
75
  # end
76
76
  #
77
- # # Corresponding template:
78
- # #
79
- # # <%= my_form %>
77
+ # <!-- use this in the template -->
78
+ # <%= my_form %>
80
79
  module FormHelper
81
80
  # Default HTTP method for form
82
81
  #
@@ -181,22 +180,23 @@ module Hanami
181
180
  # end
182
181
  # %>
183
182
  #
184
- # # It will render:
185
- # #
186
- # # <form action="/deliveries/1" method="POST" accept-charset="utf-8">
187
- # # <input type="hidden" name="_method" value="PATCH">
188
- # #
189
- # # # Value taken from delivery.delivered_on
190
- # # <input type="date" name="delivery[delivered_on]" id="delivery-delivered-on" value="2015-05-27">
191
- # #
192
- # # # Value taken from customer.name
193
- # # <input type="text" name="delivery[customer][name]" id="delivery-customer-name" value="Luca">
194
- # #
195
- # # # Value taken from customer.address.city
196
- # # <input type="text" name="delivery[customer][address][city]" id="delivery-customer-address-city" value="Rome">
197
- # #
198
- # # <button type="submit">Update</button>
199
- # # </form>
183
+ # <!-- output -->
184
+ #
185
+ # <form action="/deliveries/1" method="POST" accept-charset="utf-8">
186
+ # <input type="hidden" name="_method" value="PATCH">
187
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
188
+ #
189
+ # # Value taken from delivery.delivered_on
190
+ # <input type="date" name="delivery[delivered_on]" id="delivery-delivered-on" value="2015-05-27">
191
+ #
192
+ # # Value taken from customer.name
193
+ # <input type="text" name="delivery[customer][name]" id="delivery-customer-name" value="Luca">
194
+ #
195
+ # # Value taken from customer.address.city
196
+ # <input type="text" name="delivery[customer][address][city]" id="delivery-customer-address-city" value="Rome">
197
+ #
198
+ # <button type="submit">Update</button>
199
+ # </form>
200
200
  def initialize(name, url, values = {}, attributes = {})
201
201
  @name = name
202
202
  @url = url
@@ -255,15 +255,17 @@ module Hanami
255
255
  # end
256
256
  # %>
257
257
  #
258
- # Output:
259
- # # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
260
- # # <div>
261
- # # <label for="book-title">Title</label>
262
- # # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
263
- # # </div>
264
- # #
265
- # # <button type="submit">Create</button>
266
- # # </form>
258
+ # <!-- output -->
259
+ #
260
+ # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
261
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
262
+ # <div>
263
+ # <label for="book-title">Title</label>
264
+ # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
265
+ # </div>
266
+ #
267
+ # <button type="submit">Create</button>
268
+ # </form>
267
269
  #
268
270
  #
269
271
  #
@@ -284,17 +286,20 @@ module Hanami
284
286
  # end
285
287
  # end
286
288
  #
289
+ # <!-- in the corresponding template use this -->
287
290
  # <%= form %>
288
291
  #
289
- # Output:
290
- # # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
291
- # # <div>
292
- # # <label for="book-title">Title</label>
293
- # # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
294
- # # </div>
295
- # #
296
- # # <button type="submit">Create</button>
297
- # # </form>
292
+ # <!-- output -->
293
+ #
294
+ # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
295
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
296
+ # <div>
297
+ # <label for="book-title">Title</label>
298
+ # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
299
+ # </div>
300
+ #
301
+ # <button type="submit">Create</button>
302
+ # </form>
298
303
  #
299
304
  # @example Share Code Between Views
300
305
  #
@@ -348,15 +353,17 @@ module Hanami
348
353
  # end
349
354
  # %>
350
355
  #
351
- # Output:
352
- # # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
353
- # # <div>
354
- # # <label for="book-title">Title</label>
355
- # # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
356
- # # </div>
357
- # #
358
- # # <button type="submit">Create</button>
359
- # # </form>
356
+ # <!-- output -->
357
+ #
358
+ # <form action="/books" method="POST" accept-charset="utf-8" id="book-form" class="form-horizontal">
359
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
360
+ # <div>
361
+ # <label for="book-title">Title</label>
362
+ # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
363
+ # </div>
364
+ #
365
+ # <button type="submit">Create</button>
366
+ # </form>
360
367
  #
361
368
  # @example Method override
362
369
  # <%=
@@ -367,13 +374,15 @@ module Hanami
367
374
  # end
368
375
  # %>
369
376
  #
370
- # Output:
371
- # # <form action="/books/23" accept-charset="utf-8" id="book-form" method="POST">
372
- # # <input type="hidden" name="_method" value="PUT">
373
- # # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
374
- # #
375
- # # <button type="submit">Update</button>
376
- # # </form>
377
+ # <!-- output -->
378
+ #
379
+ # <form action="/books/23" accept-charset="utf-8" id="book-form" method="POST">
380
+ # <input type="hidden" name="_method" value="PUT">
381
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
382
+ # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
383
+ #
384
+ # <button type="submit">Update</button>
385
+ # </form>
377
386
  #
378
387
  # @example Nested fields
379
388
  # <%=
@@ -388,13 +397,15 @@ module Hanami
388
397
  # end
389
398
  # %>
390
399
  #
391
- # Output:
392
- # # <form action="/deliveries" accept-charset="utf-8" id="delivery-form" method="POST">
393
- # # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
394
- # # <input type="text" name="delivery[address][city]" id="delivery-address-city" value="">
395
- # #
396
- # # <button type="submit">Create</button>
397
- # # </form>
400
+ # <!-- output -->
401
+ #
402
+ # <form action="/deliveries" accept-charset="utf-8" id="delivery-form" method="POST">
403
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
404
+ # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
405
+ # <input type="text" name="delivery[address][city]" id="delivery-address-city" value="">
406
+ #
407
+ # <button type="submit">Create</button>
408
+ # </form>
398
409
  def form_for(name, url, options = {}, &blk)
399
410
  form = if name.is_a?(Form)
400
411
  options = url
@@ -1,6 +1,7 @@
1
1
  require 'hanami/helpers/form_helper/html_node'
2
2
  require 'hanami/helpers/form_helper/values'
3
3
  require 'hanami/helpers/html_helper/html_builder'
4
+ require 'hanami/helpers/escape_helper'
4
5
  require 'hanami/utils/string'
5
6
 
6
7
  module Hanami
@@ -74,6 +75,8 @@ module Hanami
74
75
 
75
76
  # ENCTYPE_MULTIPART = 'multipart/form-data'.freeze
76
77
 
78
+ include Helpers::EscapeHelper
79
+
77
80
  self.html_node = ::Hanami::Helpers::FormHelper::HtmlNode
78
81
 
79
82
  # Instantiate a form builder
@@ -160,13 +163,14 @@ module Hanami
160
163
  # end
161
164
  # %>
162
165
  #
163
- # Output:
164
- # # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
165
- # # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
166
- # # <input type="text" name="delivery[address][street]" id="delivery-address-street" value="">
167
- # #
168
- # # <button type="submit">Create</button>
169
- # # </form>
166
+ # <!-- output -->
167
+ # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
168
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
169
+ # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
170
+ # <input type="text" name="delivery[address][street]" id="delivery-address-street" value="">
171
+ #
172
+ # <button type="submit">Create</button>
173
+ # </form>
170
174
  #
171
175
  # @example Multiple levels of nesting
172
176
  # <%=
@@ -186,15 +190,16 @@ module Hanami
186
190
  # end
187
191
  # %>
188
192
  #
189
- # Output:
190
- # # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
191
- # # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
192
- # # <input type="text" name="delivery[address][street]" id="delivery-address-street" value="">
193
- # # <input type="text" name="delivery[address][location][city]" id="delivery-address-location-city" value="">
194
- # # <input type="text" name="delivery[address][location][country]" id="delivery-address-location-country" value="">
195
- # #
196
- # # <button type="submit">Create</button>
197
- # # </form>
193
+ # <!-- output -->
194
+ # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
195
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
196
+ # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
197
+ # <input type="text" name="delivery[address][street]" id="delivery-address-street" value="">
198
+ # <input type="text" name="delivery[address][location][city]" id="delivery-address-location-city" value="">
199
+ # <input type="text" name="delivery[address][location][country]" id="delivery-address-location-country" value="">
200
+ #
201
+ # <button type="submit">Create</button>
202
+ # </form>
198
203
  def fields_for(name)
199
204
  current_name = @name
200
205
  @name = _input_name(name)
@@ -224,15 +229,15 @@ module Hanami
224
229
  # end
225
230
  # %>
226
231
  #
227
- # Output:
228
- # # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
229
- # # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
230
- # # <input type="text" name="delivery[addresses][][street]" id="delivery-address-0-street" value="">
231
- # # <input type="text" name="delivery[addresses][][street]" id="delivery-address-1-street" value="">
232
- # #
233
- # # <button type="submit">Create</button>
234
- # # </form>
232
+ # <!-- output -->
233
+ # <form action="/deliveries" method="POST" accept-charset="utf-8" id="delivery-form">
234
+ # <input type="hidden" name="_csrf_token" value="920cd5bfaecc6e58368950e790f2f7b4e5561eeeab230aa1b7de1b1f40ea7d5d">
235
+ # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
236
+ # <input type="text" name="delivery[addresses][][street]" id="delivery-address-0-street" value="">
237
+ # <input type="text" name="delivery[addresses][][street]" id="delivery-address-1-street" value="">
235
238
  #
239
+ # <button type="submit">Create</button>
240
+ # </form>
236
241
  def fields_for_collection(name, &block)
237
242
  current_name = @name
238
243
  base_value = _value(name)
@@ -262,8 +267,17 @@ module Hanami
262
267
  # label :extended_title
263
268
  # %>
264
269
  #
265
- # # Output:
266
- # # <label for="book-extended-title">Extended title</label>
270
+ # <!-- output -->
271
+ # <label for="book-extended-title">Extended title</label>
272
+ #
273
+ # @example HTML attributes
274
+ # <%=
275
+ # # ...
276
+ # label :title, class: "form-label"
277
+ # %>
278
+ #
279
+ # <!-- output -->
280
+ # <label for="book-title" class="form-label">Title</label>
267
281
  #
268
282
  # @example Custom content
269
283
  # <%=
@@ -271,8 +285,8 @@ module Hanami
271
285
  # label 'Title', for: :extended_title
272
286
  # %>
273
287
  #
274
- # # Output:
275
- # # <label for="book-extended-title">Title</label>
288
+ # <!-- output -->
289
+ # <label for="book-extended-title">Title</label>
276
290
  #
277
291
  # @example Custom "for" attribute
278
292
  # <%=
@@ -280,8 +294,8 @@ module Hanami
280
294
  # label :extended_title, for: 'ext-title'
281
295
  # %>
282
296
  #
283
- # # Output:
284
- # # <label for="ext-title">Extended title</label>
297
+ # <!-- output -->
298
+ # <label for="ext-title">Extended title</label>
285
299
  #
286
300
  # @example Nested fields usage
287
301
  # <%=
@@ -292,9 +306,9 @@ module Hanami
292
306
  # end
293
307
  # %>
294
308
  #
295
- # # Output:
296
- # # <label for="delivery-address-city">City</label>
297
- # # <input type="text" name="delivery[address][city] id="delivery-address-city" value="">
309
+ # <!-- output -->
310
+ # <label for="delivery-address-city">City</label>
311
+ # <input type="text" name="delivery[address][city] id="delivery-address-city" value="">
298
312
  def label(content, attributes = {})
299
313
  attributes = { for: _for(content, attributes.delete(:for)) }.merge(attributes)
300
314
  content = case content
@@ -307,6 +321,37 @@ module Hanami
307
321
  super(content, attributes)
308
322
  end
309
323
 
324
+ # Fieldset
325
+ #
326
+ # @param content [Symbol,String,NilClass] the content
327
+ # @param attributes [Hash] HTML attributes to pass to the label tag
328
+ #
329
+ # @since 1.0.0.beta2
330
+ #
331
+ # @example Basic usage
332
+ # <%=
333
+ # # ...
334
+ # fieldset do
335
+ # legend "Author"
336
+ #
337
+ # fields_for :author do
338
+ # label :name
339
+ # text_field :name
340
+ # end
341
+ # end
342
+ # %>
343
+ #
344
+ # <!-- output -->
345
+ # <fieldset>
346
+ # <legend>Author</legend>
347
+ # <label for="book-author-name">Name</label>
348
+ # <input type="text" name="book[author][name]" id="book-author-name" value="">
349
+ # </fieldset>
350
+ def fieldset(content = nil, attributes = {})
351
+ # This is here only for documentation purposes
352
+ super
353
+ end
354
+
310
355
  # Check box
311
356
  #
312
357
  # It renders a check box input.
@@ -337,18 +382,27 @@ module Hanami
337
382
  # check_box :free_shipping
338
383
  # %>
339
384
  #
340
- # # Output:
341
- # # <input type="hidden" name="delivery[free_shipping]" value="0">
342
- # # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1">
385
+ # <!-- output -->
386
+ # <input type="hidden" name="delivery[free_shipping]" value="0">
387
+ # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1">
388
+ #
389
+ # @example HTML Attributes
390
+ # <%=
391
+ # check_box :free_shipping, class: "form-check-input"
392
+ # %>
393
+ #
394
+ # <!-- output -->
395
+ # <input type="hidden" name="delivery[free_shipping]" value="0">
396
+ # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" class="form-check-input">
343
397
  #
344
398
  # @example Specify (un)checked values
345
399
  # <%=
346
400
  # check_box :free_shipping, checked_value: 'true', unchecked_value: 'false'
347
401
  # %>
348
402
  #
349
- # # Output:
350
- # # <input type="hidden" name="delivery[free_shipping]" value="false">
351
- # # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="true">
403
+ # <!-- output -->
404
+ # <input type="hidden" name="delivery[free_shipping]" value="false">
405
+ # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="true">
352
406
  #
353
407
  # @example Automatic "checked" attribute
354
408
  # # For this example the params are:
@@ -358,9 +412,9 @@ module Hanami
358
412
  # check_box :free_shipping
359
413
  # %>
360
414
  #
361
- # # Output:
362
- # # <input type="hidden" name="delivery[free_shipping]" value="0">
363
- # # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
415
+ # <!-- output -->
416
+ # <input type="hidden" name="delivery[free_shipping]" value="0">
417
+ # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
364
418
  #
365
419
  # @example Force "checked" attribute
366
420
  # # For this example the params are:
@@ -370,9 +424,9 @@ module Hanami
370
424
  # check_box :free_shipping, checked: 'checked'
371
425
  # %>
372
426
  #
373
- # # Output:
374
- # # <input type="hidden" name="delivery[free_shipping]" value="0">
375
- # # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
427
+ # <!-- output -->
428
+ # <input type="hidden" name="delivery[free_shipping]" value="0">
429
+ # <input type="checkbox" name="delivery[free_shipping]" id="delivery-free-shipping" value="1" checked="checked">
376
430
  #
377
431
  # @example Multiple check boxes
378
432
  # <%=
@@ -380,9 +434,9 @@ module Hanami
380
434
  # check_box :languages, name: 'book[languages][]', value: 'english', id: nil
381
435
  # %>
382
436
  #
383
- # # Output:
384
- # # <input type="checkbox" name="book[languages][]" value="italian">
385
- # # <input type="checkbox" name="book[languages][]" value="english">
437
+ # <!-- output -->
438
+ # <input type="checkbox" name="book[languages][]" value="italian">
439
+ # <input type="checkbox" name="book[languages][]" value="english">
386
440
  #
387
441
  # @example Automatic "checked" attribute for multiple check boxes
388
442
  # # For this example the params are:
@@ -393,9 +447,9 @@ module Hanami
393
447
  # check_box :languages, name: 'book[languages][]', value: 'english', id: nil
394
448
  # %>
395
449
  #
396
- # # Output:
397
- # # <input type="checkbox" name="book[languages][]" value="italian" checked="checked">
398
- # # <input type="checkbox" name="book[languages][]" value="english">
450
+ # <!-- output -->
451
+ # <input type="checkbox" name="book[languages][]" value="italian" checked="checked">
452
+ # <input type="checkbox" name="book[languages][]" value="english">
399
453
  def check_box(name, attributes = {})
400
454
  _hidden_field_for_check_box(name, attributes)
401
455
  input _attributes_for_check_box(name, attributes)
@@ -414,8 +468,17 @@ module Hanami
414
468
  # color_field :background
415
469
  # %>
416
470
  #
417
- # # Output:
418
- # # <input type="color" name="user[background]" id="user-background" value="">
471
+ # <!-- output -->
472
+ # <input type="color" name="user[background]" id="user-background" value="">
473
+ #
474
+ # @example HTML Attributes
475
+ # <%=
476
+ # # ...
477
+ # color_field :background, class: "form-control"
478
+ # %>
479
+ #
480
+ # <!-- output -->
481
+ # <input type="color" name="user[background]" id="user-background" value="" class="form-control">
419
482
  def color_field(name, attributes = {})
420
483
  input _attributes(:color, name, attributes)
421
484
  end
@@ -433,8 +496,17 @@ module Hanami
433
496
  # date_field :birth_date
434
497
  # %>
435
498
  #
436
- # # Output:
437
- # # <input type="date" name="user[birth_date]" id="user-birth-date" value="">
499
+ # <!-- output -->
500
+ # <input type="date" name="user[birth_date]" id="user-birth-date" value="">
501
+ #
502
+ # @example HTML Attributes
503
+ # <%=
504
+ # # ...
505
+ # date_field :birth_date, class: "form-control"
506
+ # %>
507
+ #
508
+ # <!-- output -->
509
+ # <input type="date" name="user[birth_date]" id="user-birth-date" value="" class="form-control">
438
510
  def date_field(name, attributes = {})
439
511
  input _attributes(:date, name, attributes)
440
512
  end
@@ -452,8 +524,17 @@ module Hanami
452
524
  # datetime_field :delivered_at
453
525
  # %>
454
526
  #
455
- # # Output:
456
- # # <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
527
+ # <!-- output -->
528
+ # <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
529
+ #
530
+ # @example HTML Attributes
531
+ # <%=
532
+ # # ...
533
+ # datetime_field :delivered_at, class: "form-control"
534
+ # %>
535
+ #
536
+ # <!-- output -->
537
+ # <input type="datetime" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">
457
538
  def datetime_field(name, attributes = {})
458
539
  input _attributes(:datetime, name, attributes)
459
540
  end
@@ -471,12 +552,105 @@ module Hanami
471
552
  # datetime_local_field :delivered_at
472
553
  # %>
473
554
  #
474
- # # Output:
475
- # # <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
555
+ # <!-- output -->
556
+ # <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="">
557
+ #
558
+ # @example HTML Attributes
559
+ # <%=
560
+ # # ...
561
+ # datetime_local_field :delivered_at, class: "form-control"
562
+ # %>
563
+ #
564
+ # <!-- output -->
565
+ # <input type="datetime-local" name="delivery[delivered_at]" id="delivery-delivered-at" value="" class="form-control">
476
566
  def datetime_local_field(name, attributes = {})
477
567
  input _attributes(:'datetime-local', name, attributes)
478
568
  end
479
569
 
570
+ # Time field
571
+ #
572
+ # @param name [Symbol] the input name
573
+ # @param attributes [Hash] HTML attributes to pass to the input tag
574
+ #
575
+ # @since 1.0.0.beta2
576
+ #
577
+ # @example Basic usage
578
+ # <%=
579
+ # # ...
580
+ # time_field :release_hour
581
+ # %>
582
+ #
583
+ # <!-- output -->
584
+ # <input type="time" name="book[release_hour]" id="book-release-hour" value="">
585
+ #
586
+ # @example HTML Attributes
587
+ # <%=
588
+ # # ...
589
+ # time_field :release_hour, class: "form-control"
590
+ # %>
591
+ #
592
+ # <!-- output -->
593
+ # <input type="time" name="book[release_hour]" id="book-release-hour" value="" class="form-control">
594
+ def time_field(name, attributes = {})
595
+ input _attributes(:time, name, attributes)
596
+ end
597
+
598
+ # Month field
599
+ #
600
+ # @param name [Symbol] the input name
601
+ # @param attributes [Hash] HTML attributes to pass to the input tag
602
+ #
603
+ # @since 1.0.0.beta2
604
+ #
605
+ # @example Basic usage
606
+ # <%=
607
+ # # ...
608
+ # month_field :release_month
609
+ # %>
610
+ #
611
+ # <!-- output -->
612
+ # <input type="month" name="book[release_month]" id="book-release-month" value="">
613
+ #
614
+ # @example HTML Attributes
615
+ # <%=
616
+ # # ...
617
+ # month_field :release_month, class: "form-control"
618
+ # %>
619
+ #
620
+ # <!-- output -->
621
+ # <input type="month" name="book[release_month]" id="book-release-month" value="" class="form-control">
622
+ def month_field(name, attributes = {})
623
+ input _attributes(:month, name, attributes)
624
+ end
625
+
626
+ # Week field
627
+ #
628
+ # @param name [Symbol] the input name
629
+ # @param attributes [Hash] HTML attributes to pass to the input tag
630
+ #
631
+ # @since 1.0.0.beta2
632
+ #
633
+ # @example Basic usage
634
+ # <%=
635
+ # # ...
636
+ # week_field :release_week
637
+ # %>
638
+ #
639
+ # <!-- output -->
640
+ # <input type="week" name="book[release_week]" id="book-release-week" value="">
641
+ #
642
+ # @example HTML Attributes
643
+ # <%=
644
+ # # ...
645
+ # week_field :release_week, class: "form-control"
646
+ # %>
647
+ #
648
+ # <!-- output -->
649
+ # <input type="week" name="book[release_week]" id="book-release-week" value="" class="form-control">
650
+ def week_field(name, attributes = {})
651
+ input _attributes(:week, name, attributes)
652
+ end
653
+
480
654
  # Email input
481
655
  #
482
656
  # @param name [Symbol] the input name
@@ -490,12 +664,80 @@ module Hanami
490
664
  # email_field :email
491
665
  # %>
492
666
  #
493
- # # Output:
494
- # # <input type="email" name="user[email]" id="user-email" value="">
667
+ # <!-- output -->
668
+ # <input type="email" name="user[email]" id="user-email" value="">
669
+ #
670
+ # @example HTML Attributes
671
+ # <%=
672
+ # # ...
673
+ # email_field :email, class: "form-control"
674
+ # %>
675
+ #
676
+ # <!-- output -->
677
+ # <input type="email" name="user[email]" id="user-email" value="" class="form-control">
495
678
  def email_field(name, attributes = {})
496
679
  input _attributes(:email, name, attributes)
497
680
  end
498
681
 
682
+ # URL input
683
+ #
684
+ # @param name [Symbol] the input name
685
+ # @param attributes [Hash] HTML attributes to pass to the input tag
686
+ #
687
+ # @since 1.0.0.beta2
688
+ #
689
+ # @example Basic usage
690
+ # <%=
691
+ # # ...
692
+ # url_field :website
693
+ # %>
694
+ #
695
+ # <!-- output -->
696
+ # <input type="url" name="user[website]" id="user-website" value="">
697
+ #
698
+ # @example HTML Attributes
699
+ # <%=
700
+ # # ...
701
+ # url_field :website, class: "form-control"
702
+ # %>
703
+ #
704
+ # <!-- output -->
705
+ # <input type="url" name="user[website]" id="user-website" value="" class="form-control">
706
+ def url_field(name, attributes = {})
707
+ attrs = attributes.dup
708
+ attrs[:value] = escape_url(attrs.fetch(:value) { _value(name) })
709
+
710
+ input _attributes(:url, name, attrs)
711
+ end
712
+
713
+ # Telephone input
714
+ #
715
+ # @param name [Symbol] the input name
716
+ # @param attributes [Hash] HTML attributes to pass to the input tag
717
+ #
718
+ # @since 1.0.0.beta2
719
+ #
720
+ # @example Basic usage
721
+ # <%=
722
+ # # ...
723
+ # tel_field :telephone
724
+ # %>
725
+ #
726
+ # <!-- output -->
727
+ # <input type="tel" name="user[telephone]" id="user-telephone" value="">
728
+ #
729
+ # @example HTML Attributes
730
+ # <%=
731
+ # # ...
732
+ # telurl_field :telephone, class: "form-control"
733
+ # %>
734
+ #
735
+ # <!-- output -->
736
+ # <input type="tel" name="user[telephone]" id="user-telephone" value="" class="form-control">
737
+ def tel_field(name, attributes = {})
738
+ input _attributes(:tel, name, attributes)
739
+ end
740
+
499
741
  # Hidden input
500
742
  #
501
743
  # @param name [Symbol] the input name
@@ -509,15 +751,15 @@ module Hanami
509
751
  # hidden_field :customer_id
510
752
  # %>
511
753
  #
512
- # # Output:
513
- # # <input type="hidden" name="delivery[customer_id]" id="delivery-customer-id" value="">
754
+ # <!-- output -->
755
+ # <input type="hidden" name="delivery[customer_id]" id="delivery-customer-id" value="">
514
756
  def hidden_field(name, attributes = {})
515
757
  input _attributes(:hidden, name, attributes)
516
758
  end
517
759
 
518
760
  # File input
519
761
  #
520
- # PLEASE REMEMBER TO ADD <tt>enctype: 'multipart/form-data'</tt> ATTRIBUTE TO THE FORM
762
+ # **PLEASE REMEMBER TO ADD <tt>enctype: 'multipart/form-data'</tt> ATTRIBUTE TO THE FORM**
521
763
  #
522
764
  # @param name [Symbol] the input name
523
765
  # @param attributes [Hash] HTML attributes to pass to the input tag
@@ -532,26 +774,35 @@ module Hanami
532
774
  # file_field :avatar
533
775
  # %>
534
776
  #
535
- # # Output:
536
- # # <input type="file" name="user[avatar]" id="user-avatar">
777
+ # <!-- output -->
778
+ # <input type="file" name="user[avatar]" id="user-avatar">
537
779
  #
538
- # @example Accepted mime types
780
+ # @example HTML Attributes
781
+ # <%=
782
+ # # ...
783
+ # file_field :avatar, class: "avatar-upload"
784
+ # %>
785
+ #
786
+ # <!-- output -->
787
+ # <input type="file" name="user[avatar]" id="user-avatar" class="avatar-upload">
788
+ #
789
+ # @example Accepted MIME Types
539
790
  # <%=
540
791
  # # ...
541
792
  # file_field :resume, accept: 'application/pdf,application/ms-word'
542
793
  # %>
543
794
  #
544
- # # Output:
545
- # # <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
795
+ # <!-- output -->
796
+ # <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
546
797
  #
547
- # @example Accepted mime types (as array)
798
+ # @example Accepted MIME Types (as array)
548
799
  # <%=
549
800
  # # ...
550
801
  # file_field :resume, accept: ['application/pdf', 'application/ms-word']
551
802
  # %>
552
803
  #
553
- # # Output:
554
- # # <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
804
+ # <!-- output -->
805
+ # <input type="file" name="user[resume]" id="user-resume" accept="application/pdf,application/ms-word">
555
806
  #
556
807
  # @example Accepted multiple file upload (as array)
557
808
  # <%=
@@ -559,8 +810,8 @@ module Hanami
559
810
  # file_field :resume, multiple: true
560
811
  # %>
561
812
  #
562
- # # Output:
563
- # # <input type="file" name="user[resume]" id="user-resume" multiple="multiple">
813
+ # <!-- output -->
814
+ # <input type="file" name="user[resume]" id="user-resume" multiple="multiple">
564
815
  def file_field(name, attributes = {})
565
816
  attributes[:accept] = Array(attributes[:accept]).join(ACCEPT_SEPARATOR) if attributes.key?(:accept)
566
817
  attributes = { type: :file, name: _input_name(name), id: _input_id(name) }.merge(attributes)
@@ -570,6 +821,9 @@ module Hanami
570
821
 
571
822
  # Number input
572
823
  #
824
+ # You can also make use of the `max`, `min`, and `step` attributes for
825
+ # the HTML5 number field.
826
+ #
573
827
  # @param name [Symbol] the input name
574
828
  # @param attributes [Hash] HTML attributes to pass to the number input
575
829
  #
@@ -579,11 +833,8 @@ module Hanami
579
833
  # number_field :percent_read
580
834
  # %>
581
835
  #
582
- # # Output:
583
- # # <input type="number" name="book[percent_read]" id="book-percent-read" value="">
584
- #
585
- # You can also make use of the 'max', 'min', and 'step' attributes for
586
- # the HTML5 number field.
836
+ # <!-- output -->
837
+ # <input type="number" name="book[percent_read]" id="book-percent-read" value="">
587
838
  #
588
839
  # @example Advanced attributes
589
840
  # <%=
@@ -591,12 +842,43 @@ module Hanami
591
842
  # number_field :priority, min: 1, max: 10, step: 1
592
843
  # %>
593
844
  #
594
- # # Output:
595
- # # <input type="number" name="book[percent_read]" id="book-precent-read" value="" min="1" max="10" step="1">
845
+ # <!-- output -->
846
+ # <input type="number" name="book[percent_read]" id="book-precent-read" value="" min="1" max="10" step="1">
596
847
  def number_field(name, attributes = {})
597
848
  input _attributes(:number, name, attributes)
598
849
  end
599
850
 
851
+ # Range input
852
+ #
853
+ # You can also make use of the `max`, `min`, and `step` attributes for
854
+ # the HTML5 number field.
855
+ #
856
+ # @param name [Symbol] the input name
857
+ # @param attributes [Hash] HTML attributes to pass to the number input
858
+ #
859
+ # @since 1.0.0.beta2
860
+ #
861
+ # @example Basic usage
862
+ # <%=
863
+ # # ...
864
+ # range_field :discount_percentage
865
+ # %>
866
+ #
867
+ # <!-- output -->
868
+ # <input type="range" name="book[discount_percentage]" id="book-discount-percentage" value="">
869
+ #
870
+ # @example Advanced attributes
871
+ # <%=
872
+ # # ...
873
+ # range_field :discount_percentage, min: 1, max: 10, step: 1
874
+ # %>
875
+ #
876
+ # <!-- output -->
877
+ # <input type="number" name="book[discount_percentage]" id="book-discount-percentage" value="" min="1" max="10" step="1">
878
+ def range_field(name, attributes = {})
879
+ input _attributes(:range, name, attributes)
880
+ end
881
+
600
882
  # Text-area input
601
883
  #
602
884
  # @param name [Symbol] the input name
@@ -611,8 +893,8 @@ module Hanami
611
893
  # text_area :hobby
612
894
  # %>
613
895
  #
614
- # # Output:
615
- # # <textarea name="user[hobby]" id="user-hobby"></textarea>
896
+ # <!-- output -->
897
+ # <textarea name="user[hobby]" id="user-hobby"></textarea>
616
898
  #
617
899
  # @example Set content
618
900
  # <%=
@@ -620,8 +902,8 @@ module Hanami
620
902
  # text_area :hobby, 'Football'
621
903
  # %>
622
904
  #
623
- # # Output:
624
- # # <textarea name="user[hobby]" id="user-hobby">Football</textarea>
905
+ # <!-- output -->
906
+ # <textarea name="user[hobby]" id="user-hobby">Football</textarea>
625
907
  #
626
908
  # @example Set content and HTML attributes
627
909
  # <%=
@@ -629,8 +911,8 @@ module Hanami
629
911
  # text_area :hobby, 'Football', class: 'form-control'
630
912
  # %>
631
913
  #
632
- # # Output:
633
- # # <textarea name="user[hobby]" id="user-hobby" class="form-control">Football</textarea>
914
+ # <!-- output -->
915
+ # <textarea name="user[hobby]" id="user-hobby" class="form-control">Football</textarea>
634
916
  #
635
917
  # @example Omit content and specify HTML attributes
636
918
  # <%=
@@ -638,8 +920,8 @@ module Hanami
638
920
  # text_area :hobby, class: 'form-control'
639
921
  # %>
640
922
  #
641
- # # Output:
642
- # # <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
923
+ # <!-- output -->
924
+ # <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
643
925
  #
644
926
  # @example Force blank value
645
927
  # <%=
@@ -647,8 +929,8 @@ module Hanami
647
929
  # text_area :hobby, '', class: 'form-control'
648
930
  # %>
649
931
  #
650
- # # Output:
651
- # # <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
932
+ # <!-- output -->
933
+ # <textarea name="user[hobby]" id="user-hobby" class="form-control"></textarea>
652
934
  def text_area(name, content = nil, attributes = {})
653
935
  if content.respond_to?(:to_hash)
654
936
  attributes = content
@@ -672,13 +954,51 @@ module Hanami
672
954
  # text_field :first_name
673
955
  # %>
674
956
  #
675
- # # Output:
676
- # # <input type="text" name="user[first_name]" id="user-first-name" value="">
957
+ # <!-- output -->
958
+ # <input type="text" name="user[first_name]" id="user-first-name" value="">
959
+ #
960
+ # @example HTML Attributes
961
+ # <%=
962
+ # # ...
963
+ # text_field :first_name, class: "form-control"
964
+ # %>
965
+ #
966
+ # <!-- output -->
967
+ # <input type="text" name="user[first_name]" id="user-first-name" value="" class="form-control">
677
968
  def text_field(name, attributes = {})
678
969
  input _attributes(:text, name, attributes)
679
970
  end
680
971
  alias input_text text_field
681
972
 
973
+ # Search input
974
+ #
975
+ # @param name [Symbol] the input name
976
+ # @param attributes [Hash] HTML attributes to pass to the input tag
977
+ #
978
+ # @since 1.0.0.beta2
979
+ #
980
+ # @example Basic usage
981
+ # <%=
982
+ # # ...
983
+ # search_field :q
984
+ # %>
985
+ #
986
+ # <!-- output -->
987
+ # <input type="search" name="search[q]" id="search-q" value="">
988
+ #
989
+ # @example HTML Attributes
990
+ # <%=
991
+ # # ...
992
+ # search_field :q, class: "form-control"
993
+ # %>
994
+ #
995
+ # <!-- output -->
996
+ # <input type="search" name="search[q]" id="search-q" value="" class="form-control">
997
+ def search_field(name, attributes = {})
998
+ input _attributes(:search, name, attributes)
999
+ end
1000
+ alias input_text text_field
1001
+
682
1002
  # Radio input
683
1003
  #
684
1004
  # If request params have a value that corresponds to the given value,
@@ -698,9 +1018,20 @@ module Hanami
698
1018
  # radio_button :category, 'Non-Fiction'
699
1019
  # %>
700
1020
  #
701
- # # Output:
702
- # # <input type="radio" name="book[category]" value="Fiction">
703
- # # <input type="radio" name="book[category]" value="Non-Fiction">
1021
+ # <!-- output -->
1022
+ # <input type="radio" name="book[category]" value="Fiction">
1023
+ # <input type="radio" name="book[category]" value="Non-Fiction">
1024
+ #
1025
+ # @example HTML Attributes
1026
+ # <%=
1027
+ # # ...
1028
+ # radio_button :category, 'Fiction', class: "form-check"
1029
+ # radio_button :category, 'Non-Fiction', class: "form-check"
1030
+ # %>
1031
+ #
1032
+ # <!-- output -->
1033
+ # <input type="radio" name="book[category]" value="Fiction" class="form-check">
1034
+ # <input type="radio" name="book[category]" value="Non-Fiction" class="form-check">
704
1035
  #
705
1036
  # @example Automatic checked value
706
1037
  # # Given the following params:
@@ -715,9 +1046,9 @@ module Hanami
715
1046
  # radio_button :category, 'Non-Fiction'
716
1047
  # %>
717
1048
  #
718
- # # Output:
719
- # # <input type="radio" name="book[category]" value="Fiction">
720
- # # <input type="radio" name="book[category]" value="Non-Fiction" checked="checked">
1049
+ # <!-- output -->
1050
+ # <input type="radio" name="book[category]" value="Fiction">
1051
+ # <input type="radio" name="book[category]" value="Non-Fiction" checked="checked">
721
1052
  def radio_button(name, value, attributes = {})
722
1053
  attributes = { type: :radio, name: _input_name(name), value: value }.merge(attributes)
723
1054
  attributes[:checked] = CHECKED if _value(name).to_s == value.to_s
@@ -737,8 +1068,8 @@ module Hanami
737
1068
  # password_field :password
738
1069
  # %>
739
1070
  #
740
- # # Output:
741
- # # <input type="password" name="signup[password]" id="signup-password" value="">
1071
+ # <!-- output -->
1072
+ # <input type="password" name="signup[password]" id="signup-password" value="">
742
1073
  def password_field(name, attributes = {})
743
1074
  input({ type: :password, name: _input_name(name), id: _input_id(name), value: nil }.merge(attributes))
744
1075
  end
@@ -760,14 +1091,27 @@ module Hanami
760
1091
  # <%=
761
1092
  # # ...
762
1093
  # values = Hash['Italy' => 'it', 'United States' => 'us']
1094
+ # select :store, values, class: "form-control"
1095
+ # %>
1096
+ #
1097
+ # <!-- output -->
1098
+ # <select name="book[store]" id="book-store" class="form-control">
1099
+ # <option value="it">Italy</option>
1100
+ # <option value="us">United States</option>
1101
+ # </select>
1102
+ #
1103
+ # @example HTML Attributes
1104
+ # <%=
1105
+ # # ...
1106
+ # values = Hash['Italy' => 'it', 'United States' => 'us']
763
1107
  # select :store, values
764
1108
  # %>
765
1109
  #
766
- # # Output:
767
- # # <select name="book[store]" id="book-store">
768
- # # <option value="it">Italy</option>
769
- # # <option value="us">United States</option>
770
- # # </select>
1110
+ # <!-- output -->
1111
+ # <select name="book[store]" id="book-store">
1112
+ # <option value="it">Italy</option>
1113
+ # <option value="us">United States</option>
1114
+ # </select>
771
1115
  #
772
1116
  # @example Automatic selected option
773
1117
  # # Given the following params:
@@ -782,38 +1126,52 @@ module Hanami
782
1126
  # select :store, values
783
1127
  # %>
784
1128
  #
785
- # # Output:
786
- # # <select name="book[store]" id="book-store">
787
- # # <option value="it" selected="selected">Italy</option>
788
- # # <option value="us">United States</option>
789
- # # </select>
1129
+ # <!-- output -->
1130
+ # <select name="book[store]" id="book-store">
1131
+ # <option value="it" selected="selected">Italy</option>
1132
+ # <option value="us">United States</option>
1133
+ # </select>
790
1134
  #
791
1135
  # @example Prompt option
792
1136
  # <%=
793
1137
  # # ...
794
1138
  # values = Hash['it' => 'Italy', 'us' => 'United States']
795
- # select :store, values, options: {prompt: 'Select a store'}
1139
+ # select :store, values, options: { prompt: 'Select a store' }
796
1140
  # %>
797
1141
  #
798
- # # Output:
799
- # # <select name="book[store]" id="book-store">
800
- # # <option>Select a store</option>
801
- # # <option value="it">Italy</option>
802
- # # <option value="us">United States</option>
803
- # # </select>
1142
+ # <!-- output -->
1143
+ # <select name="book[store]" id="book-store">
1144
+ # <option>Select a store</option>
1145
+ # <option value="it">Italy</option>
1146
+ # <option value="us">United States</option>
1147
+ # </select>
804
1148
  #
805
1149
  # @example Selected option
806
1150
  # <%=
807
1151
  # # ...
808
1152
  # values = Hash['it' => 'Italy', 'us' => 'United States']
809
- # select :store, values, options: {selected: book.store}
1153
+ # select :store, values, options: { selected: book.store }
1154
+ # %>
1155
+ #
1156
+ # <!-- output -->
1157
+ # <select name="book[store]" id="book-store">
1158
+ # <option value="it" selected="selected">Italy</option>
1159
+ # <option value="us">United States</option>
1160
+ # </select>
1161
+ #
1162
+ # @example Prompt option and HTML attributes
1163
+ # <%=
1164
+ # # ...
1165
+ # values = Hash['it' => 'Italy', 'us' => 'United States']
1166
+ # select :store, values, options: { prompt: 'Select a store' }, class: "form-control"
810
1167
  # %>
811
1168
  #
812
- # # Output:
813
- # # <select name="book[store]" id="book-store">
814
- # # <option value="it" selected="selected">Italy</option>
815
- # # <option value="us">United States</option>
816
- # # </select>
1169
+ # <!-- output -->
1170
+ # <select name="book[store]" id="book-store" class="form-control">
1171
+ # <option>Select a store</option>
1172
+ # <option value="it">Italy</option>
1173
+ # <option value="us">United States</option>
1174
+ # </select>
817
1175
  #
818
1176
  # @example Multiple select
819
1177
  # <%=
@@ -822,11 +1180,24 @@ module Hanami
822
1180
  # select :stores, values, multiple: true
823
1181
  # %>
824
1182
  #
825
- # # Output:
826
- # # <select name="book[store][]" id="book-store" multiple="multiple">
827
- # # <option value="it">Italy</option>
828
- # # <option value="us">United States</option>
829
- # # </select>
1183
+ # <!-- output -->
1184
+ # <select name="book[store][]" id="book-store" multiple="multiple">
1185
+ # <option value="it">Italy</option>
1186
+ # <option value="us">United States</option>
1187
+ # </select>
1188
+ #
1189
+ # @example Multiple select and HTML attributes
1190
+ # <%=
1191
+ # # ...
1192
+ # values = Hash['it' => 'Italy', 'us' => 'United States']
1193
+ # select :stores, values, multiple: true, class: "form-control"
1194
+ # %>
1195
+ #
1196
+ # <!-- output -->
1197
+ # <select name="book[store][]" id="book-store" multiple="multiple" class="form-control">
1198
+ # <option value="it">Italy</option>
1199
+ # <option value="us">United States</option>
1200
+ # </select>
830
1201
  def select(name, values, attributes = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
831
1202
  options = attributes.delete(:options) { {} }
832
1203
  attributes = { name: _select_input_name(name, attributes[:multiple]), id: _input_id(name) }.merge(attributes)
@@ -862,12 +1233,12 @@ module Hanami
862
1233
  # datalist :stores, values, 'books'
863
1234
  # %>
864
1235
  #
865
- # # Output:
866
- # # <input type="text" name="book[store]" id="book-store" value="" list="books">
867
- # # <datalist id="books">
868
- # # <option value="Italy"></option>
869
- # # <option value="United States"></option>
870
- # # </datalist>
1236
+ # <!-- output -->
1237
+ # <input type="text" name="book[store]" id="book-store" value="" list="books">
1238
+ # <datalist id="books">
1239
+ # <option value="Italy"></option>
1240
+ # <option value="United States"></option>
1241
+ # </datalist>
871
1242
  #
872
1243
  # @example Options As Hash
873
1244
  # <%=
@@ -876,12 +1247,12 @@ module Hanami
876
1247
  # datalist :stores, values, 'books'
877
1248
  # %>
878
1249
  #
879
- # # Output:
880
- # # <input type="text" name="book[store]" id="book-store" value="" list="books">
881
- # # <datalist id="books">
882
- # # <option value="Italy">it</option>
883
- # # <option value="United States">us</option>
884
- # # </datalist>
1250
+ # <!-- output -->
1251
+ # <input type="text" name="book[store]" id="book-store" value="" list="books">
1252
+ # <datalist id="books">
1253
+ # <option value="Italy">it</option>
1254
+ # <option value="United States">us</option>
1255
+ # </datalist>
885
1256
  #
886
1257
  # @example Specify Custom Attributes For Datalist Input
887
1258
  # <%=
@@ -890,12 +1261,12 @@ module Hanami
890
1261
  # datalist :stores, values, 'books', datalist: { class: 'form-control' }
891
1262
  # %>
892
1263
  #
893
- # # Output:
894
- # # <input type="text" name="book[store]" id="book-store" value="" list="books">
895
- # # <datalist id="books" class="form-control">
896
- # # <option value="Italy"></option>
897
- # # <option value="United States"></option>
898
- # # </datalist>
1264
+ # <!-- output -->
1265
+ # <input type="text" name="book[store]" id="book-store" value="" list="books">
1266
+ # <datalist id="books" class="form-control">
1267
+ # <option value="Italy"></option>
1268
+ # <option value="United States"></option>
1269
+ # </datalist>
899
1270
  #
900
1271
  # @example Specify Custom Attributes For Options List
901
1272
  # <%=
@@ -904,12 +1275,12 @@ module Hanami
904
1275
  # datalist :stores, values, 'books', options: { class: 'form-control' }
905
1276
  # %>
906
1277
  #
907
- # # Output:
908
- # # <input type="text" name="book[store]" id="book-store" value="" list="books">
909
- # # <datalist id="books">
910
- # # <option value="Italy" class="form-control"></option>
911
- # # <option value="United States" class="form-control"></option>
912
- # # </datalist>
1278
+ # <!-- output -->
1279
+ # <input type="text" name="book[store]" id="book-store" value="" list="books">
1280
+ # <datalist id="books">
1281
+ # <option value="Italy" class="form-control"></option>
1282
+ # <option value="United States" class="form-control"></option>
1283
+ # </datalist>
913
1284
  def datalist(name, values, list, attributes = {}) # rubocop:disable Metrics/MethodLength
914
1285
  attrs = attributes.dup
915
1286
  options = attrs.delete(:options) || {}
@@ -926,6 +1297,71 @@ module Hanami
926
1297
  end
927
1298
  end
928
1299
 
1300
+ # Button
1301
+ #
1302
+ # @param content [String] The content
1303
+ # @param attributes [Hash] HTML attributes to pass to the button tag
1304
+ #
1305
+ # @since 1.0.0.beta2
1306
+ #
1307
+ # @example Basic usage
1308
+ # <%=
1309
+ # # ...
1310
+ # button 'Click me'
1311
+ # %>
1312
+ #
1313
+ # <!-- output -->
1314
+ # <button>Click me</button>
1315
+ #
1316
+ # @example HTML Attributes
1317
+ # <%=
1318
+ # # ...
1319
+ # button 'Click me', class: "btn btn-secondary"
1320
+ # %>
1321
+ #
1322
+ # <!-- output -->
1323
+ # <button class="btn btn-secondary">Click me</button>
1324
+ def button(content, attributes = {})
1325
+ # This is here only for documentation purposes
1326
+ super
1327
+ end
1328
+
1329
+ # Image button
1330
+ #
1331
+ # Visual submit button
1332
+ #
1333
+ # **Please note:** for security reasons, please use the absolute URL of the image
1334
+ #
1335
+ # @param source [String] The **absolute URL** of the image
1336
+ # @param attributes [Hash] HTML attributes to pass to the button tag
1337
+ #
1338
+ # @since 1.0.0.beta2
1339
+ #
1340
+ # @example Basic usage
1341
+ # <%=
1342
+ # # ...
1343
+ # image_button "https://hanamirb.org/assets/button.png"
1344
+ # %>
1345
+ #
1346
+ # <!-- output -->
1347
+ # <input type="image" src="https://hanamirb.org/assets/button.png">
1348
+ #
1349
+ # @example HTML Attributes
1350
+ # <%=
1351
+ # # ...
1352
+ # image_button "https://hanamirb.org/assets/button.png", name: "image", width: "50"
1353
+ # %>
1354
+ #
1355
+ # <!-- output -->
1356
+ # <input name="image" width="50" type="image" src="https://hanamirb.org/assets/button.png">
1357
+ def image_button(source, attributes = {})
1358
+ attrs = attributes.dup
1359
+ attrs[:type] = :image
1360
+ attrs[:src] = escape_url(source)
1361
+
1362
+ input attrs
1363
+ end
1364
+
929
1365
  # Submit button
930
1366
  #
931
1367
  # @param content [String] The content
@@ -939,8 +1375,17 @@ module Hanami
939
1375
  # submit 'Create'
940
1376
  # %>
941
1377
  #
942
- # # Output:
943
- # # <button type="submit">Create</button>
1378
+ # <!-- output -->
1379
+ # <button type="submit">Create</button>
1380
+ #
1381
+ # @example HTML Attributes
1382
+ # <%=
1383
+ # # ...
1384
+ # submit 'Create', class: "btn btn-primary"
1385
+ # %>
1386
+ #
1387
+ # <!-- output -->
1388
+ # <button type="submit" class="btn btn-primary">Create</button>
944
1389
  def submit(content, attributes = {})
945
1390
  attributes = { type: :submit }.merge(attributes)
946
1391
  button(content, attributes)
@@ -1001,7 +1446,7 @@ module Hanami
1001
1446
  def _attributes(type, name, attributes)
1002
1447
  attrs = { type: type, name: _displayed_input_name(name), id: _input_id(name), value: _value(name) }
1003
1448
  attrs.merge!(attributes)
1004
- attrs[:value] = Hanami::Utils::Escape.html(attrs[:value])
1449
+ attrs[:value] = escape_html(attrs[:value])
1005
1450
  attrs
1006
1451
  end
1007
1452
 
@@ -1089,6 +1534,7 @@ module Hanami
1089
1534
  attributes
1090
1535
  end
1091
1536
 
1537
+ # @api private
1092
1538
  def _select_input_name(name, multiple)
1093
1539
  select_name = _input_name(name)
1094
1540
  select_name = "#{select_name}[]" if multiple
@@ -1097,6 +1543,8 @@ module Hanami
1097
1543
 
1098
1544
  # TODO: this has to be refactored
1099
1545
  #
1546
+ # @api private
1547
+ #
1100
1548
  # rubocop:disable Metrics/CyclomaticComplexity
1101
1549
  # rubocop:disable Metrics/PerceivedComplexity
1102
1550
  def _select_option_selected?(value, selected, input_value, multiple)
@@ -1106,6 +1554,7 @@ module Hanami
1106
1554
  # rubocop:enable Metrics/PerceivedComplexity
1107
1555
  # rubocop:enable Metrics/CyclomaticComplexity
1108
1556
 
1557
+ # @api private
1109
1558
  def _check_box_checked?(value, input_value)
1110
1559
  !input_value.nil? &&
1111
1560
  (input_value.to_s == value.to_s || input_value.is_a?(TrueClass) ||