scinote-web/app/helpers/sci_form_helper.rb

157 lines
6.5 KiB
Ruby
Raw Normal View History

2023-07-03 17:11:51 +08:00
module SciFormHelper
class SciFormBuilder < ActionView::Helpers::FormBuilder
2016-02-12 23:52:43 +08:00
# Returns Bootstrap date-time picker of the "datetime" type tailored for accessing a specified datetime attribute (identified by +name+) on an object
# assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
# hash with +options+. The supported options are shown in the following examples.
#
# ==== Examples
# Specify custom label (otherwise, a humanized version of +name+ is used)
# # => datetime_picker(:post, :published, label: "Published date")
#
# Specify custom CSS style on the element
# # => datetime_picker(:post, :published, style: "background-color: #000; margin-top: 20px;")
#
# Show a "clear" button on the bottom of the date picker.
# # => datetime_picker(:post, :published, clear: true)
#
# Show a "today" button on the bottom of the date picker.
# # => datetime_picker(:post, :published, today: true)
def datetime_picker(name, options = {})
2023-07-03 17:11:51 +08:00
id = "#{@object_name}_#{name}"
input_name = "#{@object_name}[#{name}]"
2020-03-28 00:35:24 +08:00
value = options[:value] ? options[:value].strftime("#{I18n.backend.date_format} %H:%M") : ''
2016-02-12 23:52:43 +08:00
js_locale = I18n.locale.to_s
2020-03-28 00:35:24 +08:00
js_format = options[:time] ? datetime_picker_format_full : datetime_picker_format_date_only
2016-02-12 23:52:43 +08:00
label = options[:label] || name.to_s.humanize
2016-02-12 23:52:43 +08:00
style = options[:style] ? "style='#{options[:style]}'" : ''
2016-02-12 23:52:43 +08:00
res = "<div class='form-group' #{style}><label class='control-label required' for='#{id}'>#{label}</label>" \
"<div class='container' style='padding-left: 0; margin-left: 0;'><div class='row'><div class='col-sm-6'>"
2016-02-12 23:52:43 +08:00
res << "<div class='input-group date'>" if options[:clear]
2023-07-03 17:11:51 +08:00
res << "<input type='datetime' class='form-control' name='#{input_name}' id='#{id}' " \
"readonly value='#{value}' data-toggle='date-time-picker' data-date-format='#{js_format}' " \
"data-date-locale='#{js_locale}' data-date-show-today-button='#{options[:today].present?}'/>"
if options[:clear]
res << "<span class='input-group-addon' data-toggle='clear-date-time-picker' data-target='#{id}'>" \
2023-06-08 23:33:50 +08:00
"<i class='sn-icon sn-icon-close'></i></span></div>"
2016-02-12 23:52:43 +08:00
end
res << '</div></div></div></div>'
2016-02-12 23:52:43 +08:00
res.html_safe
end
# Returns Bootstrap button group for choosing a specified enum attribute (identified by +name+) on an object
# assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
# hash with +options+. The supported options are shown in the following examples.
#
# ==== Examples
# Specify custom label (otherwise, a humanized version of +name+ is used)
# # => enum_btn_group(:car, :type, label: "Car type")
#
# Specify custom button names for enum values (a hash)
# # => enum_btn_groups(:car, :type, btn_names: { diesel: "Diesel car", electric: "Electric car" })
#
# Specify custom CSS style on the element
# # => enum_btn_group(:car, :type, style: "background-color: #000; margin-top: 20px;")
#
# Specify custom CSS classes on the element
# # => enum_btn_group(:car, :type, class: "class1 class2")
def enum_btn_group(name, options = {})
2023-07-03 17:11:51 +08:00
id = "#{@object_name}_#{name}"
input_name = "#{@object_name}[#{name}]"
2016-02-12 23:52:43 +08:00
enum_vals = @object.class.send(name.to_s.pluralize)
2023-07-03 17:11:51 +08:00
btn_names = enum_vals.keys.collect { |k| [k, k] }.to_h
btn_names = options[:btn_names] if options[:btn_names]
btn_names = ActiveSupport::HashWithIndifferentAccess.new(btn_names)
2016-02-12 23:52:43 +08:00
label = name.to_s.humanize
2023-07-03 17:11:51 +08:00
label = options[:label] if options[:label]
2016-02-12 23:52:43 +08:00
2023-07-03 17:11:51 +08:00
style_str = ''
style_str = " style='#{options[:style]}'" if options[:style]
2016-02-12 23:52:43 +08:00
2023-07-03 17:11:51 +08:00
class_str = ''
class_str = " #{options[:class]}" if options[:class]
2016-02-12 23:52:43 +08:00
2023-07-03 17:11:51 +08:00
res = ''
2016-02-12 23:52:43 +08:00
res << "<div class='form-group#{class_str}'#{style_str}>"
res << "<label for='#{id}'>#{label}</label>"
2023-07-03 17:11:51 +08:00
res << '<br>'
2016-02-12 23:52:43 +08:00
res << "<div class='btn-group' data-toggle='buttons'>"
enum_vals.keys.each do |val|
active = @object.send("#{val}?")
2023-07-03 17:11:51 +08:00
active_str = active ? ' active' : ''
checked_str = active ? " checked='checked'" : ''
2016-02-12 23:52:43 +08:00
2018-05-18 22:24:24 +08:00
res << "<label class='btn btn-toggle#{active_str}'>"
2016-02-12 23:52:43 +08:00
res << "<input type='radio' value='#{val}' name='#{input_name}' id='#{id}_#{val}'#{checked_str}>"
res << btn_names[val]
2023-07-03 17:11:51 +08:00
res << '</label>'
2016-02-12 23:52:43 +08:00
end
2023-07-03 17:11:51 +08:00
res << '</div>'
res << '</div>'
2016-02-12 23:52:43 +08:00
res.html_safe
end
# Returns smart <textarea> that dynamically resizes depending on the user
# input. Also has an option 'single_line: true' to render it as a one-line
# (imagine <input type="text">) input field that only grows beyond one line
# if inputting a larger text (otherwise, by default it spans 2 lines).
#
# Other than that, it accepts same options as regular text_area helper.
def smart_text_area(name, opts = {})
opts[:class] = [opts[:class], 'smart-text-area'].join(' ')
if !opts[:rows] && @object
opts[:rows] =
@object.public_send(name).try(:lines).try(:count)
end
opts.delete(:rows) if opts[:rows].nil?
if opts[:single_line]
2023-07-03 17:11:51 +08:00
opts[:class] = if opts[:rows]
[opts[:class], 'textarea-sm-present'].join(' ')
else
[opts[:class], 'textarea-sm'].join(' ')
end
end
text_area(name, opts)
end
2017-01-19 18:37:59 +08:00
# Returns <textarea> helper tag for tinyMCE editor
def tiny_mce_editor(name, options = {})
options.deep_merge!(cols: 120,
rows: 10,
data: {
tinymce_asset_path:
Rails.application.routes.url_helpers.tiny_mce_assets_path
})
2017-01-19 18:37:59 +08:00
text_area(name, options)
end
2016-02-12 23:52:43 +08:00
end
2020-03-28 00:35:24 +08:00
# Returns date only format string for Bootstrap DateTimePicker
def datetime_picker_format_date_only
js_format = I18n.backend.date_format.dup
js_format.gsub!(/%-d/, 'D')
js_format.gsub!(/%d/, 'DD')
js_format.gsub!(/%-m/, 'M')
js_format.gsub!(/%m/, 'MM')
js_format.gsub!(/%b/, 'MMM')
js_format.gsub!(/%B/, 'MMMM')
js_format.gsub!('%Y', 'YYYY')
js_format
end
# Returns date and time format string for Bootstrap DateTimePicker
def datetime_picker_format_full
js_format = datetime_picker_format_date_only
js_format << ' HH:mm'
js_format
end
end