class AdminAssistant class Column def form_view(action_view, admin_assistant, opts = {}) view 'FormView', action_view, admin_assistant, opts end def index_view(action_view, admin_assistant, opts = {}) view 'IndexView', action_view, admin_assistant, opts end def search_view(action_view, admin_assistant, opts = {}) view 'SearchView', action_view, admin_assistant, opts end def show_view(action_view, admin_assistant, opts = {}) view 'ShowView', action_view, admin_assistant, opts end def verify_for_search # nothing here, maybe implemented in subclasses end def view(view_class_name, action_view, admin_assistant, opts) klass = begin self.class.const_get view_class_name rescue NameError AdminAssistant::Column.const_get view_class_name end klass.new self, action_view, admin_assistant, opts end module FormViewMethods def after_html(rails_form) after = render_from_custom_template("_after_#{name}_input", rails_form) if after after else helper_method = "after_#{name}_input" if @action_view.respond_to?(helper_method) @action_view.raw( @action_view.send(helper_method, rails_form.object) ) end end end def description @description end def errors(record) record.errors[name] end def html(rails_form) record = rails_form.object hff = render_from_custom_template "_#{name}_input", rails_form hff ||= html_from_helper_method(record) hff ||= if @read_only value record elsif @write_once && @action_view.action_name == 'edit' value record else default_html rails_form end if ah = after_html(rails_form) hff << ah end hff end def html_from_helper_method(record) html_method = "#{name}_input" if @action_view.respond_to?(html_method) @action_view.send(html_method, record) end end def field_id "#{@model_class.name.underscore}_#{name}" end def render_from_custom_template(slug, rails_form) if File.exist?(custom_template_file_path(slug)) varname = @model_class.name.underscore @action_view.instance_variable_set( "@#{varname}".to_sym, rails_form.object ) locals = {varname.to_sym => rails_form.object, :form => rails_form} if rails_form.respond_to?(:prefix) locals[:prefix] = rails_form.prefix @action_view.instance_variable_set(:@prefix, rails_form.prefix) end @action_view.render( :file => file_option_for_custom_template_render(slug), :locals => locals ) end end def set_instance_variables_from_options(admin_assistant, opts) setting = admin_assistant.form_settings[name.to_sym] ivars = %w( clear_link datetime_select_options date_select_options description image_size input select_choices select_options text_area_options ) ivars.each do |ivar| instance_variable_set "@#{ivar}".to_sym, setting.send(ivar) end if @action_view.respond_to?(name + '_url') @file_url_method = @action_view.method(name + '_url') end @read_only = setting.read_only? @write_once = setting.write_once? end end module IndexViewMethods def header_css_class "sort #{sort_order}" if sort_order end def html(record) html_for_index_method = "#{name}_html_for_index" html = if @action_view.respond_to?(html_for_index_method) @action_view.send html_for_index_method, record elsif @link_to_args @action_view.link_to( @action_view.send(:h, string(record)), @link_to_args.call(record) ) else unconfigured_html(record) end html = ' ' if html.blank? html end def next_sort_params name_for_sort = name next_sort_order = 'asc' if sort_order if sort_order == 'asc' next_sort_order = 'desc' else name_for_sort = nil next_sort_order = nil end end @action_view.params.merge( :sort => name_for_sort, :sort_order => next_sort_order ) end def set_instance_variables_from_options(admin_assistant, opts) index = opts[:index] setting = admin_assistant.index_settings[name.to_sym] @link_to_args = setting.link_to_args @sort_order = index.sort_order if name == index.sort @image_size = setting.image_size @ajax_toggle_allowed = admin_assistant.update? && setting.ajax_toggle != false end def td_css_classes(column, record) css_classes = [] css_classes << 'sort' if sort_order td_css_class_for_index_method = "#{name}_css_class_for_index_td" if @action_view.respond_to?(td_css_class_for_index_method) css_classes << @action_view.send(td_css_class_for_index_method, record) end css_classes.reject{ |c| c.blank? }.join(' ') end def unconfigured_html(record) @action_view.send(:h, string(record)) end end module SearchViewMethods def set_instance_variables_from_options(admin_assistant, opts) setting = admin_assistant.search_settings[name.to_sym] unless setting.comparators == false @comparators = :all end @search = opts[:search] @blank_checkbox = setting.blank_checkbox @compare_to_range = setting.compare_to_range end end module SimpleColumnSearchViewMethods include SearchViewMethods def blank_checkbox_html(form) check_box_and_hidden_tags( "search[#{name}(blank)]", form.object.blank?(@column.name) ) + "is blank" end def boolean_input(form) opts = [['', nil]] if @boolean_labels opts << [@boolean_labels.first, true] opts << [@boolean_labels.last, false] else opts << ['true', true] opts << ['false', false] end form.select(name, opts) end def comparator_html(search) selected_comparator = search.comparator(@column.name) || '=' option_tags = comparator_opts.map { |text, value| opt = "" }.join("\n") @action_view.select_tag( "search[#{name}(comparator)]", @action_view.raw(option_tags) ) end def comparator_opts [ ['greater than', '>'], ['greater than or equal to', '>='], ['equal to', '='], ['less than or equal to', '<='], ['less than', '<'] ] end def datetime_input(form) input = '' if @compare_to_range input = datetime_range_input(form) else input << comparator_html(form.object) << ' ' if @comparators == :all input << form.datetime_select(name, :include_blank => true) input << @action_view.send( :link_to, 'Clear', '#', 'data-prefix' => "search_#{name.underscore}", :class => 'clear_datetime_select' ) end input end def datetime_range_end_point_input(form, comparator, label) input = "#{label} " input << ActionView::Helpers::DateTimeSelector.new( form.object.send(name)[comparator], :prefix => "search", :field_name => comparator.to_s, :include_position => true, :index => name, :include_blank => true, :datetime_separator => ' — ', :time_separator => ' : ' ).select_datetime input << @action_view.send( :link_to, 'Clear', '#', 'data-prefix' => "search_#{name.underscore}_#{comparator}", :class => 'clear_datetime_select' ) input end def datetime_range_input(form) input = '' input << datetime_range_end_point_input(form, :gt, 'After') input << "   " input << datetime_range_end_point_input(form, :lt, 'Before') input end def html(form) input = '' if @column.field_type == :boolean input = boolean_input form elsif @column.field_type == :datetime input = datetime_input form else if @compare_to_range input << "Greater than " input << @action_view.send( :text_field_tag, "search[#{name}][gt]", form.object.send(name)[:gt] ) input << "   Less than " input << @action_view.send( :text_field_tag, "search[#{name}][lt]", form.object.send(name)[:lt] ) else if @column.field_type == :integer && @comparators == :all input << comparator_html(form.object) << ' ' end input << form.text_field(name) input << blank_checkbox_html(form) if @blank_checkbox end end "


