############################################################
# BUTTON VIEW HELPERS
#
# You can do a lot of different things with buttons: push buttons, switches,
# checkboxes, radio buttons and more. This file contains the helpers you can
# use to help you build these.
#
require 'sproutcore/view_helpers/core_views'
module SproutCore
module ViewHelpers
# This is the core button_view helper. Most other helpers in this file
# descend from this helper. If a helper is not provided that already
# builds the button you want, you can probably use this helper to
# construct it yourself.
#
# :enabled (bindable) =>
# If set to true, the button will be enabled.
#
# :selected (bindable) =>
# Set to true, false or :mixed. This will determine if the button
# appears selected. You can bind to this option but more often you will
# want to bind to :value.
#
# :default (bindable) =>
# Set to true to make this button the default button triggered when
# you press return while focused in a panel or form.
#
# :cancel (bindable) =>
# Set to true to make this button the one triggered when you press
# return while focused on a panel or form.
#
# :theme => :regular | :back | :checkbox | :radio | :square |
# (your own theme)
# Use this to set the theme appearance of the button. The SC theme
# comes with built-in support for the ones listed above or you can
# name your own. a CSS class name will be assigned to the button with
# this theme name.
#
# :behavior => :push, :toggle, :on, :off
# Specify the behavior of the button when pressed. The default is
# :push.
#
# :tag =>
# The tag name to use for the button. Defaults to 'a'. If the tag is
# 'a', an href="javascript:;" will be added automatically unless you
# specify an alternate.
#
# :href =>
# optional href to pass. Generall you don't want to pass this.
#
# :label =>
# The value of the label placed inside the button. You can alternately
# specify inner_html which will be used a the label. Note that the
# button_view generator automatically wraps your inner_html with a
# standard button structure unless you pass :label => false
#
# :image =>
# Renders an image tag on the outside of the label span. If this is
# set, then the wrapping tag will also have 'image' css class applied.
#
# :sprite => [resource_url, x-ofset, y-offset]
# Render an image sprite! The expected size of the sprite depends on
# the class name of the view. If the x-offset or y-offset are numbers
# they will be converted to "px". If this is set, then the wrapping
# tag will also have 'sprite' css class applied.
#
# Alternatively, name the CSS class you want assigned to the img for
# the sprite.
#
view_helper :button_view do
# JavaScript
property :enabled, :key => 'isEnabled'
property :action
property :target
#property(:action) { |v| "function(ev) { return #{v}(this, ev); }" }
property :default, :key => 'isDefault'
property :cancel, :key => 'isCancel'
property :value
property :theme
property :size
property :behavior, :key => 'buttonBehavior'
property :toggle_on_value
property :toggle_off_value
property :key_equivalent, :key => :keyEquivalent
property(:selected, :key => 'isSelected') do |x|
(x == :mixed) ? 'SC.MIXED_STATE' : x
end
view 'SC.ButtonView'
# HTML
var :label, @inner_html || 'Submit'
var :tag, 'a'
var :theme, :regular
var :size, :normal
attribute(:href) { |x| (x.nil? && (@tag.downcase.to_s == 'a')) ? 'javascript:;' : nil }
# Add the theme to the CSS class.
css_class_names << 'button'
css_class_names << @theme unless @theme.nil? || @theme == false
css_class_names << @size unless @size.nil? || @size == false
var :image
var :sprite
if @image
@image = %()
css_class_names << 'image'
elsif @sprite
img_url = self.blank_url
if @sprite.instance_of?(Array)
xoff = @sprite[1]
xoff = "#{xoff}px" if xoff.kind_of?(Numeric)
yoff = @sprite[2]
yoff = "#{yoff}px" if yoff.kind_of?(Numeric)
# render image part
@image = %()
else
@image = %()
end
end
# Generate some standard HTML for unless :label => false.
unless @label == false
# Button Width properties must be set on the inner label. To deal
# with this remove any width style properties from the parent element
# and append them to the inner label.
@label_style = []
css_styles.flatten!
css_styles.reject! do | part |
if part =~ /width:/
@label_style << part
true
else
false
end
end
if @label_style.size > 0
@label_style = %(style="#{@label_style * ' '}" )
else
@label_style = ''
end
# Avoid doing the normal thing for anchor tags.
@inner_html = %(#{@image}#{@label})
else
@inner_html = [@image,@inner_html] * ''
end
end
view_helper :popup_button_view, :wraps => :button_view do
parent_helper
property :menu, :key => :menuName
view 'SC.PopupButtonView'
end
# Renders a back button
view_helper :back_button_view, :wraps => :button_view do
parent_helper :theme => :back
end
# Renders a checkbox. If you pass a label this will render the label
# text next to the checkbox. Unlike button_view, passing no :label is
# the same as passing :label => false.
view_helper :checkbox_view, :wraps => :button_view do
opts = { :theme => :checkbox }
opts[:label] = false if options[:label].nil?
parent_helper(opts)
# provide some defaults to the JavaScript.
property :behavior, :toggle, :key => 'buttonBehavior'
# render checkbox HTML.
img_url = self.blank_url
@inner_html = [%()]
@inner_html << %(#{@label}) if @label
@inner_html = @inner_html.join ''
end
# Renders a radio buton. If you pass a label this will render the label
# text next to the checkbox. Unlike button_view, passing no :label is
# the same as passing :label => false.
view_helper :radio_view, :wraps => :button_view do
opts = { :theme => :radio }
opts[:label] = false if options[:label].nil?
parent_helper(opts)
# provide some defaults to the JavaScript.
property :behavior, :on, :key => 'buttonBehavior'
# render checkbox HTML.
img_url = self.blank_url
@inner_html = [%()]
@inner_html << %(#{@label}) if @label
@inner_html = @inner_html.join ''
end
# This renders a group of radio buttons. The buttons are controlled by
# a RadioGroupView that will map the value to a set of selection states.
#
# :values => [REQ]
# Set this to the values you want displayed in the radio buttons. You
# can pass an array here of strings or symbols, in which case these will
# be used as the values for the buttons and the names will be created
# from them. Or you can pass an array of arrays. The first items is
# the key value, the second item is the human readable value.
# Alternatively, you can set the inner_html of your view to include
# radio buttons as outlets. In this case, you must name the outlets
# :key_button.
#
# :layout => :horizontal | :vertical
# This will write out horizontal or vertical to the CSS class names so
# you can control the layout of your radio buttons.
#
# :width =>
# This will set the width of each item in the view.
#
# BINDABLE OPTIONS
#
# :value =>
# The current value of the radio buttons.
#
view_helper :radio_group_view do
#JavaScript
property :value
view 'SC.RadioGroupView'
# HTML
# get the layout mode.
var :layout, :vertical
css_class_names << 'radio' # default class
css_class_names << @layout if @layout
var :tag, 'span'
# If a set of values was passed, build the button views automatically.
var :values
if @values
# Get the width styles out of the main style to put into the
# individual radio items.
css_styles.flatten!
@label_styles = css_styles.reject { |p| !(p =~ /width:/) }
css_styles.reject! { |p| @label_styles.include?(p) }
if @label_styles.size > 0
@label_styles = %( style="#{@label_styles * ' '}" )
else
@label_styles = ''
end
# save off client_builder. The context this is run in later will
# not retain the client_builder
current_client_builder = self.client_builder
html = @values.map do | v |
v = [v].flatten
key = v.first
label = (v.size > 1) ? v[1] : key.to_s.humanize
ViewHelpers::radio_view(:outlet => true, :label => label, :style => @label_styles, :toggle_on_value => key, :toggle_off_value => nil, :client => self.client_builder)
end
@inner_html = html * "\n"
end
end
# def self.blank_url
# cb = SproutCore::ClientBuilder.builder_for(:sproutcore)
# if cb
# img_url = cb.url_for('blank.gif')
# else
# # if the sproutcore client cannot be found, give it a shot anyway...
# img_url = '/static/sproutcore/en/blank.gif'
# end
# img_url
# end
end
end