class FormInput::Parameter

Form parameter.

Localize few parameter methods.

Constants

TRANSLATION_ORDER

Array definining explicit default order of names of parameter options in translation files.

Attributes

code[R]

Name of the parameter as we use it in the form fields and url queries.

form[R]

Form this parameter belongs to.

name[R]

Name of the parameter as we use it internally in our code.

opts[R]

Additional parameter options.

Public Class Methods

new( name, code, opts ) click to toggle source

Initialize new parameter.

# File lib/form_input/core.rb, line 71
def initialize( name, code, opts )
  @name = name.freeze
  @code = code.freeze
  @opts = opts.freeze
end

Public Instance Methods

array?() click to toggle source

Test if this is an array parameter.

# File lib/form_input/core.rb, line 276
def array?
  !! self[ :array ]
end
bind( form ) click to toggle source

Bind self to given form instance. Can be done only once.

# File lib/form_input/core.rb, line 84
def bind( form )
  fail "parameter #{name} is already bound" if @form
  @form = form
  self
end
blank?() click to toggle source

Test if given parameter has blank value.

# File lib/form_input/core.rb, line 135
def blank?
  case v = value
  when nil
    true
  when String
    v.empty? or !! ( v.valid_encoding? && v =~ /\A\s*\z/ )
  when Array, Hash
    v.empty?
  else
    false
  end
end
correct?() click to toggle source

Test if given parameter has value of correct type.

# File lib/form_input/core.rb, line 116
def correct?
  case v = value
  when nil
    true
  when String
    scalar?
  when Array
    array?
  when Hash
    hash?
  end or ( scalar? && [ *self[ :class ] ].any?{ |x| v.is_a?( x ) } )
end
data() click to toggle source

Get data relevant for this parameter, if any. Returns empty array if there are none.

# File lib/form_input/core.rb, line 326
def data
  self[ :data ] || []
end
disabled?() click to toggle source

Test if the parameter is disabled.

# File lib/form_input/core.rb, line 246
def disabled?
  !! self[ :disabled ]
end
empty?() click to toggle source

Test if given parameter has empty value.

# File lib/form_input/core.rb, line 149
def empty?
  case v = value
  when nil
    true
  when String, Array, Hash
    v.empty?
  else
    false
  end
end
enabled?() click to toggle source

Test if the parameter is enabled.

# File lib/form_input/core.rb, line 251
def enabled?
  not disabled?
end
error() click to toggle source

Get first error reported for this parameter. Always nil for unbound parameters.

# File lib/form_input/core.rb, line 221
def error
  errors.first
end
error_title() click to toggle source

Get the title for use in error messages. Fallbacks to normal title and code if no form title was specified.

# File lib/form_input/core.rb, line 211
def error_title
  self[ :error_title ] || title || code.to_s
end
errors() click to toggle source

Get list of errors reported for this paramater. Always empty for unbound parameters.

# File lib/form_input/core.rb, line 216
def errors
  form ? form.errors_for( name ) : []
end
filled?() click to toggle source

Test if given parameter has non-empty value.

# File lib/form_input/core.rb, line 161
def filled?
  not empty?
end
filter() click to toggle source

Get input filter for this paramater, if any.

# File lib/form_input/core.rb, line 311
def filter
  opts[ :filter ]
end
form_name( key = nil ) click to toggle source

Get the proper name for use in form names, adding [] to array and [key] to hash parameters.

# File lib/form_input/core.rb, line 176
def form_name( key = nil )
  if array?
    "#{code}[]"
  elsif hash?
    fail( ArgumentError, "missing hash key" ) if key.nil?
    "#{code}[#{key}]"
  else
    code.to_s
  end
end
form_title() click to toggle source

Get the title for use in form. Fallbacks to normal title and code if no form title was specified.

# File lib/form_input/core.rb, line 206
def form_title
  self[ :form_title ] || title || code.to_s
end
form_value() click to toggle source

Get value of this parameter for use in form/URL, with all scalar values converted to strings.

# File lib/form_input/core.rb, line 105
def form_value
  if array?
    [ *value ].map{ |x| format_value( x ) }
  elsif hash?
    Hash[ [ *value ].map{ |k, v| [ k.to_s, format_value( v ) ] } ]
  else
    format_value( value )
  end
end
format() click to toggle source

Get output filter for this paramater, if any.

# File lib/form_input/core.rb, line 321
def format
  opts[ :format ]
end
format_value( value ) click to toggle source

Format given value for form/URL output, applying the formatting filter as necessary.

# File lib/form_input/core.rb, line 96
def format_value( value )
  if format.nil? or value.nil? or ( value.is_a?( String ) and type = self[ :class ] and type != String )
    value.to_s
  else
    value.instance_exec( &format ).to_s
  end
end
hash?() click to toggle source

