require 'kiss/form/field';
class Kiss
class Form
class Field
dsl_accessor :name, :type, :form, :currency, :label, :no_label, :prompt, :value, :read_only,
:ignore, :save, :options, :options_value_key, :options_display_key, :options_display_transform,
:required, :unique, :cancel, :columns, :style, :hidden_join, :html, :other, :other_field, :object,
:format, :display_format, :key, :match, :tip, :statement, :attach_errors, :factor, :digest,
:min_value_size, :max_value_size, :choose_here
alias_method :option_value_key, :options_value_key
alias_method :option_display_key, :options_display_key
alias_method :option_display_transform, :options_display_transform
alias_method :min_value_length, :min_value_size
alias_method :max_value_length, :max_value_size
def method_missing(method, *args, &block)
@_form.action.send method, *args, &block
end
def options_keys(value, display)
@_options_value_key = value
@_options_display_key = display
end
alias_method :option_keys, :options_keys
def debug(*args)
@_form.delegate.request.debug(args.first, Kernel.caller[0])
end
def initialize(form, *args, &block)
# defaults
@_form = form
@_save = true
@_currency = nil
@_attrs = args.to_attrs
@_type = :text
@_object = @_form.object
@_save = true
@_attach_errors = true
_instance_variables_set_from_attrs(@_attrs)
instance_eval(&block) if block_given?
@_errors = []
@_format = Kiss::Format.lookup(@_format)
@_display_format = Kiss::Format.lookup(@_display_format)
raise 'field must have a name' unless @_name
@_key ||= @_name
@_label ||= @_name.titleize unless @_type == :submit
# object's value overrides any form field value
# form field value is intended as default in case object value is missing
if @_object && (value = @_object[@_key.to_sym])
@_value = value
end
if @_currency.is_a?(Symbol)
@_currency = case @_currency
when :dollars
'$'
else
''
end
end
if @_options
if @_options[0].is_a?(Array)
@_options_value_key ||= 0
(@_options_display_key ||= (@_options[0].size == 1) ? 0 : 1)
elsif defined?(Kiss::Model) && @_options[0].is_a?(Kiss::Model)
model_klass = @_options[0].class
@_options_value_key ||= model_klass.value_column
@_options_display_key ||= model_klass.display_column
elsif @_options[0].is_a?(Hash)
@_options_value_key ||= :id
@_options_display_key ||= :name
end
end
@_tip = ((legend = @_format.legend) ? "(#{legend})" : nil) unless defined? @_tip
@_form.has_required_fields ||= @_required
end
def other_field_html
return '' unless @_other
other_checked = @_value && !option_pairs.any? {|v, d| v == @_value }
(@_columns ? '
' : ' ') + [
input_tag_html(
{ :value => 'other', :html => { :id => @_name+'.other' } },
other_checked ? 'checked' : ''
),
@_other[:label] || 'Other',
': ',
@_currency.to_s,
input_tag_html({
:type => :text,
:name => @_name+'.other',
:value => other_checked ? value_to_s(@_value) : nil,
:html => {
:onfocus => "document.getElementById('#{@_name}.other').checked = true"
}
}.merge(@_other))
].join
end
def column_layout(elements_html)
if elements_html.empty?
''
elsif @_columns
layout_columns = [@_columns, elements_html.size].min
num_elements_per_column = ((elements_html.size + layout_columns - 1) / layout_columns).to_i
layout_columns = ((elements_html.size + num_elements_per_column - 1) / num_elements_per_column).to_i
style = "style=\"width: #{(100 / layout_columns).to_i - 1}%\""
'
" + elements_html[i * num_elements_per_column, num_elements_per_column].join(' ') + " | "
end.join + '