Skip to content

Commit

Permalink
New Contenter::ValueValue UI helper.
Browse files Browse the repository at this point in the history
  • Loading branch information
kstephens committed Apr 7, 2011
1 parent 6284327 commit 46b4660
Show file tree
Hide file tree
Showing 2 changed files with 233 additions and 0 deletions.
165 changes: 165 additions & 0 deletions contenter_gui/lib/contenter/valid_value.rb
@@ -0,0 +1,165 @@
require 'contenter'
require 'cgi' # CGI.escapeHTML

module Contenter
# Helper to render value value interfaces.
class ValidValue
EMPTY_Array = [ ].freeze

attr_accessor :name, :default, :valid_set, :ui, :display_name
attr_accessor :value
attr_accessor :ui_name, :ui_name_path, :ui_id, :ui_class
attr_accessor :ui_cols, :ui_rows

def self.many_from_hash vv
result = { }
if vv
vv.each do | name, settings |
obj = self.new
obj.name = name
obj.from_hash!(settings)
result[obj.name] = obj
end
end
result
end

def initialize hash = nil
from_hash! hash if hash
end

def from_hash! hash
self.name ||= hash[:name]

self.ui ||= hash[:ui] || :textfield
@ui_rows ||= hash[:ui_rows]
@ui_cols ||= hash[:ui_cols]
@ui_name ||= hash[:ui_name]
@ui_name_path ||= hash[:ui_name_path]
@ui_id ||= hash[:ui_id]
@ui_class ||= hash[:ui_class]

self.valid_set ||= hash[:valid_set]
self.default ||= hash[:default]

case self.ui
when :checkbox
self.valid_set ||= [ 'f', 't' ]
end

self.default ||= (self.valid_set || EMPTY_Array).first

self.display_name ||= hash[:display_name] || { }

self
end

def value_or_default
@value.nil? ? default : value
end

def valid?
case ui
when :checkbox
val = to_bool(@value)
val == false || val == true
else
case valid_set
when nil
true
when Regexp
self.valid_set.match(@value)
when Array
self.valid_set.include?(@value)
else
true
end
end
end

def ui_id
@ui_id ||= "#{ui_name}".freeze
end

def ui_name_path
@ui_name_path ||= '%s'.freeze
end

def ui_name
@ui_name ||= "#{ui_name_path % name}".freeze
end

def ui_class
@ui_class ||= "#{ui_id}".freeze
end

def ui_rows
@ui_rows ||= 20
end

def ui_cols
@ui_cols ||= 80
end

def html_show
v = value_or_default
case ui || :textfield
when :textfield
h(display_name[v] || v)
when :textarea
"<pre>#{h(display_name[v] || v)}</pre>"
when :checkbox
to_bool(v) ? "[X]" : "[ ]"
when :dropdown, :select
h(display_name[v] || v)
else
raise ArgumentError, "name = #{name.inspect} ui = #{ui.inspect}"
end
end

def html_edit
v = value_or_default
case ui || :textfield
when :textfield
%Q{<input type="text" id="#{ui_id}" name="#{ui_name}" size="#{ui_cols}" value="#{h v}" />}
when :textarea
%Q{<textarea id="#{ui_id}" name="#{ui_name}" cols="#{ui_cols}" rows="#{ui_rows}">#{h v}</textarea>}
when :checkbox
%Q{<input type="checkbox" id="#{ui_id}" name="#{ui_name}" value="#{to_bool(v) ? 1 : nil}" />}
when :dropdown, :select
result = %Q{<select id="#{ui_id}" name="#{ui_name}">}
valid_set.each do | vv |
result << %Q{<option value="#{vv}" #{vv.to_s == v.to_s ? 'selected="selected"' : nil}>#{h(display_name[vv] || vv)}</option>}
end
result << %Q{</select>}
else
raise ArgumentError, "uname = #{name.inspect} ui = #{ui.inspect}"
end
end

def html_escape value
value = value.to_s
CGI.escapeHTML(value)
end
alias :h :html_escape

def to_bool value
case value
when nil, '', false
false
when Numeric
! value.zero?
when String, Symbol
case value.to_s
when /\A[fn0]/i
false
else
true
end
else
true
end
end

end # class
end # module
68 changes: 68 additions & 0 deletions contenter_gui/spec/contenter/valid_value_spec.rb
@@ -0,0 +1,68 @@
# -*- ruby -*-
#require 'test_helper'
require 'spec/spec_helper'

require 'contenter/valid_value'

describe "Contenter::ValueValue" do
attr_accessor :vv

def create h = nil
self.vv = Contenter::ValidValue.new(h)
self.vv
end

it 'handles :ui => :checkbox' do
create(:name => :my_checkbox,
:ui => :checkbox,
:value => nil
)
vv.value = 'foo'
vv.valid?.should == true
vv.html_show.should == '[ ]'
vv.html_edit.should == "<input type=\"checkbox\" id=\"my_checkbox\" name=\"my_checkbox\" value=\"\" />"

vv.value = true
vv.valid?.should == true
vv.html_show.should == '[X]'
vv.html_edit.should == "<input type=\"checkbox\" id=\"my_checkbox\" name=\"my_checkbox\" value=\"1\" />"

end

it 'handles :ui => :textfield' do
create(:name => :my_textfield,
:ui => :textfield,
:valid_set => [ 'foo & bar', 'baz' ]
)
vv.value = 'foo & bar'
vv.valid?.should == true
vv.html_show.should == 'foo &amp; bar'
vv.html_edit.should == "<input type=\"text\" id=\"my_textfield\" name=\"my_textfield\" size=\"80\" value=\"foo &amp; bar\" />"

vv.value = 'baz'
vv.valid?.should == true
vv.html_show.should == 'baz'
vv.html_edit.should == "<input type=\"text\" id=\"my_textfield\" name=\"my_textfield\" size=\"80\" value=\"baz\" />"

vv.value = 'booze'
vv.valid?.should == false
vv.html_show.should == 'booze'
vv.html_edit.should == "<input type=\"text\" id=\"my_textfield\" name=\"my_textfield\" size=\"80\" value=\"booze\" />"

end

it 'handles :ui => :textarea' do
create(:name => :my_textarea,
:ui_name_path => 'content[data][%s]',
:ui_id => 'ta123',
:ui => :textarea,
:ui_rows => 4
)
vv.value = 'foo & bar'
vv.valid?.should == true
vv.html_show.should == '<pre>foo &amp; bar</pre>'
vv.html_edit.should == "<textarea id=\"ta123\" name=\"content[data][my_textarea]\" cols=\"80\" rows=\"4\">foo &amp; bar</textarea>"

end

end # describe

0 comments on commit 46b4660

Please sign in to comment.