pinkman 0.9.9.9.11 → 1.0.0
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/README.md +1 -1
- data/app/assets/javascripts/pinkman_base/cache.coffee +12 -2
- data/app/assets/javascripts/pinkman_base/collection.coffee +85 -70
- data/app/assets/javascripts/pinkman_base/common.coffee +31 -2
- data/app/assets/javascripts/pinkman_base/controller.coffee +42 -28
- data/app/assets/javascripts/pinkman_base/object.coffee.erb +21 -12
- data/app/assets/javascripts/pinkman_base/pinkman.coffee +50 -2
- data/app/assets/javascripts/pinkman_base/render.coffee.erb +26 -3
- data/app/assets/javascripts/pinkman_base/router.coffee +91 -38
- data/lib/generators/pinkman/install_generator.rb +4 -3
- data/lib/generators/pinkman/templates/api.rb.erb +14 -14
- data/lib/generators/pinkman/templates/api_controller.rb +17 -26
- data/lib/generators/pinkman/templates/initializer.rb.erb +5 -1
- data/lib/pinkman/form_helper/form_helpers.rb +7 -1
- data/lib/pinkman/serializer/base.rb +5 -1
- data/lib/pinkman/serializer/scope.rb +16 -2
- data/lib/pinkman/version.rb +1 -1
- data/lib/pinkman/views_helpers/form_helper.rb +7 -3
- data/lib/pinkman/views_helpers/template_helper.rb +14 -6
- data/lib/pinkman/views_helpers/writer_helper.rb +3 -2
- data/lib/pinkman/views_helpers.rb +2 -2
- data/lib/pinkman.rb +22 -18
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99be758a6c0fd2b3b91ded4b49b176b0084daa153008390ce2d7a0301b763339
|
4
|
+
data.tar.gz: 7652fe78dbacada668465d7aa3abc24789439f87b8f9d32b8e861dc9467f3dd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b200b9dc96f6cdc0ff71a583d16e21dd65d953100f465fef9e2c0716009ffdc67f5226962e4fd52b5be931988bc9834a26f68e6793e8d949a7818a115ee529fb
|
7
|
+
data.tar.gz: dcaca3c9a82cec48a1304ed40d0be1efb1ed480b0ecfeef432c611bfe764c83797a387fea888c10b121699c7a1f5789a2ee428b1f40d0cbff45ea748cc57e83a
|
data/README.md
CHANGED
@@ -10,9 +10,19 @@ class window.PinkmanCache
|
|
10
10
|
|
11
11
|
@has: (name) ->
|
12
12
|
@_caching[name]?
|
13
|
+
|
14
|
+
@getOrInsert: (name, value) =>
|
15
|
+
if @has(name)
|
16
|
+
# console.log "has: #{name}"
|
17
|
+
return(@get(name))
|
18
|
+
else
|
19
|
+
# console.log "caching: #{name}"
|
20
|
+
return(@cache(name, value))
|
21
|
+
|
22
|
+
@get: (name, callback) ->
|
23
|
+
callback(@_caching[name]) if $p.isFunction(callback)
|
24
|
+
return(@_caching[name])
|
13
25
|
|
14
|
-
@get: (name) ->
|
15
|
-
@_caching[name]
|
16
26
|
|
17
27
|
$(document).ready ->
|
18
28
|
window.$c = window.PinkmanCache
|
@@ -1,6 +1,9 @@
|
|
1
1
|
class window.PinkmanCollection extends window.PinkmanCommon
|
2
2
|
|
3
3
|
@pinkmanType = 'collection'
|
4
|
+
|
5
|
+
@objectClass: ->
|
6
|
+
@firstInstanceOrInitialize().config.memberClass
|
4
7
|
|
5
8
|
config:
|
6
9
|
memberClass: PinkmanObject
|
@@ -10,7 +13,14 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
10
13
|
@isCollection = true
|
11
14
|
@pinkmanType = 'collection'
|
12
15
|
@collection = []
|
16
|
+
if @constructor.name? and @constructor.name!='PinkmanCollection'
|
17
|
+
if $p.isArray(@constructor.instances)
|
18
|
+
@constructor.instances.push(this)
|
19
|
+
else
|
20
|
+
@constructor.instances = [this]
|
21
|
+
|
13
22
|
Pinkman.collections.push(this)
|
23
|
+
|
14
24
|
|
15
25
|
# Desc: return an array of all members
|
16
26
|
# this behaviour makes life easier... trust me
|
@@ -230,7 +240,7 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
230
240
|
i = @collection.indexOf(value)
|
231
241
|
@collection.splice(i,1)
|
232
242
|
else
|
233
|
-
console.log 'js'
|
243
|
+
# console.log 'js'
|
234
244
|
i = @collection.indexOf object
|
235
245
|
@collection.splice(i,1)
|
236
246
|
value = object
|
@@ -529,56 +539,40 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
529
539
|
# string: search
|
530
540
|
# obj: select (cache) / where (server)
|
531
541
|
# function: select
|
532
|
-
|
533
|
-
@get: (query, callback) ->
|
534
|
-
@startCaching()
|
535
|
-
|
536
|
-
# query md5
|
537
|
-
query_md5 = md5(JSON.stringify(query) + @_name_md5)
|
538
|
-
|
539
|
-
if $c.has(query_md5)
|
540
|
-
@handleGetCollection($c.get(query_md5),callback)
|
541
|
-
else
|
542
|
-
# TRYING TO FIND IN CACHE
|
543
|
-
$c.get(@_name_md5).select query, (cache) =>
|
544
|
-
# CACHED FOUND
|
545
|
-
if cache.any()
|
546
|
-
# console.log 'cached'
|
547
|
-
@handleGetCollection(cache,callback)
|
548
|
-
|
549
|
-
# CACHED VERSION NOT FOUND -> ASK SERVER
|
550
|
-
else
|
551
|
-
# console.log 'server'
|
552
|
-
col = new this
|
553
|
-
obj = new col.config.memberClass
|
554
|
-
params = new Object
|
555
|
-
params.scope = Pinkman.scope(obj)
|
556
|
-
params.query = query
|
557
|
-
Pinkman.ajax.get
|
558
|
-
url: obj.api('get')
|
559
|
-
data: params
|
560
|
-
complete: (response) =>
|
561
|
-
col.fetchFromArray(response)
|
562
|
-
# PERFOMING INSTANCES CACHE
|
563
|
-
col.each (obj) =>
|
564
|
-
$c.get(@_name_md5).push(obj)
|
565
|
-
|
566
|
-
# CACHING THIS QUERY
|
567
|
-
$c.cache(query_md5,col)
|
568
|
-
|
569
|
-
callback(col) if $p.isFunction(callback)
|
570
|
-
return(col)
|
571
542
|
|
572
|
-
@
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
543
|
+
@get: (options) ->
|
544
|
+
if $p.isObject(options) and (options.query? or options.params?) and $p.isFunction(options.callback)
|
545
|
+
@startCaching()
|
546
|
+
options.cache = yes unless options.cache?
|
547
|
+
query = Pinkman.mergeObjects(options.scope, Pinkman.mergeObjects(options.query, options.params))
|
548
|
+
query_md5 = md5(JSON.stringify(query) + @_name_md5)
|
549
|
+
if options.cache and $c.has(query_md5)
|
550
|
+
$c.get(query_md5, options.callback)
|
551
|
+
else
|
552
|
+
col = new this
|
553
|
+
obj = new col.config.memberClass
|
554
|
+
params = new Object
|
555
|
+
params.scope = options.scope || Pinkman.scope(obj)
|
556
|
+
params.query = options.query
|
557
|
+
params = Pinkman.mergeObjects(params, options.params)
|
558
|
+
Pinkman.ajax.get
|
559
|
+
url: options.url || obj.api('get')
|
560
|
+
data: params
|
561
|
+
complete: (response) =>
|
562
|
+
col.fetchFromArray(response)
|
563
|
+
$c.cache(query_md5, col)
|
564
|
+
options.callback(col)
|
565
|
+
else
|
566
|
+
throw "Pinkman Error: collection.get invalid options #{options.toString()}"
|
567
|
+
|
568
|
+
@one: (options) ->
|
569
|
+
if $p.isObject(options) and $p.isFunction(options.callback)
|
570
|
+
args = Pinkman.dup(options)
|
571
|
+
args.callback = (col) ->
|
572
|
+
return(options.callback(col.first()))
|
573
|
+
@get(args)
|
574
|
+
else
|
575
|
+
return(throw("Pinkman Error: #{this.toString()}.one called with wrong arguments."))
|
582
576
|
|
583
577
|
@single: (args...) ->
|
584
578
|
@one(args...)
|
@@ -592,9 +586,21 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
592
586
|
# Desc: Fetch records from API_URL
|
593
587
|
# request: get /api/API_URL/
|
594
588
|
# in rails: api::controller#index
|
595
|
-
fetch: (
|
596
|
-
|
597
|
-
|
589
|
+
fetch: (args...) ->
|
590
|
+
switch args.length
|
591
|
+
when 1
|
592
|
+
if $p.isFunction(args[0])
|
593
|
+
callback = args[0]
|
594
|
+
@fetchFromUrl url: @api(), callback: callback, scope: 'public'
|
595
|
+
|
596
|
+
else if $p.isObject(args[0])
|
597
|
+
options = args[0]
|
598
|
+
@fetchFromUrl url: (options.url || @api()), callback: options.callback, scope: options.scope
|
599
|
+
when 2
|
600
|
+
scope = args[0]
|
601
|
+
callback = args[1]
|
602
|
+
@fetchFromUrl url: @api(), callback: callback, scope: scope
|
603
|
+
|
598
604
|
# Desc: Fetch records from another action of this model api
|
599
605
|
# request: get /api/API_URL/:action/#id
|
600
606
|
# in rails: api::controller#action
|
@@ -615,21 +621,21 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
615
621
|
fetchFromUrl: (options) ->
|
616
622
|
if options? and typeof options == 'object' and options.url?
|
617
623
|
options_md5 = md5(JSON.stringify(options) + @className())
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
624
|
+
options.params = new Object unless options.params?
|
625
|
+
options.cache = yes unless options.cache?
|
626
|
+
if options.scope?
|
627
|
+
options.params.scope = options.scope
|
628
|
+
else
|
629
|
+
throw 'Pinkman Error: Trying to fetch without a specified scope'
|
630
|
+
|
631
|
+
@doneFetching = null
|
632
|
+
@fetchingFrom = options.url
|
633
|
+
Pinkman.ajax.get
|
634
|
+
url: Pinkman.json2url(options.url, options.params)
|
635
|
+
complete: (response) =>
|
636
|
+
$c.cache(options_md5, response) if options.cache
|
637
|
+
@handleFetchResponse(response, options)
|
638
|
+
return(this)
|
633
639
|
|
634
640
|
handleFetchResponse: (response,options) ->
|
635
641
|
@constructor.startCaching()
|
@@ -685,8 +691,17 @@ class window.PinkmanCollection extends window.PinkmanCommon
|
|
685
691
|
# request: get /api/API_URL/search?query=YOUR_QUERY
|
686
692
|
# in rails: api::controller#search
|
687
693
|
# assume models to have a Model.search("YOUR_QUERY") method.
|
688
|
-
search: (
|
694
|
+
search: (args...) ->
|
689
695
|
@removeAll()
|
690
|
-
|
696
|
+
if args.length == 2
|
697
|
+
[query, callback] = args
|
698
|
+
else if args.length == 1 and $p.isObject(args[0])
|
699
|
+
options = args[0]
|
700
|
+
query = options.query
|
701
|
+
callback = options.callback
|
702
|
+
scope = options.scope || 'public'
|
703
|
+
return(@fetchFromUrl { url: @api() + 'search', params: {query: query}, callback: callback, scope: (scope || 'public') })
|
704
|
+
|
705
|
+
|
691
706
|
|
692
707
|
window.Pinkman.collection = window.PinkmanCollection
|
@@ -22,11 +22,18 @@ class window.PinkmanCommon
|
|
22
22
|
@isInstance: (object) ->
|
23
23
|
object.constructor is this
|
24
24
|
|
25
|
+
@firstInstanceOrInitialize: ->
|
26
|
+
obj = if $p.isArray(@instances) and @instances.length >= 1 then @instances[0] else new this
|
27
|
+
|
28
|
+
@api: (args...) ->
|
29
|
+
@firstInstanceOrInitialize().api(args...)
|
30
|
+
|
25
31
|
initialize: (attributesObject) ->
|
26
32
|
if typeof attributesObject == 'object'
|
27
33
|
for key, value of attributesObject
|
28
34
|
@set(key,value) if PinkmanObject.privateAttributes.indexOf(key) is -1
|
29
|
-
|
35
|
+
|
36
|
+
|
30
37
|
# Desc: return api url path
|
31
38
|
api: (paths...) ->
|
32
39
|
if @config? and @config.api?
|
@@ -145,6 +152,28 @@ class window.PinkmanCommon
|
|
145
152
|
@append
|
146
153
|
template: options + '-template'
|
147
154
|
target: options
|
155
|
+
|
156
|
+
prepend: (options) ->
|
157
|
+
if options? and typeof options == 'object' and options.target?
|
158
|
+
options.template = options.target + '-template' unless options.template? and options.template != ''
|
159
|
+
newOptions = new Object
|
160
|
+
for k,v of options
|
161
|
+
newOptions[k] = v if k != 'target' and k != 'callback'
|
162
|
+
newOptions.reRender = no
|
163
|
+
target = options.target
|
164
|
+
wrapIn = options.wrapIn
|
165
|
+
newOptions.object = this
|
166
|
+
newOptions.callback = (object,content) ->
|
167
|
+
if wrapIn?
|
168
|
+
$('#'+target).prepend("<div class='#{wrapIn}'>#{content}</div>")
|
169
|
+
else
|
170
|
+
$('#'+target).prepend(content)
|
171
|
+
options.callback(object,content) if options.callback? and typeof options.callback == 'function'
|
172
|
+
Pinkman.render(newOptions)
|
173
|
+
else if options? and Pinkman.isString(options)
|
174
|
+
@prepend
|
175
|
+
template: options + '-template'
|
176
|
+
target: options
|
148
177
|
|
149
178
|
_queue: (options) ->
|
150
179
|
options.id = options.template
|
@@ -152,7 +181,7 @@ class window.PinkmanCommon
|
|
152
181
|
@renderQueue.directPush(options)
|
153
182
|
|
154
183
|
hasError: ->
|
155
|
-
@errors?
|
184
|
+
return(this) if @errors?
|
156
185
|
|
157
186
|
hasErrors: ->
|
158
187
|
@hasError()
|
@@ -32,11 +32,8 @@ class window.PinkmanController extends window.PinkmanObject
|
|
32
32
|
'#' + @id
|
33
33
|
|
34
34
|
setParams: (params) ->
|
35
|
-
|
36
|
-
|
37
|
-
@params = JSON.parse('{"' + decodeURI(query).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')
|
38
|
-
else
|
39
|
-
@params = new Object
|
35
|
+
# console.log params
|
36
|
+
@params = new Object
|
40
37
|
|
41
38
|
(@params[k] = v) for k,v of params if params? and typeof params == 'object'
|
42
39
|
@params
|
@@ -98,7 +95,7 @@ class window.PinkmanController extends window.PinkmanObject
|
|
98
95
|
# but... in a few ocasions, the developer must have the capability to exclude certain attributes from this binding.
|
99
96
|
# thats when the "except" option comes in
|
100
97
|
# maybe a "only" option is going to be implemented in the near future
|
101
|
-
bindAllSelector: (id,options) ->
|
98
|
+
bindAllSelector: (id, options) ->
|
102
99
|
except = options.except if $p.isObject(options) and options.except?
|
103
100
|
selector = "##{@id} form [data-action], ##{@id} .form [data-action]"
|
104
101
|
|
@@ -130,7 +127,7 @@ class window.PinkmanController extends window.PinkmanObject
|
|
130
127
|
|
131
128
|
PinkmanAction.define
|
132
129
|
id: "#{@pinkey}-bindAll"
|
133
|
-
selector: @bindAllSelector(@id,options)
|
130
|
+
selector: @bindAllSelector(@id, options)
|
134
131
|
eventName: ['change','keyup']
|
135
132
|
controller: this
|
136
133
|
callback: (obj,$j) ->
|
@@ -162,7 +159,7 @@ class window.PinkmanController extends window.PinkmanObject
|
|
162
159
|
|
163
160
|
# === Autocomplete ===
|
164
161
|
|
165
|
-
# -- Usage: autocomplete(input_name,options)
|
162
|
+
# -- Usage: autocomplete(input_name, options)
|
166
163
|
|
167
164
|
# -- Overview
|
168
165
|
# 1: User types something
|
@@ -171,7 +168,7 @@ class window.PinkmanController extends window.PinkmanObject
|
|
171
168
|
# 4: Pinkman sends the selected record to callback function
|
172
169
|
|
173
170
|
# -- Parameters & Options
|
174
|
-
# @autocomplete(attribute,options)
|
171
|
+
# @autocomplete(attribute, options)
|
175
172
|
# options:
|
176
173
|
# with: [collection]
|
177
174
|
# pinkman collection responsible for filtering/searching the results
|
@@ -179,9 +176,19 @@ class window.PinkmanController extends window.PinkmanObject
|
|
179
176
|
# method: [search|yourCustomMethod]
|
180
177
|
# Search is the default. Anythings that filters by a 'query'.
|
181
178
|
# You can define a yourCustomMethod inside the collection model like this:
|
182
|
-
# yourCustomMethod: (
|
183
|
-
|
184
|
-
#
|
179
|
+
# yourCustomMethod: (options) ->
|
180
|
+
|
181
|
+
# 1. perfom some filter on the collection based on options.query
|
182
|
+
|
183
|
+
# 2. don't forget to verify if user can access the requested scope in case of api comunications
|
184
|
+
|
185
|
+
# 3. call options.callback whenever the collection is ready
|
186
|
+
|
187
|
+
# options object explanation:
|
188
|
+
# options.query: what user is trying to find/search
|
189
|
+
# options.scope: scope user is trying to access (in case of api comunications)
|
190
|
+
# options.callback: call this function with the filtered collection when it's ready
|
191
|
+
|
185
192
|
|
186
193
|
# template: [template-id] (optional)
|
187
194
|
# Any template that has a 'select-attribute' action
|
@@ -205,6 +212,7 @@ class window.PinkmanController extends window.PinkmanObject
|
|
205
212
|
# variables // user options // default options
|
206
213
|
collection = options.with
|
207
214
|
callback = options.call
|
215
|
+
scope = if options.scope? then options.scope else 'public'
|
208
216
|
template = if options.template? then options.template else "#{attr_name}-autocomplete"
|
209
217
|
target = if options.target? then options.target else "#{attr_name}-autocomplete"
|
210
218
|
method = if options.method? then options.method else 'search'
|
@@ -214,6 +222,9 @@ class window.PinkmanController extends window.PinkmanObject
|
|
214
222
|
wait = if options.wait? then options.wait else 0.75
|
215
223
|
waitTimerName = "#{attr_name}AutocompleteTimer"
|
216
224
|
|
225
|
+
|
226
|
+
# collection.set('_autocompleting', attr_name)
|
227
|
+
|
217
228
|
# hide initially
|
218
229
|
$("##{target}").hide() if autoHide
|
219
230
|
|
@@ -236,23 +247,26 @@ class window.PinkmanController extends window.PinkmanObject
|
|
236
247
|
window[waitTimerName] = $p.sleep wait, =>
|
237
248
|
|
238
249
|
# calls the filter method (search)
|
239
|
-
collection[method]
|
250
|
+
collection[method]
|
251
|
+
query: obj[attr_name]
|
252
|
+
scope: scope
|
253
|
+
callback: (collection) ->
|
240
254
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
255
|
+
# render results
|
256
|
+
collection.render
|
257
|
+
template: template
|
258
|
+
target: target
|
259
|
+
callback: ->
|
260
|
+
# Hide or show autocomplete
|
261
|
+
if autoHide
|
262
|
+
if obj[attr_name]? and obj[attr_name] != ''
|
263
|
+
$("##{target}").fadeIn()
|
264
|
+
else
|
265
|
+
$("##{target}").fadeOut()
|
266
|
+
|
267
|
+
# Set the autocomplete target width to same as the input
|
268
|
+
if autoWidth
|
269
|
+
$("##{target}").width($("input[name='#{attr_name}']").innerWidth() - ($("##{target}").innerWidth() - $("##{target}").width()))
|
256
270
|
|
257
271
|
# user chooses something and click
|
258
272
|
@action "select-#{attr_name}", 'click', (args...) =>
|
@@ -13,6 +13,9 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
13
13
|
@constructor.instances = [this]
|
14
14
|
Pinkman.objects.push(this)
|
15
15
|
|
16
|
+
@alias: (newFunc, existingFunc) ->
|
17
|
+
@prototype[newFunc] = @prototype[existingFunc]
|
18
|
+
|
16
19
|
@sync: (obj,callback,each) ->
|
17
20
|
if $p.isArray(@instances) and $p.isObject(obj) and obj.id?
|
18
21
|
length = @instances.length
|
@@ -23,10 +26,10 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
23
26
|
if obj.isPink then instance.assign(obj.attributes()) else instance.assign(obj)
|
24
27
|
each(instance) if $p.isFunction(each) and obj.pinkey != instance.pinkey
|
25
28
|
callback() if (length == i) and $p.isFunction(callback)
|
26
|
-
|
27
29
|
else
|
28
30
|
true
|
29
|
-
|
31
|
+
|
32
|
+
|
30
33
|
# Desc: assign attributes from a pure javascript object
|
31
34
|
# Usage: a.assign( {attribute: value} )
|
32
35
|
assign: (obj) ->
|
@@ -42,7 +45,7 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
42
45
|
|
43
46
|
# Desc: returns a javascript object version of this
|
44
47
|
# Usage: a.attributes() #-> {key: value, key: value, ...}
|
45
|
-
attributes:
|
48
|
+
attributes: ->
|
46
49
|
a = new Object
|
47
50
|
for k,v of this
|
48
51
|
if PinkmanObject.privateAttributes.indexOf(k) == -1 and typeof v != 'function'
|
@@ -54,16 +57,22 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
54
57
|
|
55
58
|
# Desc: json version of this
|
56
59
|
# desc: used in api comunications
|
57
|
-
json:
|
60
|
+
json: ->
|
61
|
+
(@pack(toBePacked) for toBePacked in @_pack_list) if $p.isArray(@_pack_list)
|
58
62
|
a = new Object
|
59
63
|
for k,v of this
|
60
|
-
if PinkmanObject.privateAttributes.indexOf(k) == -1 and
|
61
|
-
if (v? and typeof v == 'object' and v.isPink)
|
62
|
-
# do not include collections in json format since they are supposed to have their own model/api
|
63
|
-
a[k] = v.json() unless v.isCollection
|
64
|
-
else
|
65
|
-
a[k] = v
|
64
|
+
a[k] = v if PinkmanObject.privateAttributes.indexOf(k) == -1 and not $p.isFunction(v) and not $p.isObject(v)
|
66
65
|
return a
|
66
|
+
|
67
|
+
# Desc: prepare for rails accept nested attributes
|
68
|
+
pack: (attr) ->
|
69
|
+
@_pack_list = [] unless @_pack_list?
|
70
|
+
@_pack_list.push(attr) if @_pack_list.indexOf(attr) == -1
|
71
|
+
if $p.isPink(this[attr])
|
72
|
+
pack = this[attr]
|
73
|
+
attrs = pack.json()
|
74
|
+
@set("#{attr}_attributes[#{k}]", v) for k,v of attrs
|
75
|
+
attrs
|
67
76
|
|
68
77
|
# Desc: returns a array of attributes keys
|
69
78
|
# Usage:
|
@@ -73,7 +82,7 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
73
82
|
Object.keys(@attributes())
|
74
83
|
|
75
84
|
# Desc: Alias for attributesKeys
|
76
|
-
keys:
|
85
|
+
keys: ->
|
77
86
|
@attributesKeys()
|
78
87
|
|
79
88
|
extract: (args...) ->
|
@@ -82,7 +91,7 @@ class window.PinkmanObject extends window.PinkmanCommon
|
|
82
91
|
return(a)
|
83
92
|
|
84
93
|
|
85
|
-
toString:
|
94
|
+
toString: ->
|
86
95
|
array = []
|
87
96
|
array.push("(#{@className()})")
|
88
97
|
for a in @attributesKeys()
|
@@ -14,6 +14,9 @@ class window.Pinkman
|
|
14
14
|
|
15
15
|
# --- predicate
|
16
16
|
|
17
|
+
@isPink: (obj) ->
|
18
|
+
@isObject(obj) && obj.isPink
|
19
|
+
|
17
20
|
@isNumber: (n) ->
|
18
21
|
!isNaN(parseFloat(n)) && isFinite(n)
|
19
22
|
|
@@ -38,8 +41,25 @@ class window.Pinkman
|
|
38
41
|
@sleep = (s,callback) ->
|
39
42
|
ms = s*1000
|
40
43
|
window['_sleeping'] = setTimeout(callback,ms)
|
41
|
-
|
42
|
-
|
44
|
+
|
45
|
+
|
46
|
+
@mergeObjects: (a, b) ->
|
47
|
+
if a? and @isObject(a)
|
48
|
+
clone = @dup(a)
|
49
|
+
else
|
50
|
+
clone = new Object
|
51
|
+
if b? and @isObject(b)
|
52
|
+
for k,v of b
|
53
|
+
clone[k] = v
|
54
|
+
return(clone)
|
55
|
+
|
56
|
+
@dup: (a) ->
|
57
|
+
if @isFunction(Object.assign)
|
58
|
+
if @isObject(a) then Object.assign({}, a) else throw("Pinkman Error: can't dup #{a.toString()}. It is not an object.")
|
59
|
+
else
|
60
|
+
if @isObject(a) then jQuery.extend({}, a) else throw("Pinkman Error: can't dup #{a.toString()}. It is not an object.")
|
61
|
+
|
62
|
+
|
43
63
|
# --- tools and facilities
|
44
64
|
|
45
65
|
@top: ->
|
@@ -100,6 +120,12 @@ class window.Pinkman
|
|
100
120
|
else
|
101
121
|
''
|
102
122
|
|
123
|
+
@padNum: (number, size=2) ->
|
124
|
+
output = number.toString()
|
125
|
+
output = '0' + output while (output.length < size)
|
126
|
+
output
|
127
|
+
|
128
|
+
|
103
129
|
@objToArray: (obj) ->
|
104
130
|
i = 0
|
105
131
|
a = []
|
@@ -123,6 +149,28 @@ class window.Pinkman
|
|
123
149
|
|
124
150
|
@calledFunctions = []
|
125
151
|
|
152
|
+
|
153
|
+
@each: (array, exec, callback) ->
|
154
|
+
if @isArray(array) and @isFunction(exec)
|
155
|
+
l = array.length
|
156
|
+
i = 0
|
157
|
+
for item in array
|
158
|
+
exec(item)
|
159
|
+
i++
|
160
|
+
callback(array) if i == l and @isFunction(callback)
|
161
|
+
|
162
|
+
else
|
163
|
+
throw "Pinkman.each: wrong args: expect a array, apply function and a callback function. Got #{arguments}."
|
164
|
+
|
165
|
+
@map: (array, exec, callback) ->
|
166
|
+
if @isArray(array) and @isFunction(exec)
|
167
|
+
outputArray = []
|
168
|
+
@each array, (item) =>
|
169
|
+
outputArray.push(exec(item))
|
170
|
+
, =>
|
171
|
+
callback(outputArray) if @isFunction(callback)
|
172
|
+
return(outputArray)
|
173
|
+
|
126
174
|
# --- Scope
|
127
175
|
|
128
176
|
@scope: (obj) ->
|
@@ -80,7 +80,12 @@ Pinkman.template_engines =
|
|
80
80
|
partialAdapter: (templateBody) ->
|
81
81
|
if templateBody? and templateBody != ''
|
82
82
|
partialRegex = /{{(?:\s)*partial\((?:\s)*((?:\w|-)*)(?:\s)*\)(?:\s)*}}/gm
|
83
|
-
|
83
|
+
i = 0
|
84
|
+
while partialRegex.test(templateBody)
|
85
|
+
# i++
|
86
|
+
# console.log("partial-inception level: #{i}")
|
87
|
+
templateBody = templateBody.replace(partialRegex, @partialInception)
|
88
|
+
return(templateBody)
|
84
89
|
else
|
85
90
|
''
|
86
91
|
|
@@ -92,7 +97,7 @@ Pinkman.template_engines =
|
|
92
97
|
if p.length
|
93
98
|
p.html()
|
94
99
|
else
|
95
|
-
|
100
|
+
throw "Pinkman: Partial Error - Could not find partial named #{id}."
|
96
101
|
|
97
102
|
context: (options) ->
|
98
103
|
options.object = options.context if options.context?
|
@@ -110,10 +115,28 @@ Pinkman.template_engines =
|
|
110
115
|
$('#' + options.target).html(content)
|
111
116
|
$('#' + options.target).attr('data-pinkey',options.object.pinkey) if options.object? and typeof options.object == 'object' and options.object.isPink
|
112
117
|
|
113
|
-
# checks and sync select options with the pinkman object
|
118
|
+
# checks and sync select, checkboxes and radiobuttons options with the pinkman object
|
119
|
+
# select
|
114
120
|
$("##{options.target} select").each (i,el) ->
|
115
121
|
obj = Pinkman.get($(el).data('pinkey'))
|
116
122
|
$(el).find("option[value='#{obj[$(el).attr('name')]}']").attr('selected','selected')
|
123
|
+
|
124
|
+
# checkboxes and radios
|
125
|
+
$("##{options.target} input[type='checkbox'], ##{options.target} input[type='radio']").each (i,el) ->
|
126
|
+
obj = Pinkman.get($(el).data('pinkey'))
|
127
|
+
$el = $(el)
|
128
|
+
attr = $el.attr('name')
|
129
|
+
value = $el.attr('value')
|
130
|
+
# console.log attr
|
131
|
+
# console.log value.toString()
|
132
|
+
# console.log obj[attr].toString()
|
133
|
+
|
134
|
+
if attr? and value? and obj? and obj[attr]? and obj[attr] and obj[attr].toString() == value.toString()
|
135
|
+
$el.attr('checked', yes)
|
136
|
+
else
|
137
|
+
$el.attr('checked', no)
|
138
|
+
|
139
|
+
|
117
140
|
|
118
141
|
render: (options) ->
|
119
142
|
|