joosy 1.0.0.RC4 → 1.0.0.RC5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/Gemfile +1 -1
  2. data/Gemfile.lock +99 -82
  3. data/README.md +1 -1
  4. data/app/assets/javascripts/joosy/core/application.js.coffee +2 -2
  5. data/app/assets/javascripts/joosy/core/form.js.coffee +35 -22
  6. data/app/assets/javascripts/joosy/core/helpers/form.js.coffee +38 -9
  7. data/app/assets/javascripts/joosy/core/helpers/view.js.coffee +10 -4
  8. data/app/assets/javascripts/joosy/core/helpers/widgets.js.coffee +6 -1
  9. data/app/assets/javascripts/joosy/core/joosy.js.coffee +5 -3
  10. data/app/assets/javascripts/joosy/core/layout.js.coffee +5 -5
  11. data/app/assets/javascripts/joosy/core/modules/events.js.coffee +28 -10
  12. data/app/assets/javascripts/joosy/core/modules/log.js.coffee +1 -1
  13. data/app/assets/javascripts/joosy/core/modules/module.js.coffee +2 -2
  14. data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +1 -1
  15. data/app/assets/javascripts/joosy/core/page.js.coffee +1 -1
  16. data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +18 -18
  17. data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +21 -19
  18. data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +26 -14
  19. data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +2 -2
  20. data/app/assets/javascripts/joosy/core/router.js.coffee +2 -2
  21. data/app/assets/javascripts/joosy/core/widget.js.coffee +3 -0
  22. data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +7 -7
  23. data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +5 -5
  24. data/lib/joosy/rails/version.rb +1 -1
  25. data/lib/rails/generators/joosy/templates/app/helpers/application.js.coffee +2 -2
  26. data/lib/rails/generators/joosy/templates/app/pages/welcome/index.js.coffee +5 -5
  27. data/lib/rails/generators/joosy/templates/app/routes.js.coffee +2 -2
  28. data/lib/rails/generators/joosy/templates/preload.html.slim +19 -0
  29. data/lib/rails/resources_with_joosy.rb +2 -2
  30. data/spec/javascripts/helpers/spec_helper.js.coffee +19 -0
  31. data/spec/javascripts/joosy/core/form_spec.js.coffee +36 -16
  32. data/spec/javascripts/joosy/core/helpers/forms_spec.js.coffee +28 -23
  33. data/spec/javascripts/joosy/core/helpers/widgets_spec.js.coffee +17 -0
  34. data/spec/javascripts/joosy/core/joosy_spec.js.coffee +2 -0
  35. data/spec/javascripts/joosy/core/modules/events_spec.js.coffee +35 -1
  36. data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +29 -29
  37. data/spec/javascripts/joosy/core/page_spec.js.coffee +2 -2
  38. data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +14 -9
  39. data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +19 -19
  40. data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +0 -1
  41. data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +9 -3
  42. data/spec/javascripts/joosy/preloaders/caching_spec.js.coffee +7 -7
  43. data/spec/javascripts/joosy/preloaders/inline_spec.js.coffee +5 -5
  44. data/spec/javascripts/support/sinon-1.3.1.js +6 -6
  45. data/spec/javascripts/support/sinon-ie-1.3.1.js +5 -5
  46. metadata +22 -20
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
 
6
6
  group :development do
7
7
  gem 'jasmine', :git => 'git://github.com/pivotal/jasmine-gem.git'
8
- gem 'guard-sprockets', :git => 'git://github.com/roundlake/guard-sprockets.git'
8
+ gem 'guard-sprockets'
9
9
  gem 'thin'
10
10
  end
11
11
 
data/Gemfile.lock CHANGED
@@ -1,25 +1,17 @@
1
1
  GIT
2
2
  remote: git://github.com/pivotal/jasmine-gem.git
3
- revision: c72e8d248d49a1ebe53f31a09ac511194ad4edf1
3
+ revision: 54b37cf9a51df49a77d15640e3e0caa46a508c1d
4
4
  specs:
5
- jasmine (1.2.0.rc3)
6
- jasmine-core (>= 1.2.0.rc3)
5
+ jasmine (1.2.1)
6
+ jasmine-core (>= 1.2.0)
7
7
  rack (~> 1.0)
