require 'nitro/helper/xhtml' module Nitro # :section: Property controls. # A Form control. class Control include Nitro::XhtmlHelper # Fetch the instance vars in a nice way use either rel # or prop. # # values/value contain the contents of the prop or rel, # (values reads better for relations) attr_reader :prop alias_method :rel, :prop attr_reader :obj attr_reader :value alias_method :values, :value # setup instance vars to use in methods def initialize(obj, key, value=nil) @obj = obj @prop = key @value = value || obj.send(key.name.to_sym) end # Main bulk of the control. Overide to customise def render "No view for this control" end # Label item. Override to customise def label %{} end # Custom callback to process the request information # posted back from the form # # When Property.populate_object (or fill) is called # with the :preprocess => true option then this # method will get called before the value is pushed # onto the object that is getting 'filled' # # Overide this on controls that require special mods # to the incoming values def on_populate(val) puts "PREPROCESSING !" return val end private def emit_style if prop.respond_to?(:control_style) style = prop.control_style elsif self.class.respond_to?(:style) style = self.class.style else style = nil end style ? %{ style="#{style}"} : '' end end # Fixnum class FixnumControl < Control setting :style, :default => 'width: 100px', :doc => 'The default style' def render style = prop.control_style ||self.class.style %{ + -} end end # Float class FloatControl < Control setting :style, :default => 'width: 100px', :doc => 'The default style' def render style = prop.control_style ||self.class.style %{ + -} end end # Text class TextControl < Control setting :style, :default => 'width: 250px', :doc => 'The default style' def render %{} end end # Textarea class TextareaControl < Control setting :style, :default => 'width: 500px; height: 100px', :doc => 'The default style' def render %{} end end # CheckboxControl < Control class CheckboxControl < Control setting :style, :default => '', :doc => 'The default style' def render checked = value == true ? ' checked="checked"':'' %{} end end # :section: Relation controls. # RefersTo. Also used for BelongsTo. class RefersToControl < Control def render objs = rel.target_class.all if selected = value selected = selected.pk end str = %{} return str end end # HasMany, ManyToMany and JoinsMany class HasManyControl < Control #pre :do_this, :on => :populate_object def render str = emit_container_start str << emit_js if selected_items.empty? str << emit_selector(all_items, :removable => false) else removable = selected_items.size != 1 ? true : false selected_items.each do |item| str << emit_selector(all_items, :selected => item.pk) end end str << emit_container_end end private # these parts are seperated from render to make it easier # to extend and customise the HasManyControl def all_items rel.target_class.all end def selected_items values end def emit_container_start %{