padrino-helpers 0.10.5 → 0.10.6.a
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/lib/padrino-helpers/asset_tag_helpers.rb +3 -3
- data/lib/padrino-helpers/form_builder/abstract_form_builder.rb +31 -0
- data/lib/padrino-helpers/form_helpers.rb +206 -19
- data/lib/padrino-helpers/format_helpers.rb +2 -2
- data/lib/padrino-helpers/tag_helpers.rb +160 -47
- data/test/fixtures/markup_app/views/form_for.erb +20 -4
- data/test/fixtures/markup_app/views/form_for.haml +15 -3
- data/test/fixtures/markup_app/views/form_for.slim +15 -3
- data/test/fixtures/markup_app/views/form_tag.erb +30 -0
- data/test/fixtures/markup_app/views/form_tag.haml +25 -0
- data/test/fixtures/markup_app/views/form_tag.slim +25 -0
- data/test/test_asset_tag_helpers.rb +0 -5
- data/test/test_form_builder.rb +114 -4
- data/test/test_form_helpers.rb +132 -7
- data/test/test_format_helpers.rb +2 -2
- data/test/test_tag_helpers.rb +4 -22
- metadata +32 -9
@@ -153,7 +153,7 @@ module Padrino
|
|
153
153
|
# @api public
|
154
154
|
def feed_tag(mime, url, options={})
|
155
155
|
full_mime = (mime == :atom) ? 'application/atom+xml' : 'application/rss+xml'
|
156
|
-
|
156
|
+
tag(:link, options.reverse_merge(:rel => 'alternate', :type => full_mime, :title => mime, :href => url))
|
157
157
|
end
|
158
158
|
|
159
159
|
##
|
@@ -291,9 +291,9 @@ module Padrino
|
|
291
291
|
# @api public
|
292
292
|
def javascript_include_tag(*sources)
|
293
293
|
options = sources.extract_options!.symbolize_keys
|
294
|
-
options.reverse_merge!(:type => 'text/javascript'
|
294
|
+
options.reverse_merge!(:type => 'text/javascript')
|
295
295
|
sources.flatten.map { |source|
|
296
|
-
|
296
|
+
content_tag(:script, nil, options.reverse_merge(:src => asset_path(:js, source)))
|
297
297
|
}.join("\n")
|
298
298
|
end
|
299
299
|
|
@@ -42,6 +42,37 @@ module Padrino
|
|
42
42
|
@template.text_field_tag field_name(field), options
|
43
43
|
end
|
44
44
|
|
45
|
+
def number_field(field, options={})
|
46
|
+
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
47
|
+
options.merge!(:class => field_error(field, options))
|
48
|
+
@template.number_field_tag field_name(field), options
|
49
|
+
end
|
50
|
+
|
51
|
+
def telephone_field(field, options={})
|
52
|
+
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
53
|
+
options.merge!(:class => field_error(field, options))
|
54
|
+
@template.telephone_field_tag field_name(field), options
|
55
|
+
end
|
56
|
+
alias_method :phone_field, :telephone_field
|
57
|
+
|
58
|
+
def email_field(field, options={})
|
59
|
+
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
60
|
+
options.merge!(:class => field_error(field, options))
|
61
|
+
@template.email_field_tag field_name(field), options
|
62
|
+
end
|
63
|
+
|
64
|
+
def search_field(field, options={})
|
65
|
+
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
66
|
+
options.merge!(:class => field_error(field, options))
|
67
|
+
@template.search_field_tag field_name(field), options
|
68
|
+
end
|
69
|
+
|
70
|
+
def url_field(field, options={})
|
71
|
+
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
72
|
+
options.merge!(:class => field_error(field, options))
|
73
|
+
@template.url_field_tag field_name(field), options
|
74
|
+
end
|
75
|
+
|
45
76
|
# f.text_area :summary, :value => "(enter summary)", :id => 'summary'
|
46
77
|
def text_area(field, options={})
|
47
78
|
options.reverse_merge!(:value => field_value(field), :id => field_id(field))
|
@@ -140,9 +140,9 @@ module Padrino
|
|
140
140
|
# @param [Hash] options Error message display options.
|
141
141
|
# @option options [String] :header_tag ("h2")
|
142
142
|
# Used for the header of the error div
|
143
|
-
# @option options [String] :id ("
|
143
|
+
# @option options [String] :id ("field-errors")
|
144
144
|
# The id of the error div.
|
145
|
-
# @option options [String] :class ("
|
145
|
+
# @option options [String] :class ("field-errors")
|
146
146
|
# The class of the error div.
|
147
147
|
# @option options [Array<Object>] :object
|
148
148
|
# The object (or array of objects) for which to display errors,
|
@@ -222,7 +222,7 @@ module Padrino
|
|
222
222
|
# The field on the +object+ to display the error for.
|
223
223
|
# @param [Hash] options
|
224
224
|
# The options to control the error display.
|
225
|
-
# @option options [String] :tag ("
|
225
|
+
# @option options [String] :tag ("span")
|
226
226
|
# The tag that encloses the error.
|
227
227
|
# @option options [String] :prepend ("")
|
228
228
|
# The text to prepend before the field error.
|
@@ -289,29 +289,216 @@ module Padrino
|
|
289
289
|
end
|
290
290
|
|
291
291
|
##
|
292
|
-
#
|
292
|
+
# Creates a text field input with the given name and options
|
293
293
|
#
|
294
|
-
# @macro [new]
|
295
|
-
# @param [
|
296
|
-
# The name of the input
|
294
|
+
# @macro [new] text_field
|
295
|
+
# @param [Symbol] name
|
296
|
+
# The name of the input to create.
|
297
297
|
# @param [Hash] options
|
298
|
-
# The
|
299
|
-
#
|
300
|
-
# @
|
298
|
+
# The HTML options to include in this field.
|
299
|
+
#
|
300
|
+
# @option options [String] :id
|
301
|
+
# Specifies a unique identifier for the field.
|
302
|
+
# @option options [String] :class
|
303
|
+
# Specifies the stylesheet class of the field.
|
304
|
+
# @option options [String] :name
|
305
|
+
# Specifies the name of the field.
|
306
|
+
# @option options [String] :accesskey
|
307
|
+
# Specifies a shortcut key to access the field.
|
308
|
+
# @option options [Integer] :tabindex
|
309
|
+
# Specifies the tab order of the field.
|
310
|
+
# @option options [Integer] :maxlength
|
311
|
+
# Specifies the maximum length, in characters, of the field.
|
312
|
+
# @option options [Integer] :size
|
313
|
+
# Specifies the width, in characters, of the field.
|
314
|
+
# @option options [String] :placeholder
|
315
|
+
# Specifies a short hint that describes the expected value of the field.
|
316
|
+
# @option options [Boolean] :hidden
|
317
|
+
# Specifies whether or not the field is hidden from view.
|
318
|
+
# @option options [Boolean] :spellcheck
|
319
|
+
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
320
|
+
# @option options [Boolean] :draggable
|
321
|
+
# Specifies whether or not the field is draggable. (true, false, :auto)
|
322
|
+
# @option options [String] :pattern
|
323
|
+
# Specifies the regular expression pattern that the field's value is checked against.
|
324
|
+
# @option options [Symbol] :autocomplete
|
325
|
+
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
326
|
+
# @option options [Boolean] :autofocus
|
327
|
+
# Specifies whether or not the field should automatically get focus when the page loads.
|
328
|
+
# @option options [Boolean] :required
|
329
|
+
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
330
|
+
# @option options [Boolean] :readonly
|
331
|
+
# Specifies whether or not the field is read only.
|
332
|
+
# @option options [Boolean] :disabled
|
333
|
+
# Specifies whether or not the field is disabled.
|
334
|
+
#
|
335
|
+
# @return [String]
|
336
|
+
# Generated HTML with specified +options+
|
301
337
|
#
|
302
338
|
# @example
|
303
|
-
# text_field_tag :
|
339
|
+
# text_field_tag :first_name, :maxlength => 40, :required => true
|
340
|
+
# # => <input name="first_name" maxlength="40" required type="text">
|
341
|
+
#
|
342
|
+
# text_field_tag :last_name, :class => 'string', :size => 40
|
343
|
+
# # => <input name="last_name" class="string" size="40" type="text">
|
344
|
+
#
|
345
|
+
# text_field_tag :username, :placeholder => 'Your Username'
|
346
|
+
# # => <input name="username" placeholder="Your Username" type="text">
|
304
347
|
#
|
305
348
|
# @api public
|
306
349
|
def text_field_tag(name, options={})
|
307
|
-
options.reverse_merge!(:name => name)
|
308
|
-
|
350
|
+
input_tag(:text, options.reverse_merge!(:name => name))
|
351
|
+
end
|
352
|
+
|
353
|
+
##
|
354
|
+
# Creates a number field input with the given name and options
|
355
|
+
#
|
356
|
+
# @macro [new] number_field
|
357
|
+
# @param [Symbol] name
|
358
|
+
# The name of the input to create.
|
359
|
+
# @param [Hash] options
|
360
|
+
# The HTML options to include in this field.
|
361
|
+
#
|
362
|
+
# @option options [String] :id
|
363
|
+
# Specifies a unique identifier for the field.
|
364
|
+
# @option options [String] :class
|
365
|
+
# Specifies the stylesheet class of the field.
|
366
|
+
# @option options [String] :name
|
367
|
+
# Specifies the name of the field.
|
368
|
+
# @option options [String] :accesskey
|
369
|
+
# Specifies a shortcut key to access the field.
|
370
|
+
# @option options [Integer] :tabindex
|
371
|
+
# Specifies the tab order of the field.
|
372
|
+
# @option options [Integer] :min
|
373
|
+
# Specifies the minimum value of the field.
|
374
|
+
# @option options [Integer] :max
|
375
|
+
# Specifies the maximum value of the field.
|
376
|
+
# @option options [Integer] :step
|
377
|
+
# Specifies the legal number intervals of the field.
|
378
|
+
# @option options [Boolean] :hidden
|
379
|
+
# Specifies whether or not the field is hidden from view.
|
380
|
+
# @option options [Boolean] :spellcheck
|
381
|
+
# Specifies whether or not the field should have it's spelling and grammar checked for errors.
|
382
|
+
# @option options [Boolean] :draggable
|
383
|
+
# Specifies whether or not the field is draggable. (true, false, :auto)
|
384
|
+
# @option options [String] :pattern
|
385
|
+
# Specifies the regular expression pattern that the field's value is checked against.
|
386
|
+
# @option options [Symbol] :autocomplete
|
387
|
+
# Specifies whether or not the field should have autocomplete enabled. (:on, :off)
|
388
|
+
# @option options [Boolean] :autofocus
|
389
|
+
# Specifies whether or not the field should automatically get focus when the page loads.
|
390
|
+
# @option options [Boolean] :required
|
391
|
+
# Specifies whether or not the field is required to be completeled before the form is submitted.
|
392
|
+
# @option options [Boolean] :readonly
|
393
|
+
# Specifies whether or not the field is read only.
|
394
|
+
# @option options [Boolean] :disabled
|
395
|
+
# Specifies whether or not the field is disabled.
|
396
|
+
#
|
397
|
+
# @return [String]
|
398
|
+
# Generated HTML with specified +options+
|
399
|
+
#
|
400
|
+
# @example
|
401
|
+
# number_field_tag :quanity, :class => 'numeric'
|
402
|
+
# # => <input name="quanity" class="numeric" type="number">
|
403
|
+
#
|
404
|
+
# number_field_tag :zip_code, :pattern => /[0-9]{5}/
|
405
|
+
# # => <input name="zip_code" pattern="[0-9]{5}" type="number">
|
406
|
+
#
|
407
|
+
# number_field_tag :credit_card, :autocomplete => :off
|
408
|
+
# # => <input name="credit_card" autocomplete="off" type="number">
|
409
|
+
#
|
410
|
+
# number_field_tag :age, :min => 18, :max => 120, :step => 1
|
411
|
+
# # => <input name="age" min="18" max="120" step="1" type="number">
|
412
|
+
#
|
413
|
+
# @api public
|
414
|
+
def number_field_tag(name, options={})
|
415
|
+
input_tag(:number, options.reverse_merge(:name => name))
|
416
|
+
end
|
417
|
+
|
418
|
+
##
|
419
|
+
# Creates a telephone field input with the given name and options
|
420
|
+
#
|
421
|
+
# @macro text_field
|
422
|
+
#
|
423
|
+
# @example
|
424
|
+
# telephone_field_tag :phone_number, :class => 'string'
|
425
|
+
# # => <input name="phone_number" class="string" type="tel">
|
426
|
+
#
|
427
|
+
# telephone_field_tag :cell_phone, :tabindex => 1
|
428
|
+
# telephone_field_tag :work_phone, :tabindex => 2
|
429
|
+
# telephone_field_tag :home_phone, :tabindex => 3
|
430
|
+
#
|
431
|
+
# # => <input name="cell_phone" tabindex="1" type="tel">
|
432
|
+
# # => <input name="work_phone" tabindex="2" type="tel">
|
433
|
+
# # => <input name="home_phone" tabindex="3" type="tel">
|
434
|
+
#
|
435
|
+
# @api public
|
436
|
+
def telephone_field_tag(name, options={})
|
437
|
+
input_tag(:tel, options.reverse_merge(:name => name))
|
438
|
+
end
|
439
|
+
alias_method :phone_field_tag, :telephone_field_tag
|
440
|
+
|
441
|
+
##
|
442
|
+
# Creates an email field input with the given name and options
|
443
|
+
#
|
444
|
+
# @macro text_field
|
445
|
+
#
|
446
|
+
# @example
|
447
|
+
# email_field_tag :email, :placeholder => 'you@example.com'
|
448
|
+
# # => <input name="email" placeholder="you@example.com" type="email">
|
449
|
+
#
|
450
|
+
# email_field_tag :email, :value => 'padrinorb@gmail.com', :readonly => true
|
451
|
+
# # => <input name="email" value="padrinorb@gmail.com" readonly type="email">
|
452
|
+
#
|
453
|
+
# @api public
|
454
|
+
def email_field_tag(name, options={})
|
455
|
+
input_tag(:email, options.reverse_merge(:name => name))
|
456
|
+
end
|
457
|
+
|
458
|
+
##
|
459
|
+
# Creates a search field input with the given name and options
|
460
|
+
#
|
461
|
+
# @macro text_field
|
462
|
+
#
|
463
|
+
# @example
|
464
|
+
# search_field_tag :search, :placeholder => 'Search this website...'
|
465
|
+
# # => <input name="search" placeholder="Search this website..." type="search">
|
466
|
+
#
|
467
|
+
# search_field_tag :search, :maxlength => 15, :class => ['search', 'string']
|
468
|
+
# # => <input name="search" maxlength="15" class="search string">
|
469
|
+
#
|
470
|
+
# search_field_tag :search, :id => 'search'
|
471
|
+
# # => <input name="search" id="search" type="search">
|
472
|
+
#
|
473
|
+
# search_field_tag :search, :autofocus => true
|
474
|
+
# # => <input name="search" autofocus type="search">
|
475
|
+
#
|
476
|
+
# @api public
|
477
|
+
def search_field_tag(name, options={})
|
478
|
+
input_tag(:search, options.reverse_merge(:name => name))
|
479
|
+
end
|
480
|
+
|
481
|
+
##
|
482
|
+
# Creates a url field input with the given name and options
|
483
|
+
#
|
484
|
+
# @macro text_field
|
485
|
+
#
|
486
|
+
# @example
|
487
|
+
# url_field_tag :favorite_website, :placeholder => 'http://padrinorb.com'
|
488
|
+
# <input name="favorite_website" placeholder="http://padrinorb.com." type="url">
|
489
|
+
#
|
490
|
+
# url_field_tag :home_page, :class => 'string url'
|
491
|
+
# <input name="home_page" class="string url", type="url">
|
492
|
+
#
|
493
|
+
# @api public
|
494
|
+
def url_field_tag(name, options={})
|
495
|
+
input_tag(:url, options.reverse_merge(:name => name))
|
309
496
|
end
|
310
497
|
|
311
498
|
##
|
312
499
|
# Constructs a hidden field input from the given options
|
313
500
|
#
|
314
|
-
# @macro
|
501
|
+
# @macro text_field
|
315
502
|
#
|
316
503
|
# @example
|
317
504
|
# hidden_field_tag :session_key, :value => "__secret__"
|
@@ -325,7 +512,7 @@ module Padrino
|
|
325
512
|
##
|
326
513
|
# Constructs a text area input from the given options
|
327
514
|
#
|
328
|
-
# @macro
|
515
|
+
# @macro text_field
|
329
516
|
#
|
330
517
|
# @example
|
331
518
|
# text_area_tag :username, :class => 'long', :value => "Demo?"
|
@@ -339,7 +526,7 @@ module Padrino
|
|
339
526
|
##
|
340
527
|
# Constructs a password field input from the given options
|
341
528
|
#
|
342
|
-
# @macro
|
529
|
+
# @macro text_field
|
343
530
|
#
|
344
531
|
# @example
|
345
532
|
# password_field_tag :password, :class => 'long'
|
@@ -353,7 +540,7 @@ module Padrino
|
|
353
540
|
##
|
354
541
|
# Constructs a check_box from the given options
|
355
542
|
#
|
356
|
-
# @macro
|
543
|
+
# @macro text_field
|
357
544
|
#
|
358
545
|
# @example
|
359
546
|
# check_box_tag :remember_me, :value => 'Yes'
|
@@ -367,7 +554,7 @@ module Padrino
|
|
367
554
|
##
|
368
555
|
# Constructs a radio_button from the given options
|
369
556
|
#
|
370
|
-
# @macro
|
557
|
+
# @macro text_field
|
371
558
|
#
|
372
559
|
# @example
|
373
560
|
# radio_button_tag :remember_me, :value => 'true'
|
@@ -381,7 +568,7 @@ module Padrino
|
|
381
568
|
##
|
382
569
|
# Constructs a file field input from the given options
|
383
570
|
#
|
384
|
-
# @macro
|
571
|
+
# @macro text_field
|
385
572
|
#
|
386
573
|
# @example
|
387
574
|
# file_field_tag :photo, :class => 'long'
|
@@ -81,11 +81,11 @@ module Padrino
|
|
81
81
|
# @api public
|
82
82
|
def simple_format(text, options={})
|
83
83
|
t = options.delete(:tag) || :p
|
84
|
-
start_tag = tag(t, options
|
84
|
+
start_tag = tag(t, options)
|
85
85
|
text = text.to_s.dup
|
86
86
|
text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
|
87
87
|
text.gsub!(/\n\n+/, "</#{t}>\n\n#{start_tag}") # 2+ newline -> paragraph
|
88
|
-
text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br
|
88
|
+
text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br>') # 1 newline -> br
|
89
89
|
text.insert 0, start_tag
|
90
90
|
text << "</#{t}>"
|
91
91
|
end
|
@@ -2,99 +2,212 @@ module Padrino
|
|
2
2
|
module Helpers
|
3
3
|
##
|
4
4
|
# Helpers related to producing html tags within templates.
|
5
|
-
|
5
|
+
##
|
6
6
|
module TagHelpers
|
7
7
|
##
|
8
8
|
# Tag values escaped to html entities
|
9
|
-
|
9
|
+
##
|
10
10
|
ESCAPE_VALUES = {
|
11
11
|
"<" => "<",
|
12
12
|
">" => ">",
|
13
13
|
'"' => """
|
14
14
|
}
|
15
15
|
|
16
|
+
BOOLEAN_ATTRIBUTES = [
|
17
|
+
:autoplay,
|
18
|
+
:autofocus,
|
19
|
+
:formnovalidate,
|
20
|
+
:checked,
|
21
|
+
:disabled,
|
22
|
+
:hidden,
|
23
|
+
:loop,
|
24
|
+
:multiple,
|
25
|
+
:muted,
|
26
|
+
:readonly,
|
27
|
+
:required,
|
28
|
+
:selected
|
29
|
+
]
|
30
|
+
|
16
31
|
##
|
17
|
-
# Creates an
|
32
|
+
# Creates an HTML tag with given name, content, and options
|
18
33
|
#
|
19
|
-
# @overload content_tag(name, content, options)
|
20
|
-
# @param [Symbol]
|
21
|
-
#
|
22
|
-
# @param [
|
23
|
-
#
|
24
|
-
# @param [
|
25
|
-
#
|
26
|
-
# @param [Proc] block The block returning html content
|
34
|
+
# @overload content_tag(name, content, options = nil)
|
35
|
+
# @param [Symbol] name
|
36
|
+
# The name of the HTML tag to create.
|
37
|
+
# @param [String] content
|
38
|
+
# The content inside of the the tag.
|
39
|
+
# @param [Hash] options
|
40
|
+
# The HTML options to include in this tag.
|
27
41
|
#
|
28
|
-
# @
|
42
|
+
# @overload content_tag(name, options = nil, &block)
|
43
|
+
# @param [Symbol] name
|
44
|
+
# The name of the HTML tag to create.
|
45
|
+
# @param [Hash] options
|
46
|
+
# The HTML options to include in this tag.
|
47
|
+
# @param [Proc] block
|
48
|
+
# The block returning HTML content.
|
49
|
+
#
|
50
|
+
# @macro [new] global_html_attributes
|
51
|
+
# @option options [String] :id
|
52
|
+
# Specifies a unique identifier for the element.
|
53
|
+
# @option options [String] :class
|
54
|
+
# Specifies the stylesheet class of the element.
|
55
|
+
# @option options [String] :title
|
56
|
+
# Specifies the title for the element.
|
57
|
+
# @option options [String] :accesskey
|
58
|
+
# Specifies a shortcut key to access the element.
|
59
|
+
# @option options [Symbol] :dropzone
|
60
|
+
# Specifies what happens when dragged items are dropped on the element. (:copy, :link, :move)
|
61
|
+
# @option options [Boolean] :hidden
|
62
|
+
# Specifies whether or not the element is hidden from view.
|
63
|
+
# @option options [Boolean] :draggable
|
64
|
+
# Specifies whether or not the element is draggable. (true, false, :auto)
|
65
|
+
# @option options [Boolean] :contenteditable
|
66
|
+
# Specifies whether or not the element is editable.
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
# Generated HTML with specified +options+
|
29
70
|
#
|
30
71
|
# @example
|
31
|
-
# content_tag(:p,
|
32
|
-
#
|
72
|
+
# content_tag(:p, 'Hello World', :class => 'light')
|
73
|
+
#
|
74
|
+
# # => <p class="light">
|
75
|
+
# # => Hello World
|
76
|
+
# # => </p>
|
77
|
+
#
|
78
|
+
# content_tag(:p, :class => 'dark') do
|
79
|
+
# link_to 'Padrino', 'http://www.padrinorb.com'
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# # => <p class="dark">
|
83
|
+
# # => <a href="http://www.padrinorb.com">Padrino</a>
|
84
|
+
# # => </p>
|
33
85
|
#
|
34
86
|
# @api public
|
35
|
-
def content_tag(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
87
|
+
def content_tag(name, content = nil, options = nil, &block)
|
88
|
+
if block_given?
|
89
|
+
options = content if content.is_a?(Hash)
|
90
|
+
content = capture_html(&block)
|
91
|
+
end
|
92
|
+
|
93
|
+
content = content.join("\n") if content.respond_to?(:join)
|
94
|
+
|
95
|
+
output = "<#{name}#{tag_options(options) if options}>#{content}</#{name}>"
|
96
|
+
block_is_template?(block) ? concat_content(output) : output
|
41
97
|
end
|
42
98
|
|
43
99
|
##
|
44
|
-
# Creates an
|
100
|
+
# Creates an HTML input field with the given type and options
|
45
101
|
#
|
46
102
|
# @param [Symbol] type
|
47
|
-
# The
|
103
|
+
# The type of input to create.
|
48
104
|
# @param [Hash] options
|
49
|
-
# The
|
105
|
+
# The HTML options to include in this input.
|
50
106
|
#
|
51
|
-
# @
|
107
|
+
# @option options [String] :id
|
108
|
+
# Specifies a unique identifier for the input.
|
109
|
+
# @option options [String] :class
|
110
|
+
# Specifies the stylesheet class of the input.
|
111
|
+
# @option options [String] :name
|
112
|
+
# Specifies the name of the input.
|
113
|
+
# @option options [String] :accesskey
|
114
|
+
# Specifies a shortcut key to access the input.
|
115
|
+
# @option options [Integer] :tabindex
|
116
|
+
# Specifies the tab order of the input.
|
117
|
+
# @option options [Boolean] :hidden
|
118
|
+
# Specifies whether or not the input is hidden from view.
|
119
|
+
# @option options [Boolean] :spellcheck
|
120
|
+
# Specifies whether or not the input should have it's spelling and grammar checked for errors.
|
121
|
+
# @option options [Boolean] :draggable
|
122
|
+
# Specifies whether or not the input is draggable. (true, false, :auto)
|
123
|
+
# @option options [String] :pattern
|
124
|
+
# Specifies the regular expression pattern that the input's value is checked against.
|
125
|
+
# @option options [Symbol] :autocomplete
|
126
|
+
# Specifies whether or not the input should have autocomplete enabled. (:on, :off)
|
127
|
+
# @option options [Boolean] :autofocus
|
128
|
+
# Specifies whether or not the input should automatically get focus when the page loads.
|
129
|
+
# @option options [Boolean] :required
|
130
|
+
# Specifies whether or not the input is required to be completeled before the form is submitted.
|
131
|
+
# @option options [Boolean] :readonly
|
132
|
+
# Specifies whether or not the input is read only.
|
133
|
+
# @option options [Boolean] :disabled
|
134
|
+
# Specifies whether or not the input is disabled.
|
135
|
+
#
|
136
|
+
# @return [String]
|
137
|
+
# Generated HTML with specified +options+
|
52
138
|
#
|
53
139
|
# @example
|
54
|
-
# input_tag :text, :
|
55
|
-
#
|
140
|
+
# input_tag :text, :name => 'handle'
|
141
|
+
# # => <input type="test" name="handle">
|
142
|
+
#
|
143
|
+
# input_tag :password, :name => 'password', :size => 20
|
144
|
+
# # => <input type="password" name="password" size="20">
|
145
|
+
#
|
146
|
+
# input_tag :text, :name => 'username', :required => true, :autofocus => true
|
147
|
+
# # => <input type="text" name="username" required autofocus>
|
148
|
+
#
|
149
|
+
# input_tag :number, :name => 'credit_card', :autocomplete => :off
|
150
|
+
# # => <input type="number" autocomplete="off">
|
56
151
|
#
|
57
152
|
# @api semipublic
|
58
153
|
def input_tag(type, options = {})
|
59
|
-
options.reverse_merge!(:type => type)
|
60
|
-
tag(:input, options)
|
154
|
+
tag(:input, options.reverse_merge!(:type => type))
|
61
155
|
end
|
62
156
|
|
63
157
|
##
|
64
|
-
# Creates an
|
158
|
+
# Creates an HTML tag with the given name and options
|
65
159
|
#
|
66
|
-
# @param [Symbol]
|
67
|
-
#
|
160
|
+
# @param [Symbol] name
|
161
|
+
# The name of the HTML tag to create.
|
68
162
|
# @param [Hash] options
|
69
|
-
#
|
163
|
+
# The HTML options to include in this tag.
|
164
|
+
#
|
165
|
+
# @macro global_html_attributes
|
70
166
|
#
|
71
|
-
# @return [String]
|
167
|
+
# @return [String]
|
168
|
+
# Generated HTML with specified +options+
|
72
169
|
#
|
73
170
|
# @example
|
74
|
-
# tag
|
75
|
-
#
|
171
|
+
# tag :hr, :class => 'dotted'
|
172
|
+
# # => <hr class="dotted">
|
173
|
+
#
|
174
|
+
# tag :input, :name => 'username', :type => :text
|
175
|
+
# # => <input name="username" type="text">
|
176
|
+
#
|
177
|
+
# tag :img, :src => 'images/pony.jpg', :alt => 'My Little Pony'
|
178
|
+
# # => <img src="images/pony.jpg" alt="My Little Pony">
|
179
|
+
#
|
180
|
+
# tag :img, :src => 'sinatra.jpg, :data => { :nsfw => false, :geo => [34.087, -118.407] }
|
181
|
+
# # => <img src="sinatra.jpg" data-nsfw="false" data-geo="34.087 -118.407">
|
76
182
|
#
|
77
183
|
# @api public
|
78
|
-
def tag(name, options=
|
79
|
-
|
80
|
-
content = content.join("\n") if content.respond_to?(:join)
|
81
|
-
identity_tag_attributes.each { |attr| options[attr] = attr.to_s if options[attr] }
|
82
|
-
html_attrs = options.map { |a, v| v.nil? || v == false ? nil : "#{a}=\"#{escape_value(v)}\"" }.compact.join(" ")
|
83
|
-
base_tag = (html_attrs.present? ? "<#{name} #{html_attrs}" : "<#{name}")
|
84
|
-
base_tag << (open_tag ? ">" : (content ? ">#{content}</#{name}>" : " />"))
|
184
|
+
def tag(name, options = nil)
|
185
|
+
"<#{name}#{tag_options(options) if options}>"
|
85
186
|
end
|
86
187
|
|
87
188
|
private
|
88
189
|
##
|
89
|
-
# Returns a list of attributes
|
90
|
-
|
91
|
-
def
|
92
|
-
|
190
|
+
# Returns a compiled list of HTML attributes
|
191
|
+
##
|
192
|
+
def tag_options(options)
|
193
|
+
return if options.blank?
|
194
|
+
attributes = []
|
195
|
+
options.each do |attribute, value|
|
196
|
+
next if value.nil? || value == false
|
197
|
+
if attribute == :data && value.is_a?(Hash)
|
198
|
+
value.each { |k, v| attributes << %[data-#{k.to_s.dasherize}="#{escape_value(v)}"] }
|
199
|
+
elsif BOOLEAN_ATTRIBUTES.include?(attribute)
|
200
|
+
attributes << attribute.to_s
|
201
|
+
else
|
202
|
+
attributes << %[#{attribute}="#{escape_value(value)}"]
|
203
|
+
end
|
204
|
+
end
|
205
|
+
" #{attributes.join(' ')}"
|
93
206
|
end
|
94
207
|
|
95
208
|
##
|
96
209
|
# Escape tag values to their HTML/XML entities.
|
97
|
-
|
210
|
+
##
|
98
211
|
def escape_value(string)
|
99
212
|
string.to_s.gsub(Regexp.union(*ESCAPE_VALUES.keys)){|c| ESCAPE_VALUES[c] }
|
100
213
|
end
|