8
8
  rspec (>= 1.3.1)
9
9
  selenium-webdriver (>= 0.1.3)
10
10
 
11
- GIT
12
- remote: git://github.com/roundlake/guard-sprockets.git
13
- revision: 77365fbf48b2af0c93a42fcb05747c174b90d8d7
14
- specs:
15
- guard-sprockets (0.3.1)
16
- guard (~> 1.0.0)
17
- sprockets (~> 2.0)
18
-
19
11
  PATH
20
12
  remote: .
21
13
  specs:
22
- joosy (1.0.0.RC3)
14
+ joosy (1.0.0.RC4)
23
15
  coffee-rails
24
16
  haml_coffee_assets
25
17
  i18n-js
@@ -29,133 +21,158 @@ PATH
29
21
  GEM
30
22
  remote: http://rubygems.org/
31
23
  specs:
32
- actionmailer (3.2.3)
33
- actionpack (= 3.2.3)
24
+ actionmailer (3.2.9)
25
+ actionpack (= 3.2.9)
34
26
  mail (~> 2.4.4)
35
- actionpack (3.2.3)
36
- activemodel (= 3.2.3)
37
- activesupport (= 3.2.3)
27
+ actionpack (3.2.9)
28
+ activemodel (= 3.2.9)
29
+ activesupport (= 3.2.9)
38
30
  builder (~> 3.0.0)
39
31
  erubis (~> 2.7.0)
40
- journey (~> 1.0.1)
32
+ journey (~> 1.0.4)
41
33
  rack (~> 1.4.0)
42
34
  rack-cache (~> 1.2)
43
35
  rack-test (~> 0.6.1)
44
- sprockets (~> 2.1.2)
45
- activemodel (3.2.3)
46
- activesupport (= 3.2.3)
36
+ sprockets (~> 2.2.1)
37
+ activemodel (3.2.9)
38
+ activesupport (= 3.2.9)
47
39
  builder (~> 3.0.0)
48
- activerecord (3.2.3)
49
- activemodel (= 3.2.3)
50
- activesupport (= 3.2.3)
40
+ activerecord (3.2.9)
41
+ activemodel (= 3.2.9)
42
+ activesupport (= 3.2.9)
51
43
  arel (~> 3.0.2)
52
44
  tzinfo (~> 0.3.29)
53
- activeresource (3.2.3)
54
- activemodel (= 3.2.3)
55
- activesupport (= 3.2.3)
56
- activesupport (3.2.3)
45
+ activeresource (3.2.9)
46
+ activemodel (= 3.2.9)
47
+ activesupport (= 3.2.9)
48
+ activesupport (3.2.9)
57
49
  i18n (~> 0.6)
58
50
  multi_json (~> 1.0)
59
51
  arel (3.0.2)
60
- builder (3.0.0)
61
- childprocess (0.3.1)
62
- ffi (~> 1.0.6)
52
+ builder (3.0.4)
53
+ childprocess (0.3.6)
54
+ ffi (~> 1.0, >= 1.0.6)
55
+ coderay (1.0.8)
63
56
  coffee-rails (3.2.2)
64
57
  coffee-script (>= 2.2.0)
65
58
  railties (~> 3.2.0)
66
59
  coffee-script (2.2.0)
67
60
  coffee-script-source
68
61
  execjs
69
- coffee-script-source (1.2.0)
70
- daemons (1.1.8)
62
+ coffee-script-source (1.4.0)
63
+ daemons (1.1.9)
71
64
  diff-lcs (1.1.3)
72
65
  erubis (2.7.0)
73
- eventmachine (0.12.10)
74
- eventmachine (0.12.10-java)
75
- execjs (1.3.0)
66
+ eventmachine (1.0.0)
67
+ eventmachine (1.0.0-java)
68
+ execjs (1.4.0)
76
69
  multi_json (~> 1.0)