Test if this is a hash parameter.

# File lib/form_input/core.rb, line 281
def hash?
  !! self[ :hash ]
end
hidden?() click to toggle source

Test if the parameter is hidden.

# File lib/form_input/core.rb, line 261
def hidden?
  type == :hidden
end
ignored?() click to toggle source

Test if the parameter is to be ignored on output.

# File lib/form_input/core.rb, line 266
def ignored?
  type == :ignore
end
incorrect?() click to toggle source

Test if given parameter has value of incorrect type.

# File lib/form_input/core.rb, line 130
def incorrect?
  not correct?
end
initialize_dup( other ) click to toggle source

Allow copies to evaluate tags again.

Calls superclass method
# File lib/form_input/core.rb, line 78
def initialize_dup( other )
  super
  @tags = nil
end
invalid?() click to toggle source

Test if this parameter had some errors reported.

# File lib/form_input/core.rb, line 231
def invalid?
  not valid?
end
optional?() click to toggle source

Test if the parameter is optional.

# File lib/form_input/core.rb, line 241
def optional?
  not required?
end
required?() click to toggle source

Test if the parameter is required.

# File lib/form_input/core.rb, line 236
def required?
  !! self[ :required ]
end
scalar?() click to toggle source

Test if this is a scalar parameter.

# File lib/form_input/core.rb, line 286
def scalar?
  not ( array? || hash? )
end
selected?( value ) click to toggle source

Test if given value is the selected value, for use in form selects.

# File lib/form_input/core.rb, line 188
def selected?( value )
  if empty?
    false
  elsif array?
    self.value.include?( value )
  elsif hash?
    false
  else
    self.value == value
  end
end
set?() click to toggle source

Test if value of given parameter was set.

# File lib/form_input/core.rb, line 166
def set?
  form ? form.instance_variable_defined?( "@#{name}" ) : false
end
tagged?( *tags ) click to toggle source

Test if the parameter is tagged with some of given tags, or any tag if the argument list is empty.

# File lib/form_input/core.rb, line 296
def tagged?( *tags )
  t = self.tags
  if tags.empty?
    not t.empty?
  else
    tags.flatten.any?{ |x| t.include? x }
  end
end
tags() click to toggle source

Get list of tags of this parameter.

# File lib/form_input/core.rb, line 291
def tags
  @tags ||= [ *self[ :tag ], *self[ :tags ] ]
end
title() click to toggle source

Get the name of the parameter to be displayed to the user, or nil if there is none.

# File lib/form_input/core.rb, line 201
def title
  self[ :title ]
end
transform() click to toggle source

Get input transform for this paramater, if any.

# File lib/form_input/core.rb, line 316
def transform
  opts[ :transform ]
end
translation_hash() click to toggle source

Get hash of all parameter values which may need to be localized.

# File lib/form_input/localize.rb, line 25
def translation_hash
  Hash[ opts.select{ |k, v| v.is_a? String }.sort_by{ |k, v| [ translation_order( k ), k ] } ]
end
translation_order( name ) click to toggle source

Get translation order for given option name.

# File lib/form_input/localize.rb, line 20
def translation_order( name )
  TRANSLATION_ORDER.index( name.to_s ) || TRANSLATION_ORDER.count
end
type() click to toggle source

Get type of the parameter. Defaults to :text.

# File lib/form_input/core.rb, line 256
def type
  self[ :type ] || :text
end
unset?() click to toggle source

Test if value of given parameter is not set.

# File lib/form_input/core.rb, line 171
def unset?
  not set?
end
untagged?( *tags ) click to toggle source

Test if the parameter is not tagged with any of given tags, or any tag if the argument list is empty.

# File lib/form_input/core.rb, line 306
def untagged?( *tags )
  not tagged?( *tags )
end
valid?() click to toggle source

Test if this parameter had no errors reported.

# File lib/form_input/core.rb, line 226
def valid?
  errors.empty?
end
validate() click to toggle source

Validate this parameter. Does nothing if it was found invalid already.

# File lib/form_input/core.rb, line 375
def validate
  return if invalid?

  # First of all, make sure required parameters are present and not empty.

  if required? && empty?
    report( self[ :required_msg ] || ( scalar? ? :required_scalar : :required_array ) )
    return
  end

  # Otherwise empty parameters are considered correct, as long as the type is correct.

  return if empty? && correct?

  # Make sure the parameter value contains only valid data.

  return unless if array?
    validate_array( value )
  elsif hash?
    validate_hash( value )
  else
    validate_value( value )
  end

  # Finally, invoke the custom check callbacks if there are any.

  if checks = opts[ :check ]
    [ *checks ].each{ |x| instance_exec( &x ) }
  end
end
value() click to toggle source

Get the value of this parameter. Always nil for unbound parameters.

