formular 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +29 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +105 -0
- data/Rakefile +12 -0
- data/formular.gemspec +33 -0
- data/lib/formular.rb +8 -0
- data/lib/formular/attributes.rb +45 -0
- data/lib/formular/builder.rb +52 -0
- data/lib/formular/builders/basic.rb +64 -0
- data/lib/formular/builders/bootstrap3.rb +28 -0
- data/lib/formular/builders/bootstrap3_horizontal.rb +32 -0
- data/lib/formular/builders/bootstrap3_inline.rb +10 -0
- data/lib/formular/builders/bootstrap4.rb +36 -0
- data/lib/formular/builders/bootstrap4_horizontal.rb +39 -0
- data/lib/formular/builders/bootstrap4_inline.rb +15 -0
- data/lib/formular/builders/foundation6.rb +28 -0
- data/lib/formular/element.rb +135 -0
- data/lib/formular/element/bootstrap3.rb +70 -0
- data/lib/formular/element/bootstrap3/checkable_control.rb +105 -0
- data/lib/formular/element/bootstrap3/column_control.rb +45 -0
- data/lib/formular/element/bootstrap3/horizontal.rb +146 -0
- data/lib/formular/element/bootstrap3/input_group.rb +83 -0
- data/lib/formular/element/bootstrap4.rb +49 -0
- data/lib/formular/element/bootstrap4/checkable_control.rb +94 -0
- data/lib/formular/element/bootstrap4/custom_control.rb +120 -0
- data/lib/formular/element/bootstrap4/horizontal.rb +87 -0
- data/lib/formular/element/foundation6.rb +69 -0
- data/lib/formular/element/foundation6/checkable_control.rb +72 -0
- data/lib/formular/element/foundation6/input_group.rb +88 -0
- data/lib/formular/element/foundation6/wrapped_control.rb +21 -0
- data/lib/formular/element/module.rb +35 -0
- data/lib/formular/element/modules/checkable.rb +96 -0
- data/lib/formular/element/modules/collection.rb +17 -0
- data/lib/formular/element/modules/container.rb +60 -0
- data/lib/formular/element/modules/control.rb +42 -0
- data/lib/formular/element/modules/error.rb +48 -0
- data/lib/formular/element/modules/hint.rb +36 -0
- data/lib/formular/element/modules/label.rb +30 -0
- data/lib/formular/element/modules/wrapped_control.rb +73 -0
- data/lib/formular/elements.rb +295 -0
- data/lib/formular/helper.rb +53 -0
- data/lib/formular/html_block.rb +70 -0
- data/lib/formular/path.rb +30 -0
- data/lib/formular/version.rb +3 -0
- metadata +247 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'formular/builders/bootstrap3'
|
2
|
+
module Formular
|
3
|
+
module Builders
|
4
|
+
class Bootstrap3Inline < Formular::Builders::Bootstrap3
|
5
|
+
Form = Class.new(Formular::Element::Form) { set_default :class, ['form-inline'] }
|
6
|
+
|
7
|
+
element_set form: Form
|
8
|
+
end # class Bootstrap3Inline
|
9
|
+
end # module Builders
|
10
|
+
end # module Formular
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'formular/builders/basic'
|
2
|
+
require 'formular/element/bootstrap4'
|
3
|
+
require 'formular/element/bootstrap3'
|
4
|
+
require 'formular/element/bootstrap3/input_group'
|
5
|
+
|
6
|
+
module Formular
|
7
|
+
module Builders
|
8
|
+
class Bootstrap4 < Formular::Builders::Basic
|
9
|
+
element_set(
|
10
|
+
error_notification: Formular::Element::Bootstrap3::ErrorNotification,
|
11
|
+
error: Formular::Element::Bootstrap4::Error,
|
12
|
+
hint: Formular::Element::Bootstrap4::Hint,
|
13
|
+
input: Formular::Element::Bootstrap4::Input,
|
14
|
+
input_group: Formular::Element::Bootstrap3::InputGroup,
|
15
|
+
checkbox: Formular::Element::Bootstrap4::StackedCheckbox,
|
16
|
+
radio: Formular::Element::Bootstrap4::StackedRadio,
|
17
|
+
select: Formular::Element::Bootstrap3::Select,
|
18
|
+
custom_select: Formular::Element::Bootstrap4::CustomSelect,
|
19
|
+
custom_file: Formular::Element::Bootstrap4::CustomFile,
|
20
|
+
custom_radio: Formular::Element::Bootstrap4::Inline::CustomRadio,
|
21
|
+
custom_checkbox: Formular::Element::Bootstrap4::Inline::CustomCheckbox,
|
22
|
+
custom_stacked_radio: Formular::Element::Bootstrap4::CustomStackedRadio,
|
23
|
+
custom_stacked_checkbox: Formular::Element::Bootstrap4::CustomStackedCheckbox,
|
24
|
+
inline_radio: Formular::Element::Bootstrap4::InlineRadio,
|
25
|
+
inline_checkbox: Formular::Element::Bootstrap4::InlineCheckbox,
|
26
|
+
label: Formular::Element::Label,
|
27
|
+
checkable_group_label: Formular::Element::Legend,
|
28
|
+
textarea: Formular::Element::Bootstrap3::Textarea,
|
29
|
+
wrapper: Formular::Element::Bootstrap4::Wrapper,
|
30
|
+
error_wrapper: Formular::Element::Bootstrap4::ErrorWrapper,
|
31
|
+
submit: Formular::Element::Bootstrap4::Submit,
|
32
|
+
row: Formular::Element::Bootstrap3::Row
|
33
|
+
)
|
34
|
+
end # class Bootstrap4
|
35
|
+
end # module Builders
|
36
|
+
end # module Formular
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'formular/builders/bootstrap4'
|
2
|
+
require 'formular/element/bootstrap3/horizontal'
|
3
|
+
require 'formular/element/bootstrap4/horizontal'
|
4
|
+
module Formular
|
5
|
+
module Builders
|
6
|
+
class Bootstrap4Horizontal < Formular::Builders::Bootstrap4
|
7
|
+
element_set(
|
8
|
+
input: Formular::Element::Bootstrap4::Horizontal::Input,
|
9
|
+
custom_file: Formular::Element::Bootstrap4::Horizontal::CustomFile,
|
10
|
+
input_group: Formular::Element::Bootstrap3::Horizontal::InputGroup,
|
11
|
+
select: Formular::Element::Bootstrap3::Horizontal::Select,
|
12
|
+
custom_select: Formular::Element::Bootstrap4::Horizontal::CustomSelect,
|
13
|
+
checkbox: Formular::Element::Bootstrap4::Horizontal::Checkbox,
|
14
|
+
custom_stacked_checkbox: Formular::Element::Bootstrap4::Horizontal::CustomStackedCheckbox,
|
15
|
+
radio: Formular::Element::Bootstrap4::Horizontal::Radio,
|
16
|
+
custom_stacked_radio: Formular::Element::Bootstrap4::Horizontal::CustomStackedRadio,
|
17
|
+
inline_radio: Formular::Element::Bootstrap4::Horizontal::InlineRadio,
|
18
|
+
custom_radio: Formular::Element::Bootstrap4::Horizontal::CustomRadio,
|
19
|
+
inline_checkbox: Formular::Element::Bootstrap4::Horizontal::InlineCheckbox,
|
20
|
+
custom_checkbox: Formular::Element::Bootstrap4::Horizontal::CustomCheckbox,
|
21
|
+
label: Formular::Element::Bootstrap4::Horizontal::Label,
|
22
|
+
legend: Formular::Element::Bootstrap4::Horizontal::Legend,
|
23
|
+
checkable_group_label: Formular::Element::Bootstrap4::Horizontal::Legend,
|
24
|
+
textarea: Formular::Element::Bootstrap3::Horizontal::Textarea,
|
25
|
+
error_wrapper: Formular::Element::Bootstrap4::ErrorWrapper,
|
26
|
+
input_column_wrapper: Formular::Element::Bootstrap3::Horizontal::InputColumnWrapper,
|
27
|
+
submit: Formular::Element::Bootstrap4::Horizontal::Submit
|
28
|
+
)
|
29
|
+
inheritable_attr :column_classes
|
30
|
+
|
31
|
+
#these options should be easily configurable
|
32
|
+
self.column_classes = {
|
33
|
+
left_column: ['col-sm-2'],
|
34
|
+
right_column: ['col-sm-10'],
|
35
|
+
left_offset: ['offset-sm-2']
|
36
|
+
}
|
37
|
+
end # class Bootstrap4Horizontal
|
38
|
+
end # module Builders
|
39
|
+
end # module Formular
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'formular/builders/bootstrap4'
|
2
|
+
require 'formular/builders/bootstrap3_inline'
|
3
|
+
require 'formular/element/bootstrap4/custom_control'
|
4
|
+
|
5
|
+
module Formular
|
6
|
+
module Builders
|
7
|
+
class Bootstrap4Inline < Formular::Builders::Bootstrap4
|
8
|
+
element_set(
|
9
|
+
form: Bootstrap3Inline::Form,
|
10
|
+
custom_select: Formular::Element::Bootstrap4::CustomControl::Inline::CustomSelect,
|
11
|
+
custom_file: Formular::Element::Bootstrap4::CustomControl::Inline::CustomFile
|
12
|
+
)
|
13
|
+
end # class Bootstrap4Inline
|
14
|
+
end # module Builders
|
15
|
+
end # module Formular
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'formular/builders/basic'
|
2
|
+
require 'formular/elements'
|
3
|
+
require 'formular/element/foundation6'
|
4
|
+
require 'formular/element/foundation6/input_group'
|
5
|
+
module Formular
|
6
|
+
module Builders
|
7
|
+
class Foundation6 < Formular::Builders::Basic
|
8
|
+
element_set(
|
9
|
+
error_notification: Formular::Element::Foundation6::ErrorNotification,
|
10
|
+
checkable_group_label: Formular::Element::Legend,
|
11
|
+
checkbox: Formular::Element::Foundation6::Checkbox,
|
12
|
+
radio: Formular::Element::Foundation6::Radio,
|
13
|
+
stacked_checkbox: Formular::Element::Foundation6::StackedCheckbox,
|
14
|
+
stacked_radio: Formular::Element::Foundation6::StackedRadio,
|
15
|
+
input: Formular::Element::Foundation6::Input,
|
16
|
+
input_group: Formular::Element::Foundation6::InputGroup,
|
17
|
+
file: Formular::Element::Foundation6::File,
|
18
|
+
select: Formular::Element::Foundation6::Select,
|
19
|
+
textarea: Formular::Element::Foundation6::Textarea,
|
20
|
+
wrapper: Formular::Element::Label,
|
21
|
+
error_wrapper: Formular::Element::Foundation6::LabelWithError,
|
22
|
+
error: Formular::Element::Foundation6::Error,
|
23
|
+
hint: Formular::Element::Foundation6::Hint,
|
24
|
+
submit: Formular::Element::Foundation6::Submit,
|
25
|
+
)
|
26
|
+
end # class Foundation6
|
27
|
+
end # module Builders
|
28
|
+
end # module Formular
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require "formular/attributes"
|
2
|
+
require "formular/html_block"
|
3
|
+
require 'uber/inheritable_attr'
|
4
|
+
require 'uber/options'
|
5
|
+
|
6
|
+
module Formular
|
7
|
+
# The Element class is responsible for defining what the html should look like.
|
8
|
+
# This includes default attributes, and the function to use to render the html
|
9
|
+
# actual rendering is done via a HtmlBlock class
|
10
|
+
class Element
|
11
|
+
extend Uber::InheritableAttr
|
12
|
+
|
13
|
+
inheritable_attr :html_context
|
14
|
+
inheritable_attr :html_blocks
|
15
|
+
inheritable_attr :default_hash
|
16
|
+
inheritable_attr :option_keys
|
17
|
+
inheritable_attr :tag_name
|
18
|
+
|
19
|
+
self.default_hash = {}
|
20
|
+
self.html_blocks = {}
|
21
|
+
self.html_context = :default
|
22
|
+
self.option_keys = []
|
23
|
+
|
24
|
+
# set the default value of an option or attribute
|
25
|
+
# you can make this conditional by providing a condition
|
26
|
+
# e.g. if: :some_method or unless: :some_method
|
27
|
+
def self.set_default(key, value, condition = {})
|
28
|
+
self.default_hash[key] = { value: value, condition: condition }
|
29
|
+
end
|
30
|
+
|
31
|
+
# define what your html should look like
|
32
|
+
# this block is executed in the context of an HtmlBlock instance
|
33
|
+
def self.html(context = :default, &block)
|
34
|
+
self.html_blocks[context] = block
|
35
|
+
end
|
36
|
+
|
37
|
+
# a convenient way of changing the key for a context
|
38
|
+
# useful for inheritance if you want to replace a context
|
39
|
+
# but still access the original function
|
40
|
+
def self.rename_html_context(old_context, new_context)
|
41
|
+
self.html_blocks[new_context] = self.html_blocks.delete(old_context)
|
42
|
+
end
|
43
|
+
|
44
|
+
# blacklist the keys that should NOT end up as html attributes
|
45
|
+
def self.add_option_keys(*keys)
|
46
|
+
self.option_keys += keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# define the name of the html tag for the element
|
50
|
+
# e.g.
|
51
|
+
# tag :span
|
52
|
+
# tag 'input'
|
53
|
+
# Note that if you leave this out, the tag will be inferred
|
54
|
+
# based on the name of your class
|
55
|
+
# Also, this is not inherited
|
56
|
+
def self.tag(name)
|
57
|
+
self.tag_name = name
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.call(**options, &block)
|
61
|
+
new(**options, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
def initialize(**options, &block)
|
65
|
+
@builder = options.delete(:builder)
|
66
|
+
normalize_attributes(options)
|
67
|
+
@block = block
|
68
|
+
@tag = self.class.tag_name
|
69
|
+
@html_blocks = define_html_blocks
|
70
|
+
end
|
71
|
+
attr_reader :tag, :html_blocks, :builder, :attributes, :options
|
72
|
+
|
73
|
+
def to_html(context: nil)
|
74
|
+
context ||= self.class.html_context
|
75
|
+
html_blocks[context].call
|
76
|
+
end
|
77
|
+
alias_method :to_s, :to_html
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def define_html_blocks
|
82
|
+
self.class.html_blocks.each_with_object({}) do |(context, block), hash|
|
83
|
+
hash[context] = HtmlBlock.new(self, block)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# we split the options hash between options and attributes
|
88
|
+
# based on the option_keys defined on the class
|
89
|
+
# we then get the default_hash from the class
|
90
|
+
# and merge with the user options and attributes
|
91
|
+
def normalize_attributes(**options)
|
92
|
+
@attributes = Attributes[options]
|
93
|
+
@options = @attributes.select { |k, v| @attributes.delete(k) || true if option_key?(k) }
|
94
|
+
merge_default_hash
|
95
|
+
end
|
96
|
+
|
97
|
+
# Take each default value and merge it with attributes && options.
|
98
|
+
# This way ordering is important and we can access values as they are evaluated
|
99
|
+
def merge_default_hash
|
100
|
+
self.class.default_hash.each do |k, v|
|
101
|
+
next unless evaluate_option_condition?(v[:condition])
|
102
|
+
|
103
|
+
val = Uber::Options::Value.new(v[:value]).evaluate(self)
|
104
|
+
|
105
|
+
next if val.nil?
|
106
|
+
|
107
|
+
if option_key?(k)
|
108
|
+
@options[k] = val if @options[k].nil?
|
109
|
+
else
|
110
|
+
# make sure that we merge classes, not override them
|
111
|
+
k == :class && !@attributes[k].nil? ? @attributes[k] += val : @attributes[k] ||= val
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def option_key?(k)
|
117
|
+
self.class.option_keys.include?(k)
|
118
|
+
end
|
119
|
+
|
120
|
+
# this evaluates any conditons placed on our defaults returning true or false
|
121
|
+
# e.g.
|
122
|
+
# set_default :checked, "checked", if: :is_checked?
|
123
|
+
# set_default :class, ["form-control"], unless: :file_input?
|
124
|
+
def evaluate_option_condition?(condition = {})
|
125
|
+
return true if condition.empty?
|
126
|
+
operator = condition.keys[0]
|
127
|
+
condition_result = Uber::Options::Value.new(condition.values[0]).evaluate(self)
|
128
|
+
|
129
|
+
case operator.to_sym
|
130
|
+
when :if then condition_result
|
131
|
+
when :unless then !condition_result
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end # class Element
|
135
|
+
end # module Formular
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'formular/element'
|
2
|
+
require 'formular/elements'
|
3
|
+
require 'formular/element/modules/wrapped_control'
|
4
|
+
require 'formular/element/module'
|
5
|
+
require 'formular/element/bootstrap3/checkable_control'
|
6
|
+
require 'formular/element/bootstrap3/column_control'
|
7
|
+
|
8
|
+
module Formular
|
9
|
+
class Element
|
10
|
+
module Bootstrap3
|
11
|
+
include CheckableControl
|
12
|
+
|
13
|
+
Label = Class.new(Formular::Element::Label) { set_default :class, ['control-label'] }
|
14
|
+
Row = Class.new(Formular::Element::Div) { set_default :class, ['row'] }
|
15
|
+
|
16
|
+
class Submit < Formular::Element::Button
|
17
|
+
set_default :class, ['btn', 'btn-default']
|
18
|
+
set_default :type, 'submit'
|
19
|
+
end # class Submit
|
20
|
+
|
21
|
+
class ErrorNotification < Formular::Element::ErrorNotification
|
22
|
+
set_default :class, ['alert alert-danger']
|
23
|
+
set_default :role, 'alert'
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
class Error < Formular::Element::Error
|
28
|
+
tag :span
|
29
|
+
set_default :class, ['help-block']
|
30
|
+
end # class Error
|
31
|
+
|
32
|
+
class Hint < Formular::Element::Span
|
33
|
+
set_default :class, ['help-block']
|
34
|
+
end # class Hint
|
35
|
+
|
36
|
+
class Input < Formular::Element::Input
|
37
|
+
include Formular::Element::Modules::WrappedControl
|
38
|
+
include Formular::Element::Bootstrap3::ColumnControl
|
39
|
+
|
40
|
+
set_default :class, ['form-control'], unless: :file_input?
|
41
|
+
|
42
|
+
def file_input?
|
43
|
+
attributes[:type] == 'file'
|
44
|
+
end
|
45
|
+
end # class Input
|
46
|
+
|
47
|
+
class Select < Formular::Element::Select
|
48
|
+
include Formular::Element::Modules::WrappedControl
|
49
|
+
include Formular::Element::Bootstrap3::ColumnControl
|
50
|
+
|
51
|
+
set_default :class, ['form-control']
|
52
|
+
end # class Select
|
53
|
+
|
54
|
+
class Textarea < Formular::Element::Textarea
|
55
|
+
include Formular::Element::Modules::WrappedControl
|
56
|
+
include Formular::Element::Bootstrap3::ColumnControl
|
57
|
+
|
58
|
+
set_default :class, ['form-control']
|
59
|
+
end # class Textarea
|
60
|
+
|
61
|
+
class Wrapper < Formular::Element::Div
|
62
|
+
set_default :class, ['form-group']
|
63
|
+
end # class Wrapper
|
64
|
+
|
65
|
+
class ErrorWrapper < Formular::Element::Div
|
66
|
+
set_default :class, ['form-group', 'has-error']
|
67
|
+
end # class Wrapper
|
68
|
+
end # module Bootstrap3
|
69
|
+
end # class Element
|
70
|
+
end # module Formular
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'formular/elements'
|
2
|
+
require 'formular/element/modules/wrapped_control'
|
3
|
+
require 'formular/element/module'
|
4
|
+
|
5
|
+
module Formular
|
6
|
+
class Element
|
7
|
+
module Bootstrap3
|
8
|
+
module CheckableControl
|
9
|
+
module InlineCheckable
|
10
|
+
include Formular::Element::Module
|
11
|
+
|
12
|
+
html(:wrapped) do |input|
|
13
|
+
input.wrapper do
|
14
|
+
concat input.group_label
|
15
|
+
concat input.hidden_tag unless input.collection?
|
16
|
+
if input.has_group_label?
|
17
|
+
concat Formular::Element::Div.(content: input.to_html(context: :collection))
|
18
|
+
else
|
19
|
+
concat input.to_html(context: :collection)
|
20
|
+
end
|
21
|
+
concat input.hidden_tag if input.collection?
|
22
|
+
concat input.hint
|
23
|
+
concat input.error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end # class InlineCheckable
|
27
|
+
|
28
|
+
class InlineRadio < Formular::Element::Radio
|
29
|
+
include Formular::Element::Modules::WrappedControl
|
30
|
+
include InlineCheckable
|
31
|
+
|
32
|
+
add_option_keys :control_label_options
|
33
|
+
set_default :control_label_options, { class: ['radio-inline'] }
|
34
|
+
|
35
|
+
def hidden_tag
|
36
|
+
''
|
37
|
+
end
|
38
|
+
end# class InlineRadio
|
39
|
+
|
40
|
+
class InlineCheckbox < Formular::Element::Checkbox
|
41
|
+
include Formular::Element::Modules::WrappedControl
|
42
|
+
include InlineCheckable
|
43
|
+
|
44
|
+
set_default :control_label_options, { class: ['checkbox-inline'] }
|
45
|
+
set_default :value, '1' # instead of reader value
|
46
|
+
|
47
|
+
html { closed_start_tag }
|
48
|
+
end # class InlineCheckbox
|
49
|
+
|
50
|
+
module StackedCheckable
|
51
|
+
include Formular::Element::Module
|
52
|
+
|
53
|
+
html(:wrapped) do |input|
|
54
|
+
input.wrapper do
|
55
|
+
concat input.group_label
|
56
|
+
concat input.hidden_tag unless input.collection?
|
57
|
+
concat input.to_html(context: :collection)
|
58
|
+
concat input.hidden_tag if input.collection?
|
59
|
+
concat input.hint
|
60
|
+
concat input.error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
html(:collection) do |input|
|
65
|
+
input.collection.map { |control|
|
66
|
+
control.inner_wrapper { control.to_html(context: :checkable_label) }
|
67
|
+
}.join('')
|
68
|
+
end
|
69
|
+
|
70
|
+
module InstanceMethods
|
71
|
+
def inner_wrapper(&block)
|
72
|
+
Formular::Element::Div.(class: inner_wrapper_class, &block).to_s
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end # module StackedCheckable
|
76
|
+
|
77
|
+
class Checkbox < Formular::Element::Checkbox
|
78
|
+
include Formular::Element::Modules::WrappedControl
|
79
|
+
include StackedCheckable
|
80
|
+
|
81
|
+
set_default :value, '1' # instead of reader value
|
82
|
+
|
83
|
+
html { closed_start_tag }
|
84
|
+
|
85
|
+
def inner_wrapper_class
|
86
|
+
['checkbox']
|
87
|
+
end
|
88
|
+
end # class Checkbox
|
89
|
+
|
90
|
+
class Radio < Formular::Element::Radio
|
91
|
+
include Formular::Element::Modules::WrappedControl
|
92
|
+
include StackedCheckable
|
93
|
+
|
94
|
+
def inner_wrapper_class
|
95
|
+
['radio']
|
96
|
+
end
|
97
|
+
|
98
|
+
def hidden_tag
|
99
|
+
''
|
100
|
+
end
|
101
|
+
end # class Radio
|
102
|
+
end # module CheckableControl
|
103
|
+
end # module Bootstrap3
|
104
|
+
end # class Element
|
105
|
+
end # module Formular
|