Class: Formless

Inherits:
Object
  • Object
show all
Defined in:
lib/formless.rb

Constant Summary collapse

VERSION =
'0.1'
DATE_FORMAT =
'%d/%m/%Y'
DATETIME_FORMAT =
'%d/%m/%Y %l:%M%P'
FieldSetters =
{
  textarea: proc { |node, values|
    node.content = values.shift
  },
  radio: proc { |node, values|
    node.delete('checked')
    node['checked'] = 'checked' if values.include? node['value']
  },
  checkbox: proc { |node, values|
    node.delete('checked')
    node['checked'] = 'checked' if values.include? node['value']
  },
  select: proc { |node, values|
    matches = node.css('option').to_a.each { |n| n.delete('selected') }.find_all do |n|
      n.has_attribute?('value') ? values.include?(n['value']) : values.include?(n.content)
    end
    if !matches.empty?
      if node.has_attribute? 'multiple'
        matches.each { |n| n['selected'] = 'selected' }
      else
        matches.first['selected'] = 'selected'
      end
    elsif !node.has_attribute?('multiple') && value = values.compact.first
      node << node.document.create_element('option', value, selected: 'selected')
    end
  },
  password: proc { |node, values|
    node['value'] = values.shift if options[:populate_passwords]
  },
  default: proc { |node, values|
    node['value'] = values.shift
  }
}
Formatters =
{
  [Date, Time] => proc { |node, value|
    case node['type']
    when 'date'
      value.strftime('%F')
    when 'datetime'
      value.strftime('%FT%T%z')
    when 'datetime-local'
      value.strftime('%FT%T')
    when 'week'
      value.strftime('%G-W%V')
    when 'month'
      value.strftime('%G-%m')
    else
      (value.respond_to? :hour) ? value.strftime(DATETIME_FORMAT) : value.strftime(DATE_FORMAT)
    end
  },
  nil => proc { '' }
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(html, selector = nil, **options) ⇒ Formless

Returns a new instance of Formless.



79
80
81
82
83
84
85
86
87
# File 'lib/formless.rb', line 79

def initialize(html, selector = nil, **options)
  self.nodeset = html
  self.selector = selector
  @options = {
    field_setters: FieldSetters,
    formatters: Formatters,
    populate_passwords: false
  }.merge!(options)
end

Instance Attribute Details

#nodesetObject

Returns the value of attribute nodeset.



65
66
67
# File 'lib/formless.rb', line 65

def nodeset
  @nodeset
end

#optionsObject (readonly)

Returns the value of attribute options.



64
65
66
# File 'lib/formless.rb', line 64

def options
  @options
end

#selectorObject

Returns the value of attribute selector.



63
64
65
# File 'lib/formless.rb', line 63

def selector
  @selector
end

Instance Method Details

#field_settersObject



89
90
91
# File 'lib/formless.rb', line 89

def field_setters
  self.options[:field_setters]
end

#formattersObject



93
94
95
# File 'lib/formless.rb', line 93

def formatters
  self.options[:formatters]
end

#populate(values, selector = nil, nodeset = self.nodeset) ⇒ Object



97
98
99
# File 'lib/formless.rb', line 97

def populate(values, selector = nil, nodeset = self.nodeset)
  populate!(values, selector, Nokogiri::XML::NodeSet.new(nodeset.document, nodeset.to_a.map! { |n| n.dup }))
end

#populate!(values, selector = nil, nodeset = self.nodeset) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/formless.rb', line 101

def populate!(values, selector = nil, nodeset = self.nodeset)
  nodeset = selector ? nodeset.css(selector) : nodeset
  values.each do |field, value|
    nodes = nodeset.css(%{[name="#{field}"]})
    nodes = nodeset.css(%{[name="#{field}[]"]}) if nodes.empty?
    nodes.each { |n| set_field(n, value) }
  end
  nodeset
end