#{input}

" end end module ShowViewMethods def html(record) slug = "_#{name}_for_show" if File.exist?(custom_template_file_path(slug)) varname = @model_class.name.underscore @action_view.instance_variable_set("@#{varname}".to_sym, record) locals = {varname.to_sym => record} @action_view.render( :file => file_option_for_custom_template_render(slug), :locals => locals ) else @action_view.send(:h, string(record)) end end end class View attr_reader :sort_order def initialize(column, action_view, admin_assistant, opts = {}) @column, @action_view, @opts = column, action_view, opts @model_class = admin_assistant.model_class base_setting = admin_assistant[name] @boolean_labels = base_setting.boolean_labels @strftime_format = base_setting.strftime_format fem_name = name + '_exists?' if @action_view.respond_to?(fem_name) @file_exists_method = @action_view.method(fem_name) end @label = base_setting.label @polymorphic_types = base_setting.polymorphic_types if respond_to?(:set_instance_variables_from_options) set_instance_variables_from_options(admin_assistant, opts) end end def check_box_and_hidden_tags(input_name, value) @action_view.send(:hidden_field_tag, input_name, '0', :id => "#{input_name}_hidden") + @action_view.send(:check_box_tag, input_name, '1', value) end def controller @action_view.controller end def custom_template_file_path(slug) File.join( Rails.root, 'app/views', controller.controller_path, "#{slug}.html.erb" ) end def file_option_for_custom_template_render(slug) custom_template_file_path slug end def label if @label @label elsif @column.name.to_s == 'id' 'ID' else @column.name.to_s.capitalize.gsub(/_/, ' ') end end def name @column.name end def paperclip? @column.is_a?(PaperclipColumn) end def sort_possible?(total_entries) @column.is_a?(ActiveRecordColumn) || (@column.is_a?(BelongsToColumn) && total_entries < 100_000) end def string(record) string_method = "#{@column.name}_string" if @action_view.respond_to?(string_method) @action_view.send string_method, record else value = value(record) if @boolean_labels value ? @boolean_labels.first : @boolean_labels.last elsif value.respond_to?(:strftime) && @strftime_format value.strftime @strftime_format else value.to_s end end end def value(record) value_method = "#{name}_value" if @action_view.respond_to?(value_method) @action_view.send value_method, record else record.send(name) if record.respond_to?(name) end end end class FormView < View include FormViewMethods end class IndexView < View include IndexViewMethods end class SearchView < View include SearchViewMethods end class ShowView < View include ShowViewMethods end end end