Class: Nitro::FormHelper::FormXmlBuilder

Inherits:
Glue::XmlBuilder show all
Defined in:
lib/nitro/helper/form.rb

Overview

A specialized Builder for dynamically building of forms. Provides extra support for forms backed by managed objects (entities). – TODO: allow multiple objects per form. TODO: use more generalized controls. ++

Instance Attribute Summary

Attributes inherited from Glue::XmlBuilder

#target

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Glue::XmlBuilder

#<<, #to_s

Constructor Details

#initialize(buffer = '', options = {}) ⇒ FormXmlBuilder

Returns a new instance of FormXmlBuilder.



74
75
76
77
78
# File 'lib/nitro/helper/form.rb', line 74

def initialize(buffer = '', options = {})
  super
  @obj = options[:object]
  @errors = options[:errors]
end

Class Method Details

.control_for(obj, a, anno, options) ⇒ Object

Returns a control for the given objects attribute.



60
61
62
63
64
# File 'lib/nitro/helper/form.rb', line 60

def self.control_for(obj, a, anno, options)
  name = anno[:control] || anno[:class].to_s.demodulize.underscore.to_sym
  control_class = self.control_map.fetch(name, NoneControl)
  return control_class.new(obj, a, options) 
end

.control_for_relation(obj, rel, options) ⇒ Object

Returns a control for the given objects relation.



68
69
70
71
72
# File 'lib/nitro/helper/form.rb', line 68

def self.control_for_relation(obj, rel, options)
  name = rel[:control] || rel.class.to_s.demodulize.underscore.to_sym
  control_class = self.control_map.fetch(name, NoneControl)
  return control_class.new(obj, rel, options) 
end

Instance Method Details

#all_attributes(options = {}) ⇒ Object Also known as: attributes, serializable_attributes

Render controls for all attributes of the form object. It only considers serializable attributes.



96
97
98
99
100
101
102
103
104
# File 'lib/nitro/helper/form.rb', line 96

def all_attributes(options = {})
  for a in @obj.class.serializable_attributes
    prop = @obj.class.ann(a)
    unless options[:all]
      next if a == @obj.class.primary_key or prop[:control] == :none or prop[:relation] or [options[:exclude]].flatten.include?(a)
    end
    attribute a, options
  end
end

#all_relations(options = {}) ⇒ Object Also known as: relations

Render controls for all relations of the form object.



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/nitro/helper/form.rb', line 131

def all_relations(options = {})
  for rel in @obj.class.relations
    unless options[:all]
      # Ignore polymorphic_marker relations.
      #--
      # gmosx: should revisit the handling of polymorphic
      # relations, feels hacky.
      #++
      next if (rel[:control] == :none) or rel.polymorphic_marker? 
    end
    relation rel, options
  end
end

#attribute(a, options = {}) ⇒ Object Also known as: attr

Render a control+label for the given property of the form object.



83
84
85
86
87
88
89
90
# File 'lib/nitro/helper/form.rb', line 83

def attribute(a, options = {})
  if anno = @obj.class.ann[a]
    control = self.class.control_for(@obj, a, anno, options)
    print element(a, anno, control.render)
  else
    raise "Undefined attribute '#{a}' for class '#{@obj.class}'."
  end
end

#form_errorsObject

If flash is filled with errors structured as name/message pairs the method creates a div containing them, otherwise it returns an empty string.

So you can write code like

#{form_errors}
<form>... </form>

and redirect the user to the form in case of errors, thus allowing him to see what was wrong.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/nitro/helper/form.rb', line 163

def form_errors
  res = ''

  unless @errors.empty?
    res << %{<div class="error">\n<ul>\n}
    for err in @errors
      if err.is_a? Array
        res << "<li><strong>#{err[0].to_s.humanize}</strong>: #{err[1]}</li>\n"
      else
        res << "<li>#{err}</li>\n"
      end
    end
    res << %{</ul>\n</div>\n}
  end

  print(res)
end

#relation(rel, options = {}) ⇒ Object Also known as: rel

Input

  • rel = The relation name as symbol, or the actual relation object.

– FIXME: Fix the mismatch with the attributes. ++



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/nitro/helper/form.rb', line 116

def relation(rel, options = {})
  # If the relation name is passed, lookup the actual
  # relation.
  
  if rel.is_a? Symbol
    rel = @obj.class.relation(rel)    
  end

  control = self.class.control_for_relation(@obj, rel, options)
  print element(rel[:symbol], rel, control.render)
end

#select_file(name, options = {}) ⇒ Object

Renders a control to select a file for upload.



148
149
150
# File 'lib/nitro/helper/form.rb', line 148

def select_file(name, options = {})
  print %|<input type="file" name="#{name}" />|
end