mguymon / sproutcore forked from sproutit/sproutcore

JavaScript Application Framework - JS library only

This URL has Read+Write access

M Nikolas Guymon (author)
Mon Dec 01 21:11:33 -0800 2008
commit  9e6ca6e60eb7fcd8ccd00422f2bcb1b189cc54a9
tree    f0094eb76fd6412a50a0a1ba853cfa79d709f86a
parent  dc1026f62a3f3a57f19fc7501eece67f18444450
sproutcore / lib / form_views.rb
100644 257 lines (224 sloc) 6.868 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
############################################################
# FORM VIEW HELPERS
#
# These view helpers make it easy to create input forms. You should wrap
# your form in the form_view tag and include your fields inside.
#
 
require_helpers 'core_views'
 
# Defines a form view. Note that you can make this form into a panel
# by passing :panel => true
view_helper :form_view do
 
  property :content
  property :enabled, :key => 'isEnabled'
  property :valid, :key => 'isValid'
  property :commiting, :key => 'isCommitting'
  property :dirty, :key => 'isDirty'
  property :errors
  property :error_count, :key => 'errorCount'
  property :autocommit
  property :prompt, :key => 'commitPrompt'
  view 'SC.FormView'
  
  attribute :action, ''
  attribute :method, 'post'
  var :tag, 'form'
end
 
view_helper :error_explanation_view do
  
  # JavaScript
  view 'SC.ErrorExplanationView'
  
  # HTML
  var :tag, 'ul'
  css_class_names << 'errors'
end
 
view_helper :checkbox_field_view do
 
  # JavaScript
  property :value
  property :enabled, :key => 'isEnabled'
  view 'SC.CheckboxFieldView'
 
  # HTML
  var :tag, 'input'
  var :label
 
  attribute :type, 'checkbox'
  attribute :name, @item_id
  
  # if a label is passed, then wrap the checkbox in a label tag and
  # place the label text next to it.
  if @label
    content { %(<label><#{@tag} #{attributes} /> <span class="label">#{@label}</span></label>) }
  else
    content { "<#{@tag} #{attributes} />" }
  end
end
 
# This renders a list of radio buttons.
#
# :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.
#
# :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
#
# :objects =>
# This can point to a hash of objects which will be used to convert the
# key values you set into JS objects.
#
# :value =>
# The current value of the radio buttons.
#
view_helper :radio_field_view do
  
  #JavaScript
  bind :objects
  property :value
  view 'SC.RadioFieldView'
  
  # HTML
 
  # 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
  
  # get the layout mode.
  var :layout, :vertical
  css_class_names << 'radio' # default class
  css_class_names << @layout if @layout
  
  var :tag, 'div'
  
  # generate the inner-html
  var :values
  html = @values.map do | v |
    v = [v].flatten
    key = v.first
    label = (v.size > 1) ? v[1] : key.to_s.humanize
    %(<label><input type="radio" name="#{item_id}" value="#{key}" #{@label_styles} /><span class="label">#{label}</span></label>)
  end
  @inner_html = html * "\n"
   
end
 
 
  
view_helper :text_field_view do
  var :tag, 'input'
 
  view 'SC.TextFieldView'
  property :field_value
  property :value, :key => :field_value
  property :hint
  property :validate, :key => :validator
  property :label, :key => 'fieldLabel'
  
  attribute :size
  attribute :type, 'text'
  attribute :label
  attribute :name
  content { "<#{@tag} #{attributes} />" }
end
 
view_helper :password_field_view, :extends => :text_field_view do
  attribute :type, 'password'
end
 
view_helper :text_area_view do
  var :form, false
  var :tag, 'textarea'
  var :value, @inner_html
  
  if @form
    view nil
  else
    view 'SC.TextareaFieldView'
    property :hint
    property :field_value
    property :value
  end
  
  attribute :cols, 72
  attribute :rows, 10
  attribute :validate
  attribute :label
  attribute :name
  attribute :form, :key => :name
  content { "#{ot}#{@value}#{ct}" }
end
 
# This view renders a browser-native popup menu.
#
# :field =>
# pass a name to make this part of the enclosing form.
#
# :options =>
# This will statically generate the HTML for the options menu. The
# value of this property should be an array of items containing strings
# or symbols, which will form both the item names and values or you can
# pass an array of arrays. The first item should be the value of the
# object, then second item should be the name of the menu.
#
# Note that if you bind to the :objects property, then that binding
# will override this code.
#
# :name_key =>
# Specifies the key to use to get the name of a menu item from the
# array of objects. This is only used if the menu items are generated
# dynamically.
#
# :sort_key =>
# Optional sort key to use to order the menu. If the sort key is not
# passed, the name of the menu items will be used. This is only used
# if the menu items are generated dynamically.
#
# :value_key =>
# Optional key used to get the value for each menu item from the
# array of objects. Only used if the menu items are generated
# dynamically.
#
# :empty =>
# Optional. Pass the string name of the "Empty" menu item. This item
# will appear at the top of the menu and its value will be a null
# object. The value you pass here will be localized by default. Only
# used if the menu items are generated dynamically.
#
# :localize =>
# Optional. If true, the names of the menu items and the empty menu
# item will be passed through the localization system. Defaults to
# false.
#
# :validator =>
# Optional. Pass the name of a validator and it will be used for this
# control.
#
# BINDABLE PROPERTIES
#
# :objects =>
# bind to an array of objects used to generate the menu item. This will
# override any hard-coded options you pass through the :options param.
#
# :value =>
# bind to the current value to show in the pop-up menu.
#
# :enabled =>
# bind or pass to set the control to enabled or disabled.
#
view_helper :select_field_view do
  # JavaScript
  property :name_key
  property :sort_key
  property :value_key
  property :empty, :key => 'emptyName'
  property :empty_name
  property :empty_disabled
  property :empty_value
  property :enabled, :key => 'isEnabled'
  bind :objects
  view 'SC.SelectFieldView'
  
  # HTML
  var :tag, 'select'
  var :options
  if @options
    html = @options.map do |opt|
      opt = [opt].flatten
      key = opt.first
      name = (opt.size > 1) ? opt[1] : key.to_s.titleize
      %(<option value="#{key}">#{name}</option>)
    end
    @inner_html = html * "\n"
  end
end