padrino-helpers 0.10.5 → 0.10.6.a
Sign up to get free protection for your applications and to get access to all the features.
- 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
|