# File lib/form_input/core.rb, line 91
def value
  form ? form[ name ] : nil
end
visible?() click to toggle source

Test if the parameter is visible.

# File lib/form_input/core.rb, line 271
def visible?
  not ( hidden? || ignored? )
end

Private Instance Methods

validate_array( value ) click to toggle source

Validate given array. Return true if the entire array validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 410
def validate_array( value )

  # Make sure it's an array in the first place.

  unless value.is_a? Array
    report( :not_array )
    return
  end

  # Enforce array limits.

  return unless validate_count( value )

  # Now validate array elements. If we detect problems, don't bother with the rest.

  value.all?{ |v| validate_value( v ) }
end
validate_count( value ) click to toggle source

Validate container limits. Return true if it validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 486
def validate_count( value )

  if limit = self[ :min_count ] and value.count < limit
    report( :min_count, limit, 'element' )
    return
  end

  if limit = self[ :max_count ] and value.count > limit
    report( :max_count, limit, 'element' )
    return
  end

  true
end
validate_hash( value ) click to toggle source

Validate given hash. Return true if the entire hash validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 430
def validate_hash( value )

  # Make sure it's a hash in the first place.

  unless value.is_a? Hash
    report( :not_hash )
    return
  end

  # Enforce hash limits.

  return unless validate_count( value )

  # Now validate hash keys and values. If we detect problems, don't bother with the rest.

  value.all?{ |k, v| validate_key( k ) && validate_value( v ) }
end
validate_key( value ) click to toggle source

Validate given hash key. Return true if it validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 450
def validate_key( value )

  # If there is a key pattern specified, make sure the key matches.

  if patterns = self[ :match_key ]
    unless [ *patterns ].all?{ |x| value.to_s =~ x }
      report( :match_key )
      return
    end
    return true
  end

  # Otherwise make sure it's an integer.

  unless value.is_a? Integer
    report( :invalid_key )
    return
  end

  # Make sure it is within allowed limits.

  if limit = self[ :min_key ] and value < limit
    report( :min_key )
    return
  end

  if limit = self[ :max_key ] and value > limit
    report( :max_key )
    return
  end

  true
end
validate_string( value ) click to toggle source

Validate given string. Return true if it validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 550
def validate_string( value )

  # Make sure it's a string in the first place.

  unless value.is_a? String
    report( scalar? ? :not_string : :element_type )
    return
  end

  # Make sure the string contains only valid data.

  unless value.valid_encoding? && ( value.encoding == DEFAULT_ENCODING || value.ascii_only? )
    report( :invalid_encoding )
    return
  end

  unless value =~ /\A(\p{Graph}|[ \t\r\n])*\z/u
    report( :invalid_characters )
    return
  end

  # Enforce any size limits.

  if limit = self[ :min_size ] and value.size < limit
    report( :min_size, limit, 'character' )
    return
  end

  if limit = self[ :min_bytesize ] and value.bytesize < limit
    report( :min_bytesize, limit, 'byte' )
    return
  end

  if limit = self[ :max_size ] and value.size > limit
    report( :max_size, limit, 'character' )
    return
  end

  if limit = self[ :max_bytesize ] and value.bytesize > limit
    report( :max_bytesize, limit, 'byte' )
    return
  end

  # Finally make sure the format is valid.

  if patterns = self[ :reject ]
    if [ *patterns ].any?{ |x| value =~ x }
      report( self[ :reject_msg ] || self[ :msg ] || :reject_msg )
      return
    end
  end

  if patterns = self[ :match ]
    unless [ *patterns ].all?{ |x| value =~ x }
      report( self[ :match_msg ] || self[ :msg ] || :match_msg )
      return
    end
  end

  true
end
validate_value( value ) click to toggle source

Validate given scalar value. Return true if it validated correctly, nil or false otherwise.

# File lib/form_input/core.rb, line 503
def validate_value( value )

  # First apply the type tests.

  if type = self[ :class ] and type != String
    unless [ *type ].any?{ |x| value.is_a?( x ) }
      report( scalar? ? :value_type : :element_type )
      return
    end
  else
    return unless validate_string( value )
  end

  # Then enforce any value limits.

  if limit = self[ :min ] and value.to_f < limit.to_f
    report( :min_limit, limit )
    return
  end

  if limit = self[ :max ] and value.to_f > limit.to_f
    report( :max_limit, limit )
    return
  end

  if limit = self[ :inf ] and value.to_f <= limit.to_f
    report( :inf_limit, limit )
    return
  end

  if limit = self[ :sup ] and value.to_f >= limit.to_f
    report( :sup_limit, limit )
    return
  end

  # Finally, invoke the custom callbacks if there are any.

  if tests = opts[ :test ]
    [ *tests ].each{ |x| instance_exec( value, &x ) }
    return unless valid?
  end

  true
end