77
- ffi (1.0.11)
78
- ffi (1.0.11-java)
79
- guard (1.0.1)
80
- ffi (>= 0.5.0)
81
- thor (~> 0.14.6)
82
- guard-coffeescript (0.5.7)
70
+ ffi (1.1.5)
71
+ ffi (1.1.5-java)
72
+ guard (1.5.4)
73
+ listen (>= 0.4.2)
74
+ lumberjack (>= 1.0.2)
75
+ pry (>= 0.9.10)
76
+ thor (>= 0.14.6)
77
+ guard-coffeescript (1.2.1)
83
78
  coffee-script (>= 2.2.0)
84
- guard (>= 0.8.3)
85
- haml_coffee_assets (0.9.3)
86
- execjs (>= 1.2.9)
79
+ guard (>= 1.1.0)
80
+ guard-sprockets (0.4.1)
81
+ guard (>= 1.1.0)
82
+ sprockets (~> 2.0)
83
+ haml_coffee_assets (1.7.2)
84
+ coffee-script (>= 1.0.0)
87
85
  sprockets (>= 2.0.3)
88
86
  tilt (>= 1.3.3)
89
87
  hike (1.2.1)
90
- i18n (0.6.0)
88
+ i18n (0.6.1)
91
89
  i18n-js (2.1.2)
92
90
  i18n
93
- jasmine-core (1.2.0.rc3)
94
- journey (1.0.3)
95
- jquery-rails (2.0.2)
96
- railties (>= 3.2.0, < 5.0)
91
+ jasmine-core (1.2.0)
92
+ journey (1.0.4)
93
+ jquery-rails (2.1.3)
94
+ railties (>= 3.1.0, < 5.0)
97
95
  thor (~> 0.14)
98
- json (1.7.3)
96
+ json (1.7.5)
97
+ json (1.7.5-java)
98
+ libwebsocket (0.1.6)
99
+ websocket
100
+ listen (0.5.3)
101
+ lumberjack (1.0.2)
99
102
  mail (2.4.4)
100
103
  i18n (>= 0.4.0)
101
104
  mime-types (~> 1.16)
102
105
  treetop (~> 1.4.8)
103
- mime-types (1.18)
104
- multi_json (1.2.0)
106
+ method_source (0.8.1)
107
+ mime-types (1.19)
108
+ multi_json (1.3.7)
105
109
  polyglot (0.3.3)
110
+ pry (0.9.10)
111
+ coderay (~> 1.0.5)
112
+ method_source (~> 0.8)
113
+ slop (~> 3.3.1)
114
+ pry (0.9.10-java)
115
+ coderay (~> 1.0.5)
116
+ method_source (~> 0.8)
117
+ slop (~> 3.3.1)
118
+ spoon (~> 0.0)
106
119
  rack (1.4.1)
107
120
  rack-cache (1.2)
108
121
  rack (>= 0.4)
109
122
  rack-ssl (1.3.2)
110
123
  rack
111
- rack-test (0.6.1)
124
+ rack-test (0.6.2)
112
125
  rack (>= 1.0)
113
- rails (3.2.3)
114
- actionmailer (= 3.2.3)
115
- actionpack (= 3.2.3)
116
- activerecord (= 3.2.3)
117
- activeresource (= 3.2.3)
118
- activesupport (= 3.2.3)
126
+ rails (3.2.9)
127
+ actionmailer (= 3.2.9)
128
+ actionpack (= 3.2.9)
129
+ activerecord (= 3.2.9)
130
+ activeresource (= 3.2.9)
131
+ activesupport (= 3.2.9)
119
132
  bundler (~> 1.0)
120
- railties (= 3.2.3)
121
- railties (3.2.3)
122
- actionpack (= 3.2.3)
123
- activesupport (= 3.2.3)
133
+ railties (= 3.2.9)
134
+ railties (3.2.9)
135
+ actionpack (= 3.2.9)
136
+ activesupport (= 3.2.9)
124
137
  rack-ssl (~> 1.3.2)
125
138
  rake (>= 0.8.7)
126
139
  rdoc (~> 3.4)
127
- thor (~> 0.14.6)
128
- rake (0.9.2.2)
140
+ thor (>= 0.14.6, < 2.0)
141
+ rake (10.0.1)
129
142
  rdoc (3.12)
130
143
  json (~> 1.4)
