require 'simple_form'
require 'nested_form/builder_mixin'
module AbAdmin
module Views
class FormBuilder < ::SimpleForm::FormBuilder
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::TagHelper
include NestedForm::BuilderMixin if defined? NestedForm
map_type :color, to: ::AbAdmin::Views::Inputs::ColorInput
map_type :ckeditor, to: ::AbAdmin::Views::Inputs::CkeditorInput
map_type :editor, to: ::AbAdmin::Views::Inputs::EditorInput
map_type :date, :time, :datetime, to: ::AbAdmin::Views::Inputs::DateTimeInput
map_type :token, to: ::AbAdmin::Views::Inputs::TokenInput
def input(attribute_name, options = {}, &block)
if options[:fancy] || (!options.key?(:fancy) && ((!options.key?(:as) && options[:collection]) || options[:as] == :select))
options[:input_html] ||= {}
options[:input_html][:class] = "#{options[:input_html][:class]} fancy_select"
end
case options[:as]
when :uploader
title = options[:title] || I18n.t("admin.#{attribute_name}", default: object.class.han(attribute_name))
return template.input_set(title) { attach_file_field(attribute_name, options) }
when :map
title = options[:title] || I18n.t("admin.#{attribute_name}", default: object.class.han(attribute_name))
prefix = options[:prefix] || object.class.model_name.singular
data_fields = [:lat, :lon, :zoom].map { |attr| hidden_field(attr) }.join.html_safe
return template.input_set(title) { data_fields + geo_input(prefix, options[:js_options]) }
when :token
options[:label] ||= object.class.han(attribute_name.to_s.sub(/^token_|_id$/, ''))
when :association, :tree_select
unless options[:reflection]
if options[:as] == :tree_select
options[:collection] ||= begin
reflection = object.class.reflect_on_association(attribute_name)
records = reflection.klass.all(reflection.options.slice(:conditions, :order))
reflection.klass.nested_opts_with_parent(records, object)
end
end
return association(attribute_name, options.merge(as: :select))
end
when :checkbox_tree
reflection = object.class.reflect_on_association(attribute_name)
return template.render 'admin/shared/inputs/checkbox_tree', attribute_name: attribute_name, reflection: reflection, f: self
end
attribute_name = "#{attribute_name}_#{options[:locale]}" if options[:locale]
super(attribute_name, options, &block)
end
def link_to_add_assoc(assoc, options={})
model = @object.class.reflect_on_association(assoc).klass
title = [@template.icon('plus', true), I18n.t('admin.add'), model.model_name.human].join(' ').html_safe
link_to_add title, assoc, class: "btn btn-primary #{options[:class]}"
end
def link_to_remove_assoc
link_to_remove @template.icon('trash', true) + I18n.t('admin.delete'), class: 'btn btn-danger btn-mini pull-right'
end
def locale_tabs(&block)
loc_html = {}
Globalize.available_locales.each do |l|
loc_html[l] = template.capture { block.call(l) }
end
template.render 'admin/shared/locale_tabs', loc_html: loc_html
end
def save_buttons
template.render 'admin/shared/save_buttons'
end
def geo_input(prefix, js_options={}, &block)
input_name = "#{prefix}_geo_ac"
js = %Q[$("##{prefix}_geo_input").geoInput(#{js_options.to_json})]
<<-HTML.html_safe
#{template.init_js(js)}
HTML
end
def attach_file_field(attribute_name, options = {})
value = options.delete(:value) if options.key?(:value)
value ||= object.fileupload_asset(attribute_name)
asset_klass = object.reflections[attribute_name].try(:klass)
element_guid = object.fileupload_guid
element_id = template.dom_id(object, [attribute_name, element_guid].join('_'))
max_size = options[:file_max_size] || asset_klass.try(:max_size)
script_options = (options.delete(:script) || {}).stringify_keys
params = {
method: attribute_name,
assetable_id: object.new_record? ? nil : object.id,
assetable_type: object.class.name,
guid: element_guid
}.merge(script_options.delete(:params) || {})
script_options['action'] ||= '/sunrise/fileupload?' + Rack::Utils.build_query(params)
if !script_options['allowedExtensions'] && asset_klass
script_options['allowedExtensions'] = asset_klass.ext_list
end
if options[:template_id]
script_options['template_id'] = options[:template_id]
end
if options[:file]
script_options['allowedExtensions'] ||= %w(pdf doc docx xls xlsx ppt pptx zip rar csv jpg jpeg gif png)
script_options['template_id'] = '#fileupload_ftmpl'
options[:asset_template] = 'file'
elsif options[:video]
script_options['allowedExtensions'] ||= %w(mp4 flv)
script_options['template_id'] = '#fileupload_vtmpl'
options[:asset_template] = 'video'
end
script_options['allowedExtensions'] ||= %w(jpg jpeg png gif)
script_options['multiple'] ||= object.fileupload_multiple?(attribute_name)
script_options['element'] ||= element_id
script_options['sizeLimit'] = max_size.megabytes.to_i
locals = {
element_id: element_id,
error: error(attribute_name),
file_title: (options[:file_title] || script_options['allowedExtensions'].join(', ')),
file_max_size: max_size,
assets: [value].flatten.delete_if { |v| v.nil? || v.new_record? },
button_title: options[:button_title] || I18n.t("admin.fileupload.button#{'s' if script_options['multiple']}"),
asset_template: (options[:asset_template] || 'asset'),
container_data: {
klass: params[:assetable_type],
asset: asset_klass.to_s,
assoc: params[:method],
multiple: script_options['multiple'],
crop: options[:crop]
}
}
locals[:css_class] = ['fileupload', "#{locals[:asset_template]}_render_template"]
locals[:css_class] << "#{options[:file] ? 'file' : 'image'}_asset_type"
locals[:css_class] << (script_options['multiple'] ? 'many_assets' : 'one_asset')
locals[:css_class] << 'error' if locals[:error]
js_opts = [locals[:element_id], template.sort_admin_assets_path(klass: asset_klass), script_options['multiple']].map(&:inspect).join(', ')
locals[:js] = <<-JAVASCRIPT
var upl = new qq.FileUploaderInput(#{script_options.to_json});
upl._setupDragDrop();
new AdminAssets(#{js_opts});
JAVASCRIPT
if options[:description]
opts = [attribute_name, object.class.name, object.id, object.fileupload_guid].map { |i| i.to_s.inspect }.join(', ')
template.concat javascript_tag("$(function(){new AssetDescription(#{opts})})")
end
template.render(partial: "admin/fileupload/#{options[:container] || 'container'}", locals: locals)
end
protected
def object_plural
object_name.to_s.pluralize
end
end
end
end