bootstrap_form_extensions 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/bootstrap_form_extensions/arrayed_field.js +70 -0
- data/app/assets/javascripts/bootstrap_form_extensions/bootstrap-timepicker.min.js +5 -0
- data/app/assets/javascripts/bootstrap_form_extensions/index.js +2 -0
- data/app/assets/javascripts/bootstrap_form_extensions/jquery.html5data.min.js +7 -0
- data/app/assets/javascripts/bootstrap_form_extensions/scheduler.js +226 -0
- data/app/assets/javascripts/bootstrap_form_extensions/select_or_new.js +76 -0
- data/app/assets/javascripts/bootstrap_form_extensions/time_picker.js +61 -0
- data/app/assets/javascripts/bootstrap_form_extensions/timespan.js +60 -0
- data/app/assets/stylesheets/bootstrap_form_extensions/bootstrap-timepicker.min.css +10 -0
- data/app/assets/stylesheets/bootstrap_form_extensions/common.css +11 -0
- data/app/assets/stylesheets/bootstrap_form_extensions/index.css +4 -0
- data/app/assets/stylesheets/bootstrap_form_extensions/scheduler.css +31 -0
- data/app/assets/stylesheets/bootstrap_form_extensions/submit_bar.css +4 -0
- data/app/views/bootstrap_form_extensions/_submit_bar.html.erb +36 -0
- data/lib/bootstrap_form_extensions.rb +22 -0
- data/lib/bootstrap_form_extensions/arrayed_field.rb +107 -0
- data/lib/bootstrap_form_extensions/date_time_pickers.rb +71 -0
- data/lib/bootstrap_form_extensions/helpers.rb +18 -0
- data/lib/bootstrap_form_extensions/scheduler.rb +72 -0
- data/lib/bootstrap_form_extensions/select_or_new.rb +36 -0
- data/lib/bootstrap_form_extensions/submit_bar.rb +65 -0
- data/lib/bootstrap_form_extensions/timespan.rb +55 -0
- data/lib/bootstrap_form_extensions/version.rb +3 -0
- data/lib/tasks/rails_bootstrap_form_extensions_tasks.rake +4 -0
- data/test/arrayed_field_test.rb +63 -0
- data/test/bootstrap_form_extensions_test.rb +7 -0
- data/test/date_time_pickers_test.rb +50 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/category.rb +7 -0
- data/test/dummy/app/models/thing.rb +46 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/migrate/20150918185031_create_things.rb +9 -0
- data/test/dummy/db/migrate/20150924203053_add_timespan.rb +7 -0
- data/test/dummy/db/migrate/20150929213249_add_arrayed_field.rb +7 -0
- data/test/dummy/db/migrate/20151006171627_add_another_arrayed_field.rb +7 -0
- data/test/dummy/db/migrate/20151006181943_add_json_field.rb +7 -0
- data/test/dummy/db/migrate/20151007213131_add_scheduler_field.rb +7 -0
- data/test/dummy/db/migrate/20151030194330_add_date_time.rb +7 -0
- data/test/dummy/db/migrate/20151106165522_add_category.rb +10 -0
- data/test/dummy/db/schema.rb +31 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +1997 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/test/fixtures/things.yml +8 -0
- data/test/javascripts/arrayed_field_spec.js +101 -0
- data/test/javascripts/helpers/function_bind_polyfill_for_phantomjs.js +32 -0
- data/test/javascripts/helpers/jasmine-jquery.js +838 -0
- data/test/javascripts/scheduler_spec.js +354 -0
- data/test/javascripts/select_or_new_spec.js +113 -0
- data/test/javascripts/support/jasmine.yml +127 -0
- data/test/javascripts/support/jasmine_helper.rb +19 -0
- data/test/javascripts/time_picker_spec.js +42 -0
- data/test/javascripts/timespan_spec.js +81 -0
- data/test/javascripts/vendor/bootstrap.min.js +7 -0
- data/test/javascripts/vendor/jquery-2.1.4.min.js +4 -0
- data/test/scheduler_serializer_test.rb +200 -0
- data/test/scheduler_test.rb +15 -0
- data/test/select_or_new_test.rb +37 -0
- data/test/submit_bar_test.rb +112 -0
- data/test/test_helper.rb +37 -0
- data/test/timespan_test.rb +47 -0
- metadata +291 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
module BootstrapFormExtensions
|
2
|
+
|
3
|
+
module Scheduler
|
4
|
+
|
5
|
+
include BootstrapFormExtensions::Helpers
|
6
|
+
|
7
|
+
def self.serializer to: :yaml, default_selection: true
|
8
|
+
BootstrapFormExtensions::Scheduler::Serializer.new to, default_selection
|
9
|
+
end
|
10
|
+
|
11
|
+
def scheduler method, **options
|
12
|
+
schedule = object.send method
|
13
|
+
hidden = hidden_field method, value: JSON.dump(schedule), class: 'scheduler-hidden-field'
|
14
|
+
options[:wrapper] ||= {}
|
15
|
+
options[:wrapper][:data] ||= {}
|
16
|
+
options[:wrapper][:data][:scheduler] = true
|
17
|
+
form_group_builder(method, options) { hidden + schedule_to_table(schedule) }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def schedule_to_table schedule
|
23
|
+
content_tag :table, class: 'scheduler-badge' do
|
24
|
+
content_tag :tbody do
|
25
|
+
schedule.each.with_index.inject(''.html_safe) do |rows, (day_array, day_index)|
|
26
|
+
rows << content_tag(:tr) do
|
27
|
+
day_array.each.with_index.inject(''.html_safe) do |columns, (value, hour_index)|
|
28
|
+
columns << content_tag(:td, ' '.html_safe, class: (true?(value) ? 'on' : 'off'), data: { day: day_index, hour: hour_index })
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Serializer
|
37
|
+
|
38
|
+
include BootstrapFormExtensions::Helpers
|
39
|
+
|
40
|
+
attr_reader :to_format, :default_selection
|
41
|
+
|
42
|
+
def initialize to_format, default_selection
|
43
|
+
@to_format = to_format
|
44
|
+
@default_selection = default_selection
|
45
|
+
end
|
46
|
+
|
47
|
+
def load value_from_db
|
48
|
+
value_from_db = YAML.load(value_from_db.to_s || '') if to_format == :yaml
|
49
|
+
value_from_db = [] if value_from_db.blank?
|
50
|
+
value_from_db = parse_schedule_array value_from_db unless value_from_db[6].try(:[], 23).present?
|
51
|
+
value_from_db
|
52
|
+
end
|
53
|
+
|
54
|
+
def dump value_from_user
|
55
|
+
value_from_user = JSON.parse value_from_user rescue [] if value_from_user.is_a? String
|
56
|
+
value_from_user = [] unless value_from_user.is_a? Array
|
57
|
+
value_from_user = parse_schedule_array value_from_user
|
58
|
+
value_from_user = value_from_user.to_yaml if to_format == :yaml
|
59
|
+
value_from_user
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def parse_schedule_array value
|
65
|
+
Array.new(7) { |i| Array.new(24) { |j| (value[i][j].nil? && default_selection) || true?(value[i][j]) rescue default_selection } }
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module BootstrapFormExtensions
|
2
|
+
|
3
|
+
module SelectOrNew
|
4
|
+
|
5
|
+
include BootstrapFormExtensions::Helpers
|
6
|
+
|
7
|
+
def select_or_new method, choices = [], options = {}, html_options = {}
|
8
|
+
new_is_selected = object.send(method) == 0
|
9
|
+
|
10
|
+
# select...
|
11
|
+
options.delete :prompt
|
12
|
+
options.delete :include_blank
|
13
|
+
choices.unshift [ "Please select", nil ]
|
14
|
+
choices.push [ "New...", 0 ]
|
15
|
+
html_options[:class] = [ "form-control", html_options[:class] ].compact.join(' ')
|
16
|
+
html_options[:style] = 'display: none;' if new_is_selected
|
17
|
+
select = self.select_without_bootstrap method, choices, options, html_options
|
18
|
+
|
19
|
+
# ... or new
|
20
|
+
icon = @template.glyphicon_tag 'remove', class: 'text-danger'
|
21
|
+
icon = content_tag :div, icon, class: 'input-group-addon select-or-new-cancel'
|
22
|
+
new_method = "new_#{method.to_s.sub(/_id$/, '')}"
|
23
|
+
new_field_name = "#{object_name}[#{new_method}]"
|
24
|
+
text = @template.text_field_tag new_field_name, object.try(new_method), class: 'form-control', placeholder: 'New...'
|
25
|
+
text = content_tag :div, text + icon, class: 'input-group', style: (new_is_selected ? '' : 'display: none;')
|
26
|
+
|
27
|
+
# form group to put them together
|
28
|
+
html_options[:wrapper] ||= {}
|
29
|
+
html_options[:wrapper][:data] ||= {}
|
30
|
+
html_options[:wrapper][:data][:select_or_new] = true
|
31
|
+
form_group_builder(method, options, html_options) { select + text }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module BootstrapFormExtensions
|
2
|
+
|
3
|
+
module SubmitBar
|
4
|
+
|
5
|
+
mattr_accessor :partial
|
6
|
+
@@partial = 'bootstrap_form_extensions/submit_bar'
|
7
|
+
|
8
|
+
mattr_accessor :show_submit_button
|
9
|
+
@@show_submit_button = true
|
10
|
+
|
11
|
+
mattr_accessor :submit_button_text
|
12
|
+
@@submit_button_text = 'Save'
|
13
|
+
|
14
|
+
mattr_accessor :show_submit_menu
|
15
|
+
@@show_submit_menu = true
|
16
|
+
|
17
|
+
mattr_accessor :show_submit_and_dup_button
|
18
|
+
@@show_submit_and_dup_button = true
|
19
|
+
|
20
|
+
mattr_accessor :show_submit_and_new_button
|
21
|
+
@@show_submit_and_new_button = true
|
22
|
+
|
23
|
+
mattr_accessor :show_cancel_button
|
24
|
+
@@show_cancel_button = true
|
25
|
+
|
26
|
+
mattr_accessor :cancel_button_text
|
27
|
+
@@cancel_button_text = 'Cancel'
|
28
|
+
|
29
|
+
mattr_accessor :back_button_text
|
30
|
+
@@back_button_text = 'Back'
|
31
|
+
|
32
|
+
def submit_bar show_submit_button: @@show_submit_button, submit_button_text: @@submit_button_text,
|
33
|
+
show_submit_menu: @@show_submit_menu, show_submit_and_dup_button: @@show_submit_and_dup_button, show_submit_and_new_button: @@show_submit_and_new_button,
|
34
|
+
show_cancel_button: @@show_cancel_button, cancel_button_text: nil, cancel_button_url: nil,
|
35
|
+
extra_buttons: [], right_buttons: [],
|
36
|
+
partial: @@partial
|
37
|
+
|
38
|
+
show_submit_menu &&= @template.current_ability.can? :new, object if @template.respond_to? :current_ability
|
39
|
+
cancel_button_url ||= @template.url_for(object.persisted? ? object : @template.controller_name.to_sym) rescue 'javascript:history.back();'
|
40
|
+
cancel_button_text ||= show_submit_button ? @@cancel_button_text : @@back_button_text
|
41
|
+
|
42
|
+
@template.render partial, {
|
43
|
+
show_submit_button: show_submit_button, submit_button_text: submit_button_text,
|
44
|
+
show_submit_menu: show_submit_menu, show_submit_and_dup_button: show_submit_and_dup_button, show_submit_and_new_button: show_submit_and_new_button,
|
45
|
+
show_cancel_button: show_cancel_button, cancel_button_text: cancel_button_text, cancel_button_url: cancel_button_url,
|
46
|
+
extra_buttons: parse_extra_buttons_for_submit_bar(extra_buttons, :extra),
|
47
|
+
right_buttons: parse_extra_buttons_for_submit_bar(right_buttons, :right),
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def parse_extra_buttons_for_submit_bar buttons, type
|
54
|
+
buttons.map do |options|
|
55
|
+
text = options.delete :text
|
56
|
+
url = options.delete :url
|
57
|
+
options[:class] = [ 'btn', 'btn-default', "submitbar-#{type}-button", options[:class] ].compact.join(' ')
|
58
|
+
options[:rel] ||= "nofollow"
|
59
|
+
{ text: text, url: url, options: options }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module BootstrapFormExtensions
|
2
|
+
|
3
|
+
module Timespan
|
4
|
+
|
5
|
+
UNITS_IN_SECONDS = ActiveSupport::OrderedHash[ :seconds, 1, :minutes, 60, :hours, 3600, :days, 86400, :weeks, 604800, :months, 18144000 ]
|
6
|
+
|
7
|
+
mattr_accessor :units
|
8
|
+
@@units = UNITS_IN_SECONDS.keys
|
9
|
+
|
10
|
+
def timespan method, units: @@units, quantity_options: {}, unit_options: {}
|
11
|
+
quantity, selected, units = quantity_and_units_for_timespan method, units
|
12
|
+
hidden = hidden_field method, class: 'timespan-seconds'
|
13
|
+
field = text_field_for_timespan method, quantity, quantity_options
|
14
|
+
select = select_for_timespan method, selected, units, unit_options
|
15
|
+
content_tag :span, hidden + field + ' '.html_safe + select, data: { timespan: true }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def quantity_and_units_for_timespan method, units
|
21
|
+
units = units.map { |unit| [ unit, UNITS_IN_SECONDS[unit] ] }
|
22
|
+
|
23
|
+
time_in_seconds = object.send method
|
24
|
+
return [ '', units.first.last, units ] if time_in_seconds.blank?
|
25
|
+
|
26
|
+
selected = UNITS_IN_SECONDS.values.reverse.find(proc { 1 }) { |seconds| time_in_seconds % seconds == 0 }
|
27
|
+
quantity = time_in_seconds / selected
|
28
|
+
[ quantity, selected, units ]
|
29
|
+
end
|
30
|
+
|
31
|
+
def text_field_for_timespan method, quantity, quantity_options
|
32
|
+
text_field_name = method.to_s.sub(/(_in_seconds)?$/, '_quantity').to_sym
|
33
|
+
|
34
|
+
quantity_options[:size] ||= 5
|
35
|
+
quantity_options[:class] = [ "form-control", "timespan-quantity", quantity_options[:class] ].compact.join(' ')
|
36
|
+
|
37
|
+
field = @template.text_field_tag text_field_name, quantity, quantity_options
|
38
|
+
field << generate_help(method, nil)
|
39
|
+
|
40
|
+
css_class = 'form-group'
|
41
|
+
css_class << " #{error_class}" if has_error?(method)
|
42
|
+
|
43
|
+
content_tag :div, field, class: css_class
|
44
|
+
end
|
45
|
+
|
46
|
+
def select_for_timespan method, selected, units, unit_options
|
47
|
+
select_field_name = method.to_s.sub(/(_in_seconds)?$/, '_unit').to_sym
|
48
|
+
unit_options[:class] = [ "form-control", "timespan-unit", unit_options[:class] ].compact.join(' ')
|
49
|
+
select = @template.select_tag select_field_name, @template.options_for_select(units, selected), unit_options
|
50
|
+
content_tag :div, select, class: 'form-group'
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ArrayedFieldTest < ActionView::TestCase
|
4
|
+
include BootstrapFormExtensions::ArrayedField
|
5
|
+
|
6
|
+
def setup
|
7
|
+
setup_test_fixture
|
8
|
+
end
|
9
|
+
|
10
|
+
test "arrayed_text_field with default values" do
|
11
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_list">List</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-11"><input type="text" id="" class="form-control" data-name="thing[list][]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"><div class="row voffset1"><div class="col-sm-11"><input type="text" name="thing[list][]" id="thing_list_" value="One" class="form-control" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div><div class="row voffset1"><div class="col-sm-11"><input type="text" name="thing[list][]" id="thing_list_" value="Two" class="form-control" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>'
|
12
|
+
assert_equal expected, @builder.arrayed_text_field(:list)
|
13
|
+
end
|
14
|
+
|
15
|
+
test "arrayed_url_field with default values" do
|
16
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_urls">Urls</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-11"><input type="url" id="" class="form-control" data-name="thing[urls][]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"><div class="row voffset1"><div class="col-sm-11"><input type="url" name="thing[urls][]" id="thing_urls_" value="www.example1.com" class="form-control" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div><div class="row voffset1"><div class="col-sm-11"><input type="url" name="thing[urls][]" id="thing_urls_" value="www.example2.com" class="form-control" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>'
|
17
|
+
assert_equal expected, @builder.arrayed_url_field(:urls)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "ArrayedField, with nonexistent attribute, assumes the value is an empty array" do
|
21
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_nonexistent">Nonexistent</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-11"><input type="text" id="" class="form-control" data-name="thing[nonexistent][]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>'
|
22
|
+
assert_equal expected, @builder.arrayed_text_field(:nonexistent)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "ArrayedField, with non-array attribute, assumes the value is an empty array" do
|
26
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2 required" for="thing_name">Name</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-11"><input type="text" id="" class="form-control" data-name="thing[name][]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>'
|
27
|
+
assert_equal expected, @builder.arrayed_text_field(:name)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "pass options to the form group in the an ArrayedField" do
|
31
|
+
@output_buffer = @builder.arrayed_text_field(:list, wrapper_class: 'extra-class')
|
32
|
+
assert_select 'div.form-group.extra-class'
|
33
|
+
end
|
34
|
+
|
35
|
+
test "arrayed_json_field with default values" do
|
36
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_variables">Variables</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-2"><input type="text" id="" class="form-control" placeholder="name" data-name="thing[variables][][name]" /></div><div class="col-sm-2"><input type="text" id="" class="form-control" placeholder="value" data-name="thing[variables][][value]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"><div class="row voffset1"><div class="col-sm-2"><input type="text" name="thing[variables][][name]" id="thing_variables__name" class="form-control" placeholder="name" /></div><div class="col-sm-2"><input type="text" name="thing[variables][][value]" id="thing_variables__value" class="form-control" placeholder="value" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div><div class="row voffset1"><div class="col-sm-2"><input type="text" name="thing[variables][][name]" id="thing_variables__name" class="form-control" placeholder="name" /></div><div class="col-sm-2"><input type="text" name="thing[variables][][value]" id="thing_variables__value" class="form-control" placeholder="value" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>'
|
37
|
+
assert_equal expected, @builder.arrayed_json_field(:variables, %i[ name value ])
|
38
|
+
end
|
39
|
+
|
40
|
+
test "arrayed_json_field with custom input types" do
|
41
|
+
expected = <<-HTML.chomp
|
42
|
+
<div class="form-group"><label class="control-label col-sm-2" for="thing_variables">Variables</label><div class="col-sm-10"><div data-arrayed-field="true"><div class="blueprint-for-arrayed-field" style="display:none;"><div class="row voffset1"><div class="col-sm-2"><select id="" class="form-control" data-name="thing[variables][][name]"><option value="var1">Variable One</option>
|
43
|
+
<option value="var2">Variable Two</option>
|
44
|
+
<option value="var3">Variable Three</option></select></div><div class="col-sm-2"><input type="text" id="" class="form-control" placeholder="value" data-name="thing[variables][][value]" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="arrayed-field-rows"><div class="row voffset1"><div class="col-sm-2"><select id="" class="form-control"><option value="var1">Variable One</option>
|
45
|
+
<option value="var2">Variable Two</option>
|
46
|
+
<option value="var3">Variable Three</option></select></div><div class="col-sm-2"><input type="text" name="thing[variables][][value]" id="thing_variables__value" class="form-control" placeholder="value" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div><div class="row voffset1"><div class="col-sm-2"><select id="" class="form-control"><option value="var1">Variable One</option>
|
47
|
+
<option value="var2">Variable Two</option>
|
48
|
+
<option value="var3">Variable Three</option></select></div><div class="col-sm-2"><input type="text" name="thing[variables][][value]" id="thing_variables__value" class="form-control" placeholder="value" /></div><div class="col-sm-1"><a class="btn btn-default remove-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-trash"></i></a></div></div></div><div class="row voffset1"><div class="col-sm-12"><a class="btn btn-default add-arrayed-field-row" href="javascript:void(0);"><i class=" glyphicon glyphicon-plus"></i></a></div></div></div></div></div>
|
49
|
+
HTML
|
50
|
+
assert_equal expected, @builder.arrayed_json_field(:variables, [ { name: { type: :select, options: options_for_variables } }, :value ])
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def options_for_variables
|
56
|
+
[
|
57
|
+
[ "Variable One", "var1" ],
|
58
|
+
[ "Variable Two", "var2" ],
|
59
|
+
[ "Variable Three", "var3" ],
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DateTimePickersTest < ActionView::TestCase
|
4
|
+
include BootstrapFormExtensions::DateTimePickers
|
5
|
+
|
6
|
+
def setup
|
7
|
+
setup_test_fixture
|
8
|
+
end
|
9
|
+
|
10
|
+
test "date_picker" do
|
11
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_start_date">Start date</label><div class="col-sm-10"><div class="input-group date" data-provide="datepicker" data-date-today-highlight="true" data-date-format="yyyy-mm-dd" data-date-today-btn="linked" data-date-autoclose="true" data-date-disable-touch-keyboard="true" data-date-enable-on-readonly="false" data-date-show-on-focus="false"><input size="10" class="form-control" type="text" value="1971-10-21" name="thing[start_date]" id="thing_start_date" /><span class="input-group-addon"><i class=" glyphicon glyphicon-calendar"></i></span></div></div></div>'
|
12
|
+
assert_equal expected, @builder.date_picker(:start_date)
|
13
|
+
end
|
14
|
+
|
15
|
+
test "add an option to date_picker" do
|
16
|
+
@output_buffer = @builder.date_picker :start_date, widget: { clear_btn: true }
|
17
|
+
assert_select 'div.date[data-date-clear-btn=true]'
|
18
|
+
end
|
19
|
+
|
20
|
+
test "overwrite one of the default options to date_picker" do
|
21
|
+
@output_buffer = @builder.date_picker :start_date, widget: { format: 'dd-mm-yyyy' }
|
22
|
+
assert_select 'div.date[data-date-format="dd-mm-yyyy"]'
|
23
|
+
end
|
24
|
+
|
25
|
+
test "time_picker" do
|
26
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_start_time">Start time</label><div class="col-sm-10"><div class="input-group bootstrap-timepicker"><input class="form-control" size="8" data-provide="timepicker" type="text" value="07:30:00" name="thing[start_time]" id="thing_start_time" /><span class="input-group-addon"><i class=" glyphicon glyphicon-time"></i></span></div></div></div>'
|
27
|
+
assert_equal expected, @builder.time_picker(:start_time)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "add an option to time_picker" do
|
31
|
+
@output_buffer = @builder.time_picker :start_time, widget: { disable_mousewheel: true }
|
32
|
+
assert_select 'input[data-time-disable-mousewheel=true]'
|
33
|
+
end
|
34
|
+
|
35
|
+
test "date_time_picker" do
|
36
|
+
expected = '<div class="form-group"><label class="control-label col-sm-2" for="thing_start_at">Start at</label><div class="col-sm-10 form-inline"><div class="form-group"><div class="input-group date" data-provide="datepicker" data-date-today-highlight="true" data-date-format="yyyy-mm-dd" data-date-today-btn="linked" data-date-autoclose="true" data-date-disable-touch-keyboard="true" data-date-enable-on-readonly="false" data-date-show-on-focus="false"><input size="10" class="form-control" type="text" value="1971-10-21" name="thing[start_date]" id="thing_start_date" /><span class="input-group-addon"><i class=" glyphicon glyphicon-calendar"></i></span></div></div> <div class="form-group"><div class="input-group bootstrap-timepicker"><input class="form-control" size="8" data-provide="timepicker" type="text" value="07:30:00" name="thing[start_time]" id="thing_start_time" /><span class="input-group-addon"><i class=" glyphicon glyphicon-time"></i></span></div></div></div></div>'
|
37
|
+
assert_equal expected, @builder.date_time_picker(:start_at)
|
38
|
+
end
|
39
|
+
|
40
|
+
test "add an option to the date control in the date_time_picker" do
|
41
|
+
@output_buffer = @builder.date_time_picker :start_at, date_options: { widget: { clear_btn: true } }
|
42
|
+
assert_select 'div.date[data-date-clear-btn=true]'
|
43
|
+
end
|
44
|
+
|
45
|
+
test "add an option to the time control in the date_time_picker" do
|
46
|
+
@output_buffer = @builder.date_time_picker :start_at, time_options: { widget: { disable_mousewheel: true } }
|
47
|
+
assert_select 'input[data-time-disable-mousewheel=true]'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/test/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|