131
- rspec (2.9.0)
132
- rspec-core (~> 2.9.0)
133
- rspec-expectations (~> 2.9.0)
134
- rspec-mocks (~> 2.9.0)
135
- rspec-core (2.9.0)
136
- rspec-expectations (2.9.1)
144
+ rspec (2.12.0)
145
+ rspec-core (~> 2.12.0)
146
+ rspec-expectations (~> 2.12.0)
147
+ rspec-mocks (~> 2.12.0)
148
+ rspec-core (2.12.0)
149
+ rspec-expectations (2.12.0)
137
150
  diff-lcs (~> 1.1.3)
138
- rspec-mocks (2.9.0)
139
- rubyzip (0.9.6.1)
140
- selenium-webdriver (2.20.0)
151
+ rspec-mocks (2.12.0)
152
+ rubyzip (0.9.9)
153
+ selenium-webdriver (2.26.0)
141
154
  childprocess (>= 0.2.5)
142
- ffi (~> 1.0)
155
+ libwebsocket (~> 0.1.3)
143
156
  multi_json (~> 1.0)
144
157
  rubyzip
145
- sprockets (2.1.2)
158
+ slop (3.3.3)
159
+ spoon (0.0.1)
160
+ sprockets (2.2.1)
146
161
  hike (~> 1.2)
162
+ multi_json (~> 1.0)
147
163
  rack (~> 1.0)
148
164
  tilt (~> 1.1, != 1.3.0)
149
- thin (1.3.1)
165
+ thin (1.5.0)
150
166
  daemons (>= 1.0.9)
151
167
  eventmachine (>= 0.12.6)
152
168
  rack (>= 1.0.0)
153
- thor (0.14.6)
169
+ thor (0.16.0)
154
170
  tilt (1.3.3)
155
- treetop (1.4.10)
171
+ treetop (1.4.12)
156
172
  polyglot
157
173
  polyglot (>= 0.3.1)
158
- tzinfo (0.3.33)
174
+ tzinfo (0.3.35)
175
+ websocket (1.0.3)
159
176
 
160
177
  PLATFORMS
161
178
  java
@@ -164,7 +181,7 @@ PLATFORMS
164
181
  DEPENDENCIES
165
182
  guard
166
183
  guard-coffeescript
167
- guard-sprockets!
184
+ guard-sprockets
168
185
  jasmine!
169
186
  joosy!
170
187
  thin
data/README.md CHANGED
@@ -48,7 +48,7 @@ Credits
48
48
  <img src="http://roundlake.ru/assets/logo.png" align="right" />
49
49
 
