joosy 1.2.0.alpha.73 → 1.2.0.beta.1
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.
- checksums.yaml +4 -4
- data/Gruntfile.coffee +56 -18
- data/bower.json +1 -1
- data/build/joosy/form.js +1 -0
- data/build/joosy/resources.js +1 -0
- data/build/joosy.js +2 -2774
- data/package.json +5 -4
- data/source/joosy/application.coffee +9 -7
- data/source/joosy/{extensions/resources-form/form.coffee → form.coffee} +58 -51
- data/source/joosy/helpers/form.coffee +241 -0
- data/source/joosy/helpers/index.coffee +3 -0
- data/source/joosy/helpers/routes.coffee +3 -1
- data/source/joosy/helpers/view.coffee +9 -9
- data/source/joosy/joosy.coffee +3 -5
- data/source/joosy/module.coffee +9 -4
- data/source/joosy/modules/dom.coffee +33 -31
- data/source/joosy/modules/events.coffee +24 -20
- data/source/joosy/modules/filters.coffee +38 -35
- data/source/joosy/modules/page/title.coffee +3 -3
- data/source/joosy/modules/renderer.coffee +23 -18
- data/source/joosy/modules/resources/identity_map.coffee +45 -0
- data/source/joosy/modules/resources/model.coffee +146 -0
- data/source/joosy/modules/widgets_manager.coffee +8 -8
- data/source/joosy/resources/array.coffee +0 -5
- data/source/joosy/resources/hash.coffee +8 -13
- data/source/joosy/resources/index.coffee +2 -0
- data/source/joosy/{extensions/resources → resources}/rest.coffee +48 -19
- data/source/joosy/resources/scalar.coffee +8 -10
- data/source/joosy/router.coffee +13 -12
- data/source/joosy/templaters/jst.coffee +3 -2
- data/source/joosy/widget.coffee +17 -15
- data/source/joosy.coffee +2 -0
- data/source/vendor/es5-shim.js +1316 -0
- data/source/vendor/inflections.js +598 -0
- data/source/vendor/metamorph.js +457 -0
- data/spec/helpers/matchers.coffee +4 -4
- data/spec/joosy/core/application_spec.coffee +1 -1
- data/spec/joosy/core/helpers/view_spec.coffee +2 -2
- data/spec/joosy/core/joosy_spec.coffee +8 -4
- data/spec/joosy/core/modules/dom_spec.coffee +7 -7
- data/spec/joosy/core/modules/events_spec.coffee +2 -2
- data/spec/joosy/core/modules/filters_spec.coffee +7 -8
- data/spec/joosy/core/modules/module_spec.coffee +5 -5
- data/spec/joosy/core/router_spec.coffee +3 -3
- data/spec/joosy/core/widget_spec.coffee +6 -6
- data/spec/joosy/environments/amd_spec.coffee +4 -2
- data/spec/joosy/environments/global_spec.coffee +1 -1
- data/spec/joosy/{extensions/form → form}/form_spec.coffee +9 -16
- data/spec/joosy/{extensions/form → form}/helpers/forms_spec.coffee +5 -5
- data/spec/joosy/{core/resources → resources}/array_spec.coffee +2 -2
- data/spec/joosy/{core/resources → resources}/hash_spec.coffee +0 -8
- data/spec/joosy/{core/modules/resources → resources/modules}/cacher_spec.coffee +0 -0
- data/spec/joosy/resources/modules/identity_map_spec.coffee +47 -0
- data/spec/joosy/{extensions/resources/base_spec.coffee → resources/modules/model_spec.coffee} +28 -48
- data/spec/joosy/{extensions/resources → resources}/rest_spec.coffee +29 -22
- data/spec/joosy/{core/resources → resources}/scalar_spec.coffee +8 -8
- data/templates/application/application.coffee.tt +0 -2
- data/templates/environment/app/haml/index.haml +2 -2
- data/templates/environment/package.json +1 -1
- metadata +23 -19
- data/build/joosy/extensions/resources-form.js +0 -590
- data/build/joosy/extensions/resources.js +0 -561
- data/source/joosy/extensions/resources/base.coffee +0 -282
- data/source/joosy/extensions/resources/index.coffee +0 -1
- data/source/joosy/extensions/resources-form/helpers/form.coffee +0 -104
- data/source/joosy/extensions/resources-form/index.coffee +0 -1
- data/source/metamorph.coffee +0 -410
data/package.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"keywords": [
|
5
5
|
"joosy"
|
6
6
|
],
|
7
|
-
"version": "1.2.0-
|
7
|
+
"version": "1.2.0-beta.1",
|
8
8
|
"author": "Boris Staal <boris@staal.io>",
|
9
9
|
"homepage": "http://joosy.ws/",
|
10
10
|
"repository": {
|
@@ -15,15 +15,16 @@
|
|
15
15
|
"node": ">=0.4.0"
|
16
16
|
},
|
17
17
|
"dependencies": {
|
18
|
-
"grill": ">=1.0.0-alpha.
|
18
|
+
"grill": ">=1.0.0-alpha.22"
|
19
19
|
},
|
20
20
|
"devDependencies": {
|
21
21
|
"bower": "~1.2.1",
|
22
22
|
"semver": "~2.1.0",
|
23
23
|
"grunt-coffeelint": "0.0.6",
|
24
24
|
"grunt-release": "~0.3.5",
|
25
|
-
"grunt-contrib-testem": ">=0.5.
|
25
|
+
"grunt-contrib-testem": ">=0.5.3",
|
26
26
|
"grunt-gh-pages": "git+https://github.com/inossidabile/grunt-gh-pages.git",
|
27
|
-
"moment": "~2.1.0"
|
27
|
+
"moment": "~2.1.0",
|
28
|
+
"grunt-contrib-uglify": "~0.2.4"
|
28
29
|
}
|
29
30
|
}
|
@@ -1,8 +1,7 @@
|
|
1
1
|
#= require joosy/joosy
|
2
2
|
#= require joosy/router
|
3
|
-
#=
|
4
|
-
#=
|
5
|
-
#= require_tree ./helpers
|
3
|
+
#= require joosy/templaters/jst
|
4
|
+
#= require joosy/helpers
|
6
5
|
|
7
6
|
#
|
8
7
|
# Joosy Application container
|
@@ -15,7 +14,7 @@ class Joosy.Application
|
|
15
14
|
@initialized: false
|
16
15
|
@loading: true
|
17
16
|
|
18
|
-
@
|
17
|
+
@defaultConfig:
|
19
18
|
test: false
|
20
19
|
debug: false
|
21
20
|
templater:
|
@@ -36,8 +35,11 @@ class Joosy.Application
|
|
36
35
|
if @initialized
|
37
36
|
throw new Error 'Attempted to initialize Application twice'
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
@config = {}
|
39
|
+
|
40
|
+
Joosy.Module.merge @config, @defaultConfig, true, true
|
41
|
+
Joosy.Module.merge @config, window.JoosyEnvironment, true, true if window.JoosyEnvironment?
|
42
|
+
Joosy.Module.merge @config, options, true, true
|
41
43
|
|
42
44
|
@forceSandbox() if @config.test
|
43
45
|
|
@@ -47,7 +49,7 @@ class Joosy.Application
|
|
47
49
|
Joosy.Router.setup @config.router, (action, params) =>
|
48
50
|
if Joosy.Module.hasAncestor action, Joosy.Page
|
49
51
|
@changePage action, params
|
50
|
-
else if
|
52
|
+
else if typeof(action) == 'function'
|
51
53
|
action(params)
|
52
54
|
else
|
53
55
|
throw new Error "Unknown kind of route action: #{action}"
|
@@ -95,11 +95,10 @@ class Joosy.Form extends Joosy.Module
|
|
95
95
|
# @option options [Boolean] debounce Drop submit events while there is a pending submit request
|
96
96
|
#
|
97
97
|
constructor: (form, options={}) ->
|
98
|
-
if
|
98
|
+
if typeof(options) == 'function'
|
99
99
|
@success = options
|
100
100
|
else
|
101
|
-
|
102
|
-
@[key] = value
|
101
|
+
@[key] = value for key, value of options
|
103
102
|
|
104
103
|
@$container = $(form)
|
105
104
|
return if @$container.length == 0
|
@@ -108,7 +107,7 @@ class Joosy.Form extends Joosy.Module
|
|
108
107
|
@__delegateEvents()
|
109
108
|
|
110
109
|
method = @$container.get(0).getAttribute('method')?.toLowerCase()
|
111
|
-
if method && !['get', 'post'].
|
110
|
+
if method && !['get', 'post'].indexOf(method) != -1
|
112
111
|
@__markMethod method
|
113
112
|
@$container.attr 'method', 'POST'
|
114
113
|
|
@@ -155,7 +154,7 @@ class Joosy.Form extends Joosy.Module
|
|
155
154
|
|
156
155
|
#
|
157
156
|
# Links current form with given resource and sets values of form inputs from with it.
|
158
|
-
# Form will use
|
157
|
+
# Form will use given resource while doing invalidation routine.
|
159
158
|
#
|
160
159
|
# @param [Resource] resource Resource to fill fields with
|
161
160
|
# @param [Hash] options Options
|
@@ -166,7 +165,7 @@ class Joosy.Form extends Joosy.Module
|
|
166
165
|
# @option options [String] action Action URL for the form
|
167
166
|
#
|
168
167
|
fill: (resource, options) ->
|
169
|
-
resource = resource.build() if
|
168
|
+
resource = resource.build() if typeof(resource.build) == 'function'
|
170
169
|
@__resource = resource
|
171
170
|
|
172
171
|
if options?.decorator?
|
@@ -177,27 +176,29 @@ class Joosy.Form extends Joosy.Module
|
|
177
176
|
filler = (data, scope) =>
|
178
177
|
return if data.__joosy_form_filler_lock
|
179
178
|
data.__joosy_form_filler_lock = true
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
179
|
+
|
180
|
+
for property, val of data
|
181
|
+
do (property, val) =>
|
182
|
+
key = @concatFieldName scope, property
|
183
|
+
input = @$fields().filter("[name='#{key}']:not(:file),[name='#{inflection.underscore(key)}']:not(:file),[name='#{inflection.camelize(key, true)}']:not(:file)")
|
184
|
+
if input.length > 0
|
185
|
+
if input.is ':checkbox'
|
186
|
+
if val
|
187
|
+
input.attr 'checked', 'checked'
|
188
|
+
else
|
189
|
+
input.removeAttr 'checked'
|
190
|
+
else if input.is ':radio'
|
191
|
+
input.filter("[value='#{val}']").attr 'checked', 'checked'
|
187
192
|
else
|
188
|
-
input.
|
189
|
-
|
190
|
-
|
193
|
+
input.val val
|
194
|
+
if val instanceof Joosy.Resources.Array
|
195
|
+
for entity, i in val
|
196
|
+
filler entity.data, @concatFieldName(scope, "[#{property}_attributes][#{i}]")
|
197
|
+
else if val instanceof Joosy.Resources.REST
|
198
|
+
filler val.data, @concatFieldName(scope, "[#{property}_attributes]")
|
199
|
+
else if val?.constructor == Object || val instanceof Array
|
200
|
+
filler val, key
|
191
201
|
else
|
192
|
-
input.val val
|
193
|
-
if val instanceof Joosy.Resources.Array
|
194
|
-
for entity, i in val
|
195
|
-
filler entity.data, @concatFieldName(scope, "[#{property}_attributes][#{i}]")
|
196
|
-
else if val instanceof Joosy.Resources.REST
|
197
|
-
filler val.data, @concatFieldName(scope, "[#{property}_attributes]")
|
198
|
-
else if Object.isObject(val) || Object.isArray(val)
|
199
|
-
filler val, key
|
200
|
-
else
|
201
202
|
delete data.__joosy_form_filler_lock
|
202
203
|
|
203
204
|
filler data, resource.__entityName || options.resourceName
|
@@ -264,9 +265,10 @@ class Joosy.Form extends Joosy.Module
|
|
264
265
|
if !@error? || @error(errors) is true
|
265
266
|
errors = @__stringifyErrors(errors)
|
266
267
|
|
267
|
-
|
268
|
-
|
269
|
-
|
268
|
+
for field, notifications of errors
|
269
|
+
do (field, notifications) =>
|
270
|
+
input = @findField(field).addClass @invalidationClass
|
271
|
+
@notification? input, notifications
|
270
272
|
|
271
273
|
return errors
|
272
274
|
|
@@ -330,29 +332,30 @@ class Joosy.Form extends Joosy.Module
|
|
330
332
|
__stringifyErrors: (errors) ->
|
331
333
|
result = {}
|
332
334
|
|
333
|
-
errors = errors.errors if
|
335
|
+
errors = errors.errors if errors?.errors?.constructor == Object
|
334
336
|
|
335
|
-
|
336
|
-
|
337
|
-
|
337
|
+
for field, notifications of errors
|
338
|
+
do (field, notifications) =>
|
339
|
+
if @substitutions[field]?
|
340
|
+
field = @substitutions[field]
|
338
341
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
342
|
+
if notifications.constructor == Object || @isArrayOfObjects(notifications)
|
343
|
+
result[field+key] = value for key, value of @__foldInlineEntities(notifications)
|
344
|
+
|
345
|
+
else
|
346
|
+
if field.indexOf(".") != -1
|
347
|
+
splited = field.split '.'
|
348
|
+
field = splited.shift()
|
349
|
+
if @resourceName || @__resource
|
350
|
+
name = @resourceName || @__resource.__entityName
|
351
|
+
field = name + "[#{field}]"
|
352
|
+
field += "[#{f}]" for f in splited
|
350
353
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
+
else if @resourceName || @__resource
|
355
|
+
name = @resourceName || @__resource.__entityName
|
356
|
+
field = name + "[#{field}]"
|
354
357
|
|
355
|
-
|
358
|
+
result[field] = notifications
|
356
359
|
|
357
360
|
result
|
358
361
|
|
@@ -372,8 +375,8 @@ class Joosy.Form extends Joosy.Module
|
|
372
375
|
# @return [Hash]
|
373
376
|
#
|
374
377
|
__foldInlineEntities: (hash, scope="", result={}) ->
|
375
|
-
|
376
|
-
if
|
378
|
+
for key, value of hash
|
379
|
+
if value?.constructor == Object || @isArrayOfObjects(value)
|
377
380
|
@__foldInlineEntities(value, "#{scope}[#{key}]", result)
|
378
381
|
else
|
379
382
|
result["#{scope}[#{key}]"] = value
|
@@ -388,7 +391,7 @@ class Joosy.Form extends Joosy.Module
|
|
388
391
|
items = name.split('][')
|
389
392
|
first = items[0].split('[')
|
390
393
|
if first.length == 2
|
391
|
-
if first[0].
|
394
|
+
if first[0].length == 0
|
392
395
|
items.splice 0, 1, first[1]
|
393
396
|
else
|
394
397
|
items.splice 0, 1, first[0], first[1]
|
@@ -396,4 +399,8 @@ class Joosy.Form extends Joosy.Module
|
|
396
399
|
items
|
397
400
|
|
398
401
|
isArrayOfObjects: (array) ->
|
399
|
-
|
402
|
+
array instanceof Array && array.filter((elem) -> elem?.constructor != Object).length == 0
|
403
|
+
|
404
|
+
# AMD wrapper
|
405
|
+
if define?.amd?
|
406
|
+
define 'joosy/form', -> Joosy.Form
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#
|
2
|
+
# @private
|
3
|
+
#
|
4
|
+
class Form
|
5
|
+
constructor: (@context, @resource, @options) ->
|
6
|
+
|
7
|
+
__extend: (options) ->
|
8
|
+
options.extendIds = @options.extendIds
|
9
|
+
options
|
10
|
+
|
11
|
+
for type in ['text', 'file', 'hidden', 'password']
|
12
|
+
do (type) =>
|
13
|
+
@::[type+'Field'] = (property, options={}) ->
|
14
|
+
@context[type+'Field'] @resource, property, @__extend(options)
|
15
|
+
|
16
|
+
label: (property, options={}, content='') ->
|
17
|
+
# (property, content) ->
|
18
|
+
if arguments.length == 2
|
19
|
+
content = options
|
20
|
+
options = {}
|
21
|
+
|
22
|
+
@context.label @resource, property, @__extend(options), content
|
23
|
+
|
24
|
+
radioButton: (property, tagValue, options={}) ->
|
25
|
+
@context.radioButton @resource, property, tagValue, @__extend(options)
|
26
|
+
|
27
|
+
textArea: (property, options={}) ->
|
28
|
+
@context.textArea @resource, property, @__extend(options)
|
29
|
+
|
30
|
+
checkBox: (property, options={}, checkedValue=1, uncheckedValue=0) ->
|
31
|
+
@context.checkBox @resource, property, @__extend(options), checkedValue, uncheckedValue
|
32
|
+
|
33
|
+
select: (property, selectOptions={}, options={}) ->
|
34
|
+
@context.select @resource, property, selectOptions, @__extend(options)
|
35
|
+
|
36
|
+
#
|
37
|
+
# Form helper
|
38
|
+
#
|
39
|
+
Joosy.helpers 'Application', ->
|
40
|
+
|
41
|
+
separateOptions = (options, keys) ->
|
42
|
+
attributes = {}
|
43
|
+
parameters = {}
|
44
|
+
|
45
|
+
for key, value of options
|
46
|
+
if keys.indexOf(key) != -1
|
47
|
+
parameters[key] = value
|
48
|
+
else
|
49
|
+
attributes[key] = value
|
50
|
+
|
51
|
+
[parameters, attributes]
|
52
|
+
|
53
|
+
#
|
54
|
+
# Generates main attributes of a single field for a form
|
55
|
+
#
|
56
|
+
# @param [String] resource Name of resource
|
57
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
58
|
+
# @param [String] property Name of attribute the field is for
|
59
|
+
# @param [Boolean] extendIds Marks whether DOM id of a field should contain primary key of resource
|
60
|
+
# @param [String] idSuffix Suffix to append to DOM id
|
61
|
+
# @param [Hash] DOM attributes Initial set that should be extended
|
62
|
+
#
|
63
|
+
domify = (resource, property, extendIds, idSuffix, attributes) ->
|
64
|
+
if resource.__entityName? && resource.id?
|
65
|
+
resourceId = resource.id()
|
66
|
+
resource = resource.__entityName
|
67
|
+
|
68
|
+
unless attributes
|
69
|
+
attributes = {}
|
70
|
+
else
|
71
|
+
attributes = Joosy.Module.merge {}, attributes
|
72
|
+
|
73
|
+
attributes.name = resource
|
74
|
+
attributes.name += if property.match(/^\[.*\]$/) then property else "[#{property}]"
|
75
|
+
|
76
|
+
# Parameterizing property
|
77
|
+
property = property.replace(/[^a-z0-9\-_]+/gi, '_')
|
78
|
+
property = property.replace /^_+|_+$|(_)_+/g, '$1'
|
79
|
+
property = property.toLowerCase()
|
80
|
+
|
81
|
+
attributes.id = resource
|
82
|
+
attributes.id += "_#{resourceId}" if resourceId? && extendIds
|
83
|
+
attributes.id += "_#{property}"
|
84
|
+
attributes.id += "_#{idSuffix}" if idSuffix
|
85
|
+
|
86
|
+
attributes
|
87
|
+
|
88
|
+
#
|
89
|
+
# Generates input field
|
90
|
+
#
|
91
|
+
input = (type, resource, property, extendIds, idSuffix, attributes={}) =>
|
92
|
+
attributes.type = type
|
93
|
+
attributes = domify(resource, property, extendIds, idSuffix, attributes)
|
94
|
+
|
95
|
+
@tag 'input', attributes
|
96
|
+
|
97
|
+
#
|
98
|
+
# ======================================================================
|
99
|
+
#
|
100
|
+
|
101
|
+
#
|
102
|
+
# Instantiates a form builder
|
103
|
+
#
|
104
|
+
# @param [String] resource Name of resource
|
105
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
106
|
+
# @param [Function] block Inline template that will be rendered as a form
|
107
|
+
# @param [Object] options
|
108
|
+
#
|
109
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
110
|
+
#
|
111
|
+
# @example
|
112
|
+
# != @formFor Resource, {extendIds: true}, (form) =>
|
113
|
+
# != form.textField 'property'
|
114
|
+
#
|
115
|
+
@formFor = (resource, options={}, block) ->
|
116
|
+
# (options, block) ->
|
117
|
+
if arguments.length == 2
|
118
|
+
block = options
|
119
|
+
options = {}
|
120
|
+
|
121
|
+
attributes = Joosy.Module.merge(options.html || {}, id: uuid)
|
122
|
+
uuid = Joosy.uuid()
|
123
|
+
form = new Form @, resource, options
|
124
|
+
|
125
|
+
@tag 'form', attributes, block?.call(@, form)
|
126
|
+
|
127
|
+
#
|
128
|
+
# Generates `label` tag
|
129
|
+
#
|
130
|
+
# @param [String] resource Name of resource
|
131
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
132
|
+
# @param [String] property Attribute of a resource to use
|
133
|
+
# @param [Object] options
|
134
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
135
|
+
# @param [String] content Content of the label
|
136
|
+
#
|
137
|
+
@label = (resource, property, options={}, content='') ->
|
138
|
+
# (resource, property, content) ->
|
139
|
+
if arguments.length == 3
|
140
|
+
content = options
|
141
|
+
options = {}
|
142
|
+
|
143
|
+
[parameters, attributes] = separateOptions options, ['extendIds']
|
144
|
+
|
145
|
+
attributes.for = domify(resource, property, parameters.extendIds, '', attributes).id
|
146
|
+
|
147
|
+
@contentTag 'label', content, attributes
|
148
|
+
|
149
|
+
#
|
150
|
+
# Set of typical generators for basic inputs: textField, fileField, hiddenField, passwordField
|
151
|
+
#
|
152
|
+
for type in ['text', 'file', 'hidden', 'password']
|
153
|
+
do (type) =>
|
154
|
+
@[type+'Field'] = (resource, property, options={}) ->
|
155
|
+
[parameters, attributes] = separateOptions options, ['extendIds']
|
156
|
+
|
157
|
+
input type, resource, property, parameters.extendIds, '', attributes
|
158
|
+
|
159
|
+
#
|
160
|
+
# Generates a radio button
|
161
|
+
#
|
162
|
+
# @param [String] resource Name of resource
|
163
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
164
|
+
# @param [String] property Attribute of a resource to use
|
165
|
+
# @param [Object] options
|
166
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
167
|
+
# @param [String] tagValue Value of the button
|
168
|
+
#
|
169
|
+
@radioButton = (resource, property, tagValue, options={}) ->
|
170
|
+
[parameters, attributes] = separateOptions(options, ['extendIds'])
|
171
|
+
|
172
|
+
attributes.value = tagValue
|
173
|
+
input 'radio', resource, property, options.extendIds, tagValue, attributes
|
174
|
+
|
175
|
+
#
|
176
|
+
# Generates a checkbox
|
177
|
+
#
|
178
|
+
# @param [String] resource Name of resource
|
179
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
180
|
+
# @param [String] property Attribute of a resource to use
|
181
|
+
# @param [Object] options
|
182
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
183
|
+
# @param [String] checkedValue Value for the checked condition
|
184
|
+
# @param [String] uncheckedValue Value for the unchecked condition
|
185
|
+
#
|
186
|
+
@checkBox = (resource, property, options={}, checkedValue=1, uncheckedValue=0) ->
|
187
|
+
[parameters, attributes] = separateOptions(options, ['extendIds'])
|
188
|
+
|
189
|
+
spyAttributes = domify resource, property, parameters.extendIds, '', attributes
|
190
|
+
spy = @tag 'input', name: spyAttributes.name, value: uncheckedValue, type: 'hidden'
|
191
|
+
|
192
|
+
attributes.value = checkedValue
|
193
|
+
box = input 'checkbox', resource, property, parameters.extendIds, '', attributes
|
194
|
+
|
195
|
+
spy+box
|
196
|
+
|
197
|
+
#
|
198
|
+
# Generates a select
|
199
|
+
#
|
200
|
+
# @param [String] resource Name of resource
|
201
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
202
|
+
# @param [String] property Attribute of a resource to use
|
203
|
+
# @param [Object] options
|
204
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
205
|
+
# @option options [String] value Sets current value of a select
|
206
|
+
# @option options [Boolean] includeBlank Marks if select should contain blank starting option
|
207
|
+
# @param [Object] selectOptions Options to build select with `{foo: 'bar'}`
|
208
|
+
# @param [Array] selectOptions Options to build select with `['foo', 'bar']`
|
209
|
+
#
|
210
|
+
@select = (resource, property, rawSelectOptions, options) ->
|
211
|
+
[parameters, attributes] = separateOptions(options, ['extendIds', 'value', 'includeBlank'])
|
212
|
+
|
213
|
+
if rawSelectOptions instanceof Array
|
214
|
+
selectOptions = rawSelectOptions
|
215
|
+
else
|
216
|
+
selectOptions = []
|
217
|
+
selectOptions.push [val, key] for key, val of rawSelectOptions
|
218
|
+
|
219
|
+
selectOptions.unshift ['', ''] if parameters.includeBlank
|
220
|
+
selectOptions = selectOptions.reduce (str, vals) =>
|
221
|
+
params = if (vals instanceof Array) then ['option', vals[0], { value: vals[1] }] else ['option', vals, {}]
|
222
|
+
if parameters.value == (if (vals instanceof Array) then vals[1] else vals)
|
223
|
+
params[2].selected = 'selected'
|
224
|
+
str += @contentTag.apply @, params
|
225
|
+
, ''
|
226
|
+
|
227
|
+
@contentTag 'select', selectOptions, domify(resource, property, parameters.extendIds, '', attributes)
|
228
|
+
|
229
|
+
#
|
230
|
+
# Generates a text area
|
231
|
+
#
|
232
|
+
# @param [String] resource Name of resource
|
233
|
+
# @param [Object] resource Instance of something that includes Joosy.Modules.Resources.Module
|
234
|
+
# @param [String] property Attribute of a resource to use
|
235
|
+
# @param [Object] options
|
236
|
+
# @option options [Boolean] extendIds Marks if DOM ids of fields should include primary key of resource (default: false)
|
237
|
+
# @option options [String] value Value of the text area
|
238
|
+
#
|
239
|
+
@textArea = (resource, property, options={}) ->
|
240
|
+
[parameters, attributes] = separateOptions(options, ['extendIds', 'value'])
|
241
|
+
@contentTag 'textarea', parameters.value, domify(resource, property, parameters.extendIds, '', attributes)
|
@@ -7,7 +7,9 @@
|
|
7
7
|
Joosy.helpers 'Routes', ->
|
8
8
|
|
9
9
|
@linkTo = (name='', url='', tagOptions={}) ->
|
10
|
-
|
10
|
+
|
11
|
+
# (url, tagOptions, block) ->
|
12
|
+
if typeof(tagOptions) == 'function'
|
11
13
|
block = tagOptions
|
12
14
|
[url, tagOptions] = [name, url]
|
13
15
|
name = block()
|
@@ -55,9 +55,9 @@ Joosy.helpers 'Application', ->
|
|
55
55
|
#
|
56
56
|
# Possible arguments variations:
|
57
57
|
# 1. @contentTag 'name', 'content'
|
58
|
-
# 2. @contentTag 'name',
|
59
|
-
# 3. @contentTag 'name', {},
|
60
|
-
# 4. @contentTag 'name', ->
|
58
|
+
# 2. @contentTag 'name', ->
|
59
|
+
# 3. @contentTag 'name', {}, ->
|
60
|
+
# 4. @contentTag 'name', {}, false, ->
|
61
61
|
#
|
62
62
|
# Example
|
63
63
|
# != @contentTag 'div', {class: 'foo'}, =>
|
@@ -66,20 +66,20 @@ Joosy.helpers 'Application', ->
|
|
66
66
|
@contentTag = (name, contentOrOptions=null, options=null, escape=true) ->
|
67
67
|
# This is a bit painfull but this is
|
68
68
|
# how we emulate Ruby block with lambda :(
|
69
|
-
if
|
69
|
+
if typeof(contentOrOptions) == 'string'
|
70
70
|
options ||= {}
|
71
71
|
content = contentOrOptions
|
72
|
-
else if
|
73
|
-
|
72
|
+
else if typeof(contentOrOptions) == 'function'
|
73
|
+
options = {}
|
74
|
+
content = contentOrOptions()
|
75
|
+
else
|
76
|
+
if typeof(options) == 'function'
|
74
77
|
escape = true
|
75
78
|
content = options()
|
76
79
|
else
|
77
80
|
escape = options
|
78
81
|
content = escape()
|
79
82
|
options = contentOrOptions
|
80
|
-
else
|
81
|
-
options = {}
|
82
|
-
content = contentOrOptions()
|
83
83
|
|
84
84
|
element = document.createElement name
|
85
85
|
temp = document.createElement 'div'
|
data/source/joosy/joosy.coffee
CHANGED
@@ -139,17 +139,15 @@
|
|
139
139
|
#
|
140
140
|
buildUrl: (url, params) ->
|
141
141
|
paramsString = []
|
142
|
-
|
143
|
-
Object.each params, (key, value) ->
|
144
|
-
paramsString.push "#{key}=#{value}"
|
142
|
+
paramsString.push "#{key}=#{value}" for key, value of params
|
145
143
|
|
146
144
|
hash = url.match(/(\#.*)?$/)[0]
|
147
145
|
url = url.replace /\#.*$/, ''
|
148
|
-
if
|
146
|
+
if paramsString.length != 0 && url.indexOf('?') == -1
|
149
147
|
url = url + "?"
|
150
148
|
|
151
149
|
paramsString = paramsString.join '&'
|
152
|
-
if
|
150
|
+
if paramsString.length > 0 && url[url.length-1] != '?'
|
153
151
|
paramsString = '&' + paramsString
|
154
152
|
|
155
153
|
url + paramsString + hash
|
data/source/joosy/module.coffee
CHANGED
@@ -19,7 +19,7 @@ class Joosy.Module
|
|
19
19
|
# @return [String]
|
20
20
|
#
|
21
21
|
@__className: (klass) ->
|
22
|
-
unless
|
22
|
+
unless typeof(klass) == 'function'
|
23
23
|
klass = klass.constructor
|
24
24
|
|
25
25
|
if klass.name?
|
@@ -61,7 +61,7 @@ class Joosy.Module
|
|
61
61
|
camelized = feature.charAt(0).toUpperCase() + feature.slice(1)
|
62
62
|
chained = "#{method}Without#{camelized}"
|
63
63
|
|
64
|
-
action = @::[action] unless
|
64
|
+
action = @::[action] unless typeof(action) == 'function'
|
65
65
|
|
66
66
|
@::[chained] = @::[method]
|
67
67
|
@::[method] = action
|
@@ -91,14 +91,19 @@ class Joosy.Module
|
|
91
91
|
# @param [Object] destination Object to extend
|
92
92
|
# @param [Object] source Source of new properties
|
93
93
|
# @param [Boolean] unsafe Determines if we should rewrite destination properties
|
94
|
+
# @param [Boolean] deep Whether merge should go down recursively into nested objects
|
94
95
|
#
|
95
96
|
# @return [Object] The new and mighty destination Object
|
96
97
|
#
|
97
|
-
@merge: (destination, source, unsafe=true) ->
|
98
|
+
@merge: (destination, source, unsafe=true, deep=false) ->
|
98
99
|
for key, value of source
|
99
100
|
if source.hasOwnProperty(key)
|
100
101
|
if unsafe || !destination.hasOwnProperty(key)
|
101
|
-
|
102
|
+
if deep && value.constructor == Object
|
103
|
+
destination[key] = {} unless destination[key]?.constructor == Object
|
104
|
+
Joosy.Module.merge destination[key], value
|
105
|
+
else
|
106
|
+
destination[key] = value
|
102
107
|
destination
|
103
108
|
|
104
109
|
#
|