module ActiveScaffold::Helpers::FormColumnHelpers
Helpers that assist with the rendering of a Form Column
Helpers that assist with the rendering of a Form Column
Public Instance Methods
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 355 def active_scaffold_add_existing_input(options) if ActiveScaffold.js_framework == :prototype && controller.respond_to?(:record_select_config, true) remote_controller = active_scaffold_controller_for(record_select_config.model).controller_path options.merge!(:controller => remote_controller) options.merge!(active_scaffold_input_text_options) record_select_field(options[:name], @record, options) else select_options = options_for_select(options_for_association(nested.association)) #unless column.through_association? select_options ||= options_for_select(active_scaffold_config.model.to_a.collect {|c| [h(c.to_label), c.id]}) select_tag 'associated_id', ('<option value="">' + as_(:_select_) + '</option>' + select_options).html_safe unless select_options.empty? end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 368 def active_scaffold_add_existing_label if controller.respond_to?(:record_select_config, true) record_select_config.model.model_name.human else active_scaffold_config.model.model_name.human end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 139 def active_scaffold_checkbox_list(column, select_options, associated_ids, options) html = "<ul class=\"checkbox-list\" id=\"#{options[:id]}\">" select_options.each_with_index do |option, i| label, id = option this_id = "#{options[:id]}_#{i}_id" html << content_tag(:li) do check_box_tag("#{options[:name]}[]", id, associated_ids.include?(id), :id => this_id) << content_tag(:label, h(label), :for => this_id) end end html << '</ul>' html << javascript_tag("new DraggableLists('#{options[:id]}')") if column.options[:draggable_lists] html.html_safe end
Column.type-based inputs
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 248 def active_scaffold_input_boolean(column, options) select_options = [] select_options << [as_(:_select_), nil] if !column.virtual? && column.column.null select_options << [as_(:true), true] select_options << [as_(:false), false] select_tag(options[:name], options_for_select(select_options, @record.send(column.name)), options) end
# File lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb, line 4 def active_scaffold_input_carrierwave(column, options) options = active_scaffold_input_text_options(options) carrierwave = @record.send("#{column.name}") if !carrierwave.file.blank? remove_field_options = { :name => options[:name].gsub(/\[#{column.name}\]$/, "[remove_#{column.name}]"), :id => 'remove_' + options[:id], :value => false } cache_field_options = { :name => options[:name].gsub(/\[#{column.name}\]$/, "[#{column.name}_cache]"), :id => options[:id] + '_cache' } if ActiveScaffold.js_framework == :jquery js_remove_file_code = "$(this).prev('input#remove_#{options[:id]}').val('true'); $(this).parent().hide().next().show(); return false;"; js_dont_remove_file_code = "$(this).parents('div.carrierwave_controls').find('input#remove_#{options[:id]}').val('false'); return false;"; else js_remove_file_code = "$(this).previous('input#remove_#{options[:id]}').value='true'; $(this).up().hide().next().show(); return false;"; js_dont_remove_file_code = "$(this).up('div.carrierwave_controls').down('input#remove_#{options[:id]}').value='false'; return false;"; end input = file_field(:record, column.name, options.merge(:onchange => js_dont_remove_file_code)) content_tag( :div, content_tag(:div, ( get_column_value(@record, column) + " | " + hidden_field(:record, "#{column.name}_cache", cache_field_options) + hidden_field(:record, "remove_#{column.name}", remove_field_options) + content_tag(:a, as_(:remove_file), {:href => '#', :onclick => js_remove_file_code}) ).html_safe ) + content_tag(:div, input, :style => "display: none"), :class => 'carrierwave_controls' ) else file_field(:record, column.name, options) end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 231 def active_scaffold_input_checkbox(column, options) check_box(:record, column.name, options) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 160 def active_scaffold_input_enum(column, html_options) options = { :selected => @record.send(column.name) } options_for_select = column.options[:options].collect do |text, value| active_scaffold_translated_option(column, text, value) end html_options.update(column.options[:html_options] || {}) options.update(column.options) select(:record, column.name, options_for_select, options, html_options) end
# File lib/active_scaffold/bridges/file_column/lib/form_ui.rb, line 5 def active_scaffold_input_file_column(column, options) if @record.send(column.name) # we already have a value? display the form for deletion. if ActiveScaffold.js_framework == :jquery js_remove_file_code = "$(this).prev().val('true'); $(this).parent().hide().next().show(); return false;"; else js_remove_file_code = "$(this).previous().value='true'; p=$(this).up(); p.hide(); p.next().show(); return false;"; end content_tag( :div, content_tag( :div, get_column_value(@record, column) + " " + hidden_field(:record, "delete_#{column.name}", :value => "false") + " | " + content_tag(:a, as_(:remove_file), {:href => '#', :onclick => js_remove_file_code}), {} ) + content_tag( :div, file_column_field("record", column.name, options), :style => "display: none" ), {} ) else # no, just display the file_column_field file_column_field("record", column.name, options) end end
This method decides which input to use for the given column. It does not do any rendering. It only decides which method is responsible for rendering.
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 7 def active_scaffold_input_for(column, scope = nil, options = {}) options = active_scaffold_input_options(column, scope, options) options = update_columns_options(column, scope, options) active_scaffold_render_input(column, options) end
the standard active scaffold options used for class, name and scope
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 57 def active_scaffold_input_options(column, scope = nil, options = {}) name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]" # Fix for keeping unique IDs in subform id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}" id_control += scope.gsub(/(\[|\])/, '_').gsub('__', '_').gsub(/_$/, '') if scope { :name => name, :class => "#{column.name}-input", :id => id_control}.merge(options) end
# File lib/active_scaffold/bridges/paperclip/lib/form_ui.rb, line 4 def active_scaffold_input_paperclip(column, options) options = active_scaffold_input_text_options(options) input = file_field(:record, column.name, options) paperclip = @record.send("#{column.name}") if paperclip.file? if ActiveScaffold.js_framework == :jquery js_remove_file_code = "$(this).prev().val('true'); $(this).parent().hide().next().show(); return false;"; else js_remove_file_code = "$(this).previous().value='true'; $(this).up().hide().next().show(); return false;"; end content = active_scaffold_column_paperclip(column, @record) content_tag(:div, content + " | " + hidden_field(:record, "delete_#{column.name}", :value => "false") + content_tag(:a, as_(:remove_file), {:href => '#', :onclick => js_remove_file_code}) ) + content_tag(:div, input, :style => "display: none") else input end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 235 def active_scaffold_input_password(column, options) options = active_scaffold_input_text_options(options) password_field :record, column.name, options.merge(column.options) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 131 def active_scaffold_input_plural_association(column, options) associated_options = @record.send(column.association.name).collect {|r| [r.to_label, r.id]} select_options = associated_options | options_for_association(column.association) return content_tag(:span, as_(:no_options), :id => options[:id]) if select_options.empty? active_scaffold_checkbox_list(column, select_options, associated_options.collect {|a| a[1]}, options) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 180 def active_scaffold_input_radio(column, html_options) html_options.update(column.options[:html_options] || {}) column.options[:options].inject('') do |html, (text, value)| text, value = active_scaffold_translated_option(column, text, value) html << content_tag(:label, radio_button(:record, column.name, value, html_options.merge(:id => html_options[:id] + '-' + value.to_s)) + text) end.html_safe end
requires RecordSelect plugin to be installed and configured. … maybe this should be provided in a bridge?
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 190 def active_scaffold_input_record_select(column, options) if column.singular_association? multiple = false multiple = column.options[:html_options][:multiple] if column.options[:html_options] && column.options[:html_options][:multiple] active_scaffold_record_select(column, options, @record.send(column.name), multiple) elsif column.plural_association? active_scaffold_record_select(column, options, @record.send(column.name), true) end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 170 def active_scaffold_input_select(column, html_options) if column.singular_association? active_scaffold_input_singular_association(column, html_options) elsif column.plural_association? active_scaffold_input_plural_association(column, html_options) else active_scaffold_input_enum(column, html_options) end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 114 def active_scaffold_input_singular_association(column, html_options) associated = @record.send(column.association.name) select_options = options_for_association(column.association) select_options.unshift([ associated.to_label, associated.id ]) unless associated.nil? or select_options.find {|label, id| id == associated.id} selected = associated.nil? ? nil : associated.id method = column.name #html_options[:name] += '[id]' options = {:selected => selected, :include_blank => as_(:_select_)} html_options.update(column.options[:html_options] || {}) options.update(column.options) html_options[:name] = "#{html_options[:name]}[]" if (html_options[:multiple] == true && !html_options[:name].to_s.ends_with?("[]")) select(:record, method, select_options.uniq, options, html_options) end
Form input methods
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 85 def active_scaffold_input_text_field(column, options) if column.column.nil? options = active_scaffold_input_text_options(options) if column.association associated = @record.send(column.association.name) options[:value] = associated.id end else text_types = [:text, :string, :integer, :float, :decimal, :date, :time, :datetime] options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type) if column.column.type == :string && options[:maxlength].blank? options[:maxlength] = column.column.limit options[:size] ||= options[:maxlength].to_i > 30 ? 30 : options[:maxlength] end options[:include_blank] = true if column.column.null and [:date, :datetime, :time].include?(column.column.type) options[:value] = format_number_value(@record.send(column.name), column.options) if column.column.number? end text_field(:record, column.name, options.merge(column.options)) end
the standard active scaffold options used for textual inputs
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 50 def active_scaffold_input_text_options(options = {}) options[:autocomplete] = 'off' options[:class] = "#{options[:class]} text-input".strip options end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 240 def active_scaffold_input_textarea(column, options) text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size])) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 200 def active_scaffold_record_select(column, options, value, multiple) unless column.association raise ArgumentError, "record_select can only work against associations (and #{column.name} is not). A common mistake is to specify the foreign key field (like :user_id), instead of the association (:user)." end remote_controller = active_scaffold_controller_for(column.association.klass).controller_path # if the opposite association is a :belongs_to (in that case association in this class must be has_one or has_many) # then only show records that have not been associated yet if [:has_one, :has_many].include?(column.association.macro) params.merge!({column.association.foreign_key => ''}) end record_select_options = {:controller => remote_controller, :id => options[:id]} record_select_options.merge!(active_scaffold_input_text_options) record_select_options.merge!(column.options) record_select_options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"] unless defined?(ActionView::Helpers::Tags::DateSelect) unless options['data-update_url'].nil? record_select_options['data-update_url'] = options['data-update_url'] record_select_options['data-update_send_form'] = options['data-update_send_form'] record_select_options[:class] = "#{record_select_options[:class]} #{options[:class]}".strip end if multiple record_multi_select_field(options[:name], value || [], record_select_options) else record_select_field(options[:name], value || column.association.klass.new, record_select_options) end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 15 def active_scaffold_render_input(column, options) begin # first, check if the dev has created an override for this specific field if override_form_field?(column) send(override_form_field(column), @record, options) # second, check if the dev has specified a valid form_ui for this column elsif column.form_ui and override_input?(column.form_ui) send(override_input(column.form_ui), column, options) # fallback: we get to make the decision else if column.association if column.form_ui.nil? # its an association and nothing is specified, we will assume form_ui :select active_scaffold_input_select(column, options) else # if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about. raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'" end else # regular model attribute column # if we (or someone else) have created a custom render option for the column type, use that if !column.virtual? && override_input?(column.column.type) send(override_input(column.column.type), column, options) # final ultimate fallback: use rails' generic input method else active_scaffold_input_text_field(column, options) end end end rescue Exception => e logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}" raise e end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 155 def active_scaffold_translated_option(column, text, value = nil) value = text if value.nil? [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value] end
Macro-level rendering decisions for columns
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 335 def column_renders_as(column) if column.is_a? ActiveScaffold::DataStructures::ActionColumns return :subsection elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden return :hidden elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform) return :field else return :subform end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 347 def column_scope(column) if column.plural_association? "[#{column.name}][#{@record.id || generate_temporary_id}]" else "[#{column.name}]" end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 309 def form_partial_for_column(column, renders_as = nil) renders_as ||= column_renders_as(column) if override_form_field_partial?(column) override_form_field_partial(column) elsif renders_as == :field or override_form_field?(column) "form_attribute" elsif renders_as == :subform "form_association" elsif renders_as == :hidden "form_hidden_attribute" end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 257 def onsubmit end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 287 def override_form_field(column) method_with_class = override_form_field_name(column, true) return method_with_class if respond_to?(method_with_class) method = override_form_field_name(column) method if respond_to?(method) end
the naming convention for overriding form fields with helpers
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 296 def override_form_field_name(column, class_prefix = false) "#{clean_class_name(column.active_record_class.name) + '_' if class_prefix}#{clean_column_name(column.name)}_form_column" end
the naming convention for overriding form fields with partials
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 278 def override_form_field_partial(column) begin path = active_scaffold_controller_for(column.active_record_class).controller_path File.join(path, "#{clean_column_name(column.name)}_form_column") rescue ActiveScaffold::ControllerNotFound => e nil end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 273 def override_form_field_partial?(column) template_exists?(override_form_field_partial(column), true) end
the naming convention for overriding form input types with helpers
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 305 def override_input(form_ui) "active_scaffold_input_#{form_ui}" end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 300 def override_input?(form_ui) respond_to?(override_input(form_ui)) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 269 def override_subform_partial(column, subform_partial) File.join(active_scaffold_controller_for(column.association.klass).controller_path, subform_partial) if column_renders_as(column) == :subform end
add functionality for overriding subform partials from association class path
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 265 def override_subform_partial?(column, subform_partial) template_exists?(override_subform_partial(column, subform_partial), true) end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 322 def subform_partial_for_column(column) subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform" if override_subform_partial?(column, subform_partial) override_subform_partial(column, subform_partial) else subform_partial end end
# File lib/active_scaffold/helpers/form_column_helpers.rb, line 67 def update_columns_options(column, scope, options) if column.update_columns form_action = params[:action] == 'edit' ? :update : :create url_params = {:action => 'render_field', :id => params[:id], :column => column.name, :update_columns => column.update_columns} url_params[:eid] = params[:eid] if params[:eid] url_params[:controller] = controller.class.active_scaffold_controller_for(@record.class).controller_path if scope url_params[:scope] = params[:scope] if scope options[:class] = "#{options[:class]} update_form".strip options['data-update_url'] = url_for(url_params) options['data-update_send_form'] = true if column.send_form_on_update_column end options end