50
50
  * Boris Staal ([@_inossidabile](http://twitter.com/#!/_inossidabile))
51
- * Andrew Shaydurov
51
+ * Andrew Shaydurov ([@ImGearHead](http://twitter.com/#!/ImGearHead))
52
52
  * Alexander Pavlenko ([@alerticus](http://twitter.com/#!/alerticus))
53
53
  * Peter Zotov ([@whitequark](http://twitter.com/#!/whitequark))
54
54
 
@@ -9,7 +9,7 @@ Joosy.Application =
9
9
  Pages: {}
10
10
  Layouts: {}
11
11
  Controls: {}
12
-
12
+
13
13
  loading: true
14
14
  identity: true
15
15
  debug: false
@@ -51,4 +51,4 @@ Joosy.Application =
51
51
  #
52
52
  setCurrentPage: (page, params) ->
53
53
  #if @page not instanceof page
54
- @page = new page params, @page
54
+ @page = new page params, @page
@@ -8,7 +8,7 @@
8
8
  # AJAXifies form including file uploads and stuff. Built on top of jQuery.Form.
9
9
  #
10
10
  # Joosy.Form automatically cares of form validation highlights. It can
11
- # read common server error responses and add .field_with_errors class to proper
11
+ # read common server error responses and add .field_with_errors class to proper
12
12
  # field.
13
13
  #
14
14
  # If you don't have resource associated with form (#fill), it will try to find fields
@@ -17,7 +17,7 @@
17
17
  # @example Joosy.Form usage
18
18
  # form = new Joosy.Form, -> (response)
19
19
  # console.log "Saved and got some: #{response}"
20
- #
20
+ #
21
21
  # form.progress = (percent) -> console.log "Uploaded by #{percent}%"
22
22
  # form.fill @resource
23
23
  #
@@ -34,7 +34,7 @@ class Joosy.Form extends Joosy.Module
34
34
  # Marks the CSS class to use to mark invalidated fields
35
35
  #
36
36
  invalidationClass: 'field_with_errors'
37
-
37
+
38
38
  #
39
39
  # List of mappings for fields of invalidated data which comes from server
40
40
  #
@@ -84,12 +84,12 @@ class Joosy.Form extends Joosy.Module
84
84
  # by returning false from your own before callback. Both of callbacks will run if
85
85
  # you return true.
86
86
  #
87
- # @option options [Function] success `(Object) -> null` triggers on 200 HTTP code from server.
87
+ # @option options [Function] success `(Object) -> null` triggers on 2xx HTTP code from server.
88
88
  # Pases in the parsed JSON.
89
89
  #
90
90
  # @option options [Function] progress `(Float) -> null` runs periodically while form is uploading
91
91
  #
92
- # @option options [Function] error `(Object) -> Boolean` triggers if server responded with anything but 200.
92
+ # @option options [Function] error `(Object) -> Boolean` triggers if server responded with anything but 2xx.
93
93
  # By default will run form invalidation routine. This behavior can be canceled
94
94
  # by returning false from your own error callback. Both of callbacks will run if
95
95
  # you return true.
@@ -97,6 +97,7 @@ class Joosy.Form extends Joosy.Module
97
97
  # @option options [Joosy.Resource.Generic] resource The resource to fill the form with
98
98
  # @option options [String] resourceName The string to use as a resource name prefix for fields to match invalidation
99
99
  # @option options [String] action Action URL for the form
100
+ # @option options [String] method HTTP method, for example PUT, that will passed in _method param
100
101
  #
101
102
  constructor: (form, options={}) ->
102
103
  if Object.isFunction options
@@ -136,6 +137,13 @@ class Joosy.Form extends Joosy.Module
136
137
  @fill(options.resource, options)
137
138
  delete @resource
138
139
 
140
+ if options.action?
141
+ @container.attr 'action', options.action
142
+ @container.attr 'method', 'POST'
143
+
144
+ if options.method?
145
+ @__markMethod options.method
146
+
139
147
  #
140
148
  # Resets form submit behavior to default
141
149
  #
@@ -170,14 +178,16 @@ class Joosy.Form extends Joosy.Module
170
178
  key = @concatFieldName scope, property
171
179
  input = @fields.filter("[name='#{key}']:not(:file),[name='#{key.underscore()}']:not(:file),[name='#{key.camelize(false)}']:not(:file)")
172
180
  if input.length > 0
173
- unless input.is ':checkbox'
174
- input.val val
175
- else
181
+ if input.is ':checkbox'
176
182
  if val
177
183
  input.attr 'checked', 'checked'
178
184
  else
179
185
  input.removeAttr 'checked'
180
- if Object.isObject val
186
+ else if input.is ':radio'
187
+ input.filter("[value='#{val}']").attr 'checked', 'checked'
188
+ else
189
+ input.val val
190
+ if Object.isObject(val) || Object.isArray(val)
181
191
  filler val, key
182
192
  else if val instanceof Joosy.Resource.REST
183
193
  filler val.data, @concatFieldName(scope, "[#{property}_attributes][0]")
@@ -186,7 +196,7 @@ class Joosy.Form extends Joosy.Module
186
196
  filler entity.data, @concatFieldName(scope, "[#{property}_attributes][#{i}]")
187
197
  delete data.__joosy_form_filler_lock
188
198
 
189
- filler data, resource.__entityName
199
+ filler data, resource.__entityName || options.resourceName
190
200
 
191
201
  @__markMethod(options?.method || 'PUT') if resource.id()
192
202
 
@@ -200,7 +210,7 @@ class Joosy.Form extends Joosy.Module
200
210
  #
201
211
  submit: ->
202
212
  @container.submit()
203
-
213
+
204
214
  #
205
215
  # Serializes form into query string.
206
216
  #
@@ -211,7 +221,7 @@ class Joosy.Form extends Joosy.Module
211
221
  serialize: (skipMethod=true) ->
212
222
  data = @container.serialize()
213
223
  data = data.replace /\&?\_method\=put/i, '' if skipMethod
214
-
224
+
215
225
  data
216
226
 
217
227
  #
@@ -220,7 +230,7 @@ class Joosy.Form extends Joosy.Module
220
230
  __success: (response, status, xhr) ->
221
231
  if xhr
222
232
  @success? response
223
- else if response.status == 200
233
+ else if 200 <= response.status < 300
224
234
  @success response.json
225
235
  else
226
236
  @__error response.json
@@ -248,7 +258,7 @@ class Joosy.Form extends Joosy.Module
248
258
 
249
259
  if !@error? || @error(errors) is true
250
260
  errors = @__stringifyErrors(errors)
251
-
261
+
252
262
  Object.each errors, (field, notifications) =>
253
263
  input = @findField(field).addClass @invalidationClass
254
264
  @notification? input, notifications
@@ -256,7 +266,7 @@ class Joosy.Form extends Joosy.Module
256
266
  return errors
257
267
 
258
268
  return false
259
-
269
+
260
270
  #
261
271
  # Finds field by field name.
262
272
  # This is not inlined since we want to override
@@ -280,7 +290,7 @@ class Joosy.Form extends Joosy.Module
280
290
  value: method
281
291
  )
282
292
  @container.append method
283
-
293
+
284
294
  #
285
295
  # Prepares server response for default error handler
286
296
  # Turns all possible response notations into form notation (foo[bar])
@@ -297,17 +307,17 @@ class Joosy.Form extends Joosy.Module
297
307
  #
298
308
  # @param [Object] errors Data to prepare
299
309
  #
300
- # @return [Hash<String, Array>] Flat hash with field names in keys and arrays
310
+ # @return [Hash<String, Array>] Flat hash with field names in keys and arrays
301
311
  # of errors in values
302
312
  #
303
313
  __stringifyErrors: (errors) ->
304
314
  result = {}
305
-
315
+
306
316
  Object.each errors, (field, notifications) =>
307
317
  if @substitutions[field]?
308
318
  field = @substitutions[field]
309
319
 
310
- if Object.isObject notifications
320
+ if Object.isObject(notifications) || @isArrayOfObjects(notifications)
311
321
  Object.each @__foldInlineEntities(notifications), (key, value) ->
312
322
  result[field+key] = value
313
323
  else
@@ -318,7 +328,7 @@ class Joosy.Form extends Joosy.Module
318
328
  name = @resourceName || @__resource.__entityName
319
329
  field = name + "[#{field}]"
320
330
  field += "[#{f}]" for f in splited
321
-
331
+
322
332
  else if @resourceName || @__resource
323
333
  name = @resourceName || @__resource.__entityName
324
334
  field = name + "[#{field}]"
@@ -333,7 +343,7 @@ class Joosy.Form extends Joosy.Module
333
343
  # @example Basic flattening
334
344
  # data = foo: { bar: { baz: [] } }
335
345
  # inner = @__foldInlineEntities(data.foo, 'foo')
336
- #
346
+ #
337
347
  # inner # { "foo[bar][baz]": [] }
338
348
  #
339
349
  # @param [Object] hash Structure to fold
@@ -344,7 +354,7 @@ class Joosy.Form extends Joosy.Module
344
354
  #
345
355
  __foldInlineEntities: (hash, scope="", result={}) ->
346
356
  Object.each hash, (key, value) =>
347
- if Object.isObject(value)
357
+ if Object.isObject(value) || @isArrayOfObjects(value)
348
358
  @__foldInlineEntities(value, "#{scope}[#{key}]", result)
349
359
  else
350
360
  result["#{scope}[#{key}]"] = value
@@ -365,3 +375,6 @@ class Joosy.Form extends Joosy.Module
365
375
  items.splice 0, 1, first[0], first[1]
366
376
  items[items.length - 1] = items[items.length - 1].split(']')[0]
367
377
  items
378
+
379
+ isArrayOfObjects: (array) ->
380
+ Object.isArray(array) && array.every((elem) -> Object.isObject(elem))
@@ -5,17 +5,18 @@
5
5
  #
6
6
  Joosy.helpers 'Application', ->
7
7
 
8
- description = (resource, method, extendIds) ->
9
- if resource instanceof Joosy.Resource.Generic
8
+ description = (resource, method, extendIds, idSuffix) ->
9
+ if Joosy.Module.hasAncestor resource.constructor, Joosy.Resource.Generic
10
10
  id = resource.id()
11
11
  resource = resource.__entityName
12
12
 
13
13
  name: resource + "#{if method.match(/^\[.*\]$/) then method else "[#{method}]"}"
14
- id: resource + (if id && extendIds then '_'+id else '') + "_#{method.parameterize().underscore()}"
14
+ id: resource + (if id && extendIds then '_'+id else '') + "_#{method.parameterize().underscore()}" + (if idSuffix then '_'+idSuffix else '')
15
15
 
16
16
  input = (type, resource, method, options={}) =>
17
- d = description(resource, method, options.extendIds)
17
+ d = description(resource, method, options.extendIds, options.idSuffix)
18
18
  delete options.extendIds
19
+ delete options.idSuffix
19
20
  @tag 'input', Joosy.Module.merge {type: type, name: d.name, id: d.id}, options
20
21
 
21
22
  #
@@ -23,11 +24,18 @@ Joosy.helpers 'Application', ->
23
24
  #
24
25
  class Form
25
26
  constructor: (@context, @resource, @options) ->
26
- label: (method, options={}, content='') -> @context.label(@resource, method, Joosy.Module.merge(extendIds: @options.extendIds, options), content)
27
+
28
+ label: (method, options={}, content='') ->
29
+ if !Object.isObject(options)
30
+ content = options
31
+ options = {}
32
+
33
+ @context.label(@resource, method, Joosy.Module.merge(extendIds: @options.extendIds, options), content)
34
+
27
35
  radioButton: (method, tagValue, options={}) -> @context.radioButton(@resource, method, tagValue, Joosy.Module.merge(extendIds: @options.extendIds, options))
28
36
  textArea: (method, options={}) -> @context.textArea(@resource, method, Joosy.Module.merge(extendIds: @options.extendIds, options))
29
- checkBox: (method, options={}, checkedValue=1, uncheckedValue=0) ->
30
- @context.checkBox(@resource, method, Joosy.Module.merge(extendIds: @options.extendIds, options), checkedValue, uncheckedValue)
37
+ checkBox: (method, options={}, checkedValue=1, uncheckedValue=0) -> @context.checkBox(@resource, method, Joosy.Module.merge(extendIds: @options.extendIds, options), checkedValue, uncheckedValue)
38
+ select: (method, options={}, htmlOptions={}) -> @context.select @resource, method, options, Joosy.Module.merge(extendIds: @options.extendIds, htmlOptions)
31
39
 
32
40
  ['text', 'file', 'hidden', 'password'].each (type) =>
33
41
  Form.prototype[type+'Field'] = (method, options={}) ->
@@ -58,7 +66,7 @@ Joosy.helpers 'Application', ->
58
66
  ['text', 'file', 'hidden', 'password'].each (type) =>
59
67
  @[type+'Field'] = (resource, method, options={}) -> input type, resource, method, options
60
68
 
61
- @radioButton = (resource, method, tagValue, options={}) -> input 'radio', resource, method, Joosy.Module.merge(value: tagValue, options)
69
+ @radioButton = (resource, method, tagValue, options={}) -> input 'radio', resource, method, Joosy.Module.merge(value: tagValue, idSuffix: tagValue, options)
62
70
 
63
71
  @checkBox = (resource, method, options={}, checkedValue=1, uncheckedValue=0) ->
64
72
  spy = @tag 'input', Joosy.Module.merge(name: description(resource, method).name, value: uncheckedValue, type: 'hidden')
@@ -66,10 +74,31 @@ Joosy.helpers 'Application', ->
66
74
 
67
75
  spy+box
68
76
 
77
+ @select = (resource, method, options, htmlOptions) ->
78
+ if Object.isObject options
79
+ opts = []
80
+ for key, val of options
81
+ opts.push [val, key]
82
+ else
83
+ opts = options
84
+ if htmlOptions.includeBlank
85
+ delete htmlOptions.includeBlank
86
+ opts.unshift ['', '']
87
+ opts = opts.reduce (str, vals) =>
88
+ params = if Object.isArray vals then ['option', { value: vals[1] }, vals[0]] else ['option', {}, vals]
89
+ if htmlOptions.value == (if Object.isArray(vals) then vals[1] else vals)
90
+ params[1].selected = 'selected'
91
+ str += @.tag.apply @, params
92
+ , ''
93
+ extendIds = htmlOptions.extendIds
94
+ delete htmlOptions.value
95
+ delete htmlOptions.extendIds
96
+ @tag 'select', Joosy.Module.merge(description(resource, method, extendIds), htmlOptions), opts
97
+
69
98
  @textArea = (resource, method, options={}) ->
70
99
  value = options.value
71
100
  extendIds = options.extendIds
72
101
  delete options.value
73
102
  delete options.extendIds
74
103
 
75
- @tag 'textarea', Joosy.Module.merge(description(resource, method, extendIds), options), value
104
+ @tag 'textarea', Joosy.Module.merge(description(resource, method, extendIds), options), value
@@ -4,7 +4,7 @@
4
4
  # Rendering and string representation helpers
5
5
  #
6
6
  Joosy.helpers 'Application', ->
7
-
7
+
8
8
  @tag = (name, options={}, content='') ->
9
9
  content = content() if Object.isFunction(content)
10
10
 
@@ -12,7 +12,13 @@ Joosy.helpers 'Application', ->
12
12
  temp = document.createElement 'div'
13
13
 
14
14
  Object.each options, (name, value) -> element.setAttribute name, value
15
- element.innerHTML = content
15
+
16
+ try
17
+ element.innerHTML = content
18
+ catch e
19
+ # setting innerHTML fails in the IE for elements, which cann't have children (INPUT, for ex.)
20
+ # suppress this error unless content looks valuable
21
+ throw e if content
16
22
 
17
23
  temp.appendChild element
18
24
  temp.innerHTML
@@ -28,7 +34,7 @@ Joosy.helpers 'Application', ->
28
34
  #
29
35
  # Wraps the inline block into given template
30
36
  # Request template will receive the inline block as @yield parameter
31
- #
37
+ #
32
38
  # Example
33
39
  # -# foo/baz template
34
40
  # != @renderWrapped 'foo/bar', ->
@@ -39,4 +45,4 @@ Joosy.helpers 'Application', ->
39
45
  # != @yield
40
46
  #
41
47
  @renderWrapped = (template, lambda) ->
42
- @render template, Joosy.Module.merge(this, yield: lambda())
48
+ @render template, Joosy.Module.merge(this, yield: lambda())
@@ -7,7 +7,12 @@ Joosy.helpers 'Application', ->
7
7
 
8
8
  @widget = (element, widget) ->
9
9
  uuid = Joosy.uuid()
10
- element = @tag element, id: uuid
10
+ params = id: uuid
11
+ parts = element.split '.'
12
+ if parts[1]
13
+ params.class = parts.from(1).join ' '
14
+
15
+ element = @tag parts[0], params
11
16
 
12
17
  @onRefresh -> @registerWidget '#'+uuid, widget
13
18
 
@@ -8,12 +8,12 @@
8
8
  # Core modules container
9
9
  #
10
10
  Modules: {}
11
-
11
+
12
12
  #
13
13
  # Resources container
14
14
  #
15
15
  Resource: {}
16
-
16
+
17
17
  #
18
18
  # Templaters container
19
19
  #
@@ -25,7 +25,7 @@
25
25
  # @example Basic usage
26
26
  # Joosy.namespace 'foobar', ->
27
27
  # class @RealThing
28
- #
28
+ #
29
29
  # foo = new foobar.RealThing
30
30
  #
31
31
  # @param [String] name Namespace keyword
@@ -173,6 +173,8 @@
173
173
  space[className] = class extends Joosy.Resource.REST
174
174
  @entity resource
175
175
  @source path
176
+ __collection: ->
177
+ space[collectionName]
176
178
  unless space[collectionName]
177
179
  Joosy.Modules.Log.debugAs space, "Define #{collectionName}"
178
180
  space[collectionName] = class extends Joosy.Resource.RESTCollection