chr 0.1.5 → 0.2.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/Gruntfile.coffee +6 -3
- data/LICENSE.md +1 -1
- data/README.md +286 -7
- data/app/assets/javascripts/chr-dist.js +1031 -580
- data/app/assets/javascripts/chr.coffee +7 -4
- data/app/assets/javascripts/chr/core/chr.coffee +88 -37
- data/app/assets/javascripts/chr/core/item.coffee +57 -35
- data/app/assets/javascripts/chr/core/{list-scroll.coffee → list-pagination.coffee} +6 -3
- data/app/assets/javascripts/chr/core/list-reorder.coffee +3 -3
- data/app/assets/javascripts/chr/core/list-search.coffee +20 -11
- data/app/assets/javascripts/chr/core/list.coffee +163 -89
- data/app/assets/javascripts/chr/core/module.coffee +75 -35
- data/app/assets/javascripts/chr/core/view.coffee +117 -61
- data/app/assets/javascripts/chr/store/{store.coffee → _array-store.coffee} +53 -106
- data/app/assets/javascripts/chr/store/_object-store.coffee +28 -0
- data/app/assets/javascripts/chr/store/mongosteen-array-store.coffee +199 -0
- data/app/assets/javascripts/chr/store/mongosteen-object-store.coffee +52 -0
- data/app/assets/javascripts/chr/store/rest-array-store.coffee +142 -0
- data/app/assets/javascripts/chr/store/rest-object-store.coffee +79 -0
- data/app/assets/stylesheets/core/_list.scss +20 -25
- data/app/assets/stylesheets/core/_main.scss +3 -4
- data/app/assets/stylesheets/core/_mixins.scss +33 -2
- data/app/assets/stylesheets/core/_responsive.scss +30 -9
- data/app/assets/stylesheets/form/_input_checkbox.scss +18 -14
- data/bower.json +3 -2
- data/chr.gemspec +1 -1
- data/docs/assets.md +0 -0
- data/docs/basics.md +0 -0
- data/docs/bootstrap-data.md +0 -0
- data/docs/custom-inputs.md +0 -0
- data/docs/form.md +0 -0
- data/docs/internals.md +0 -0
- data/docs/nested-forms.md +0 -0
- data/docs/redactor-js.md +0 -0
- data/docs/scopes.md +0 -0
- data/lib/chr/version.rb +1 -1
- data/package.json +1 -1
- metadata +19 -7
- data/app/assets/javascripts/chr/store/store-mongosteen.coffee +0 -111
- data/app/assets/javascripts/chr/store/store-rest.coffee +0 -90
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Author: Alexander Kravets <alex@slatestudio.com>,
|
|
3
|
+
# Slate Studio (http://www.slatestudio.com)
|
|
4
|
+
#
|
|
5
|
+
# Coding Guide:
|
|
6
|
+
# https://github.com/thoughtbot/guides/tree/master/style/coffeescript
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# OBJECT STORE
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
class @ObjectStore
|
|
13
|
+
constructor: (@config={}) ->
|
|
14
|
+
@_initialize_database()
|
|
15
|
+
|
|
16
|
+
_initialize_database: ->
|
|
17
|
+
@_data = @config.data
|
|
18
|
+
|
|
19
|
+
loadObject: ->
|
|
20
|
+
@_data
|
|
21
|
+
|
|
22
|
+
update: (id, value, callback) ->
|
|
23
|
+
$.extend(@_data, value)
|
|
24
|
+
callback?(@_data)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Author: Alexander Kravets <alex@slatestudio.com>,
|
|
3
|
+
# Slate Studio (http://www.slatestudio.com)
|
|
4
|
+
#
|
|
5
|
+
# Coding Guide:
|
|
6
|
+
# https://github.com/thoughtbot/guides/tree/master/style/coffeescript
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# MONGOSTEEN (RAILS) ARRAY/COLLECTION STORE IMPLEMENTATION
|
|
11
|
+
# this store implementation talks to Mongosteen powered Rails api, supports
|
|
12
|
+
# features:
|
|
13
|
+
#
|
|
14
|
+
# - pagination
|
|
15
|
+
# `sortBy` & `sortReverse` options should be set same as on
|
|
16
|
+
# backend model with `default_scope` method (default), e.g:
|
|
17
|
+
# - frontend: `{ sortBy: 'created_at', sortReverse: true }`
|
|
18
|
+
# - backend: `default_scope -> { desc(:created_at) }`
|
|
19
|
+
#
|
|
20
|
+
# - search
|
|
21
|
+
# backend model configuration required, e.g: `search_in :title`
|
|
22
|
+
#
|
|
23
|
+
# configuration options:
|
|
24
|
+
# @config.pagination - enable pagination, default `true`
|
|
25
|
+
# @config.searchable - enable search, default `false`
|
|
26
|
+
#
|
|
27
|
+
# -----------------------------------------------------------------------------
|
|
28
|
+
class @MongosteenArrayStore extends RestArrayStore
|
|
29
|
+
# initial store configuration
|
|
30
|
+
_initialize_database: ->
|
|
31
|
+
@dataFetchLock = false
|
|
32
|
+
@ajaxConfig =
|
|
33
|
+
processData: false
|
|
34
|
+
contentType: false
|
|
35
|
+
|
|
36
|
+
@searchable = @config.searchable ? false
|
|
37
|
+
@searchQuery = ''
|
|
38
|
+
|
|
39
|
+
@pagination = @config.pagination ? true
|
|
40
|
+
@nextPage = 1
|
|
41
|
+
@objectsPerPage = _itemsPerPageRequest ? 20
|
|
42
|
+
|
|
43
|
+
if @pagination
|
|
44
|
+
@_bind_pagination_sync()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ---------------------------------------------------------
|
|
48
|
+
# workarounds to have consistency between arrayStore and
|
|
49
|
+
# database while loading next page
|
|
50
|
+
# ---------------------------------------------------------
|
|
51
|
+
_bind_pagination_sync: ->
|
|
52
|
+
@lastPageLoaded = false
|
|
53
|
+
|
|
54
|
+
# when object's added to the end of the list & not on the last page,
|
|
55
|
+
# we don't know it's position on the backend, so remove it from store
|
|
56
|
+
$(this).on 'object_added', (e, data) =>
|
|
57
|
+
if ! @lastPageLoaded
|
|
58
|
+
new_object = data.object
|
|
59
|
+
new_object_position = data.position
|
|
60
|
+
|
|
61
|
+
# check if object added to the end of the list
|
|
62
|
+
if new_object_position >= @objectsNumberForLoadedPages
|
|
63
|
+
e.stopImmediatePropagation()
|
|
64
|
+
|
|
65
|
+
@_remove_data_object(new_object._id)
|
|
66
|
+
|
|
67
|
+
# when object's added to the end of the list & not on the last page,
|
|
68
|
+
# we don't know it's position on the backend, so remove it from store
|
|
69
|
+
$(this).on 'object_changed', (e, data) =>
|
|
70
|
+
if ! @lastPageLoaded
|
|
71
|
+
new_object = data.object
|
|
72
|
+
new_object_position = data.position
|
|
73
|
+
|
|
74
|
+
# check if object added to the end of the list
|
|
75
|
+
if new_object_position >= @objectsNumberForLoadedPages - 1
|
|
76
|
+
e.stopImmediatePropagation()
|
|
77
|
+
|
|
78
|
+
@_remove_data_object(new_object._id)
|
|
79
|
+
|
|
80
|
+
# load current page again after item delete to sync, last item on the page
|
|
81
|
+
$(this).on 'object_removed', (e, data) =>
|
|
82
|
+
if ! @lastPageLoaded
|
|
83
|
+
@_reload_current_page()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
_reload_current_page: ->
|
|
87
|
+
@nextPage -= 1 ; @load()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
_udpate_next_page: (data) ->
|
|
91
|
+
if @pagination
|
|
92
|
+
if data.length > 0
|
|
93
|
+
@lastPageLoaded = true
|
|
94
|
+
|
|
95
|
+
if data.length == @objectsPerPage
|
|
96
|
+
@nextPage += 1
|
|
97
|
+
@lastPageLoaded = false
|
|
98
|
+
|
|
99
|
+
else
|
|
100
|
+
@lastPageLoaded = true
|
|
101
|
+
|
|
102
|
+
@objectsNumberForLoadedPages = (@nextPage - 1) * @objectsPerPage
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# generate resource api url
|
|
106
|
+
_resource_url: (type, id) ->
|
|
107
|
+
objectPath = if id then "/#{ id }" else ''
|
|
108
|
+
url = "#{ @config.path }#{ objectPath }.json"
|
|
109
|
+
|
|
110
|
+
if @config.urlParams
|
|
111
|
+
extraParamsString = $.param(@config.urlParams)
|
|
112
|
+
url = "#{ url }?#{ extraParamsString }"
|
|
113
|
+
|
|
114
|
+
return url
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# get form data object from serialized form object,
|
|
118
|
+
# it uses special format for object names for support of:
|
|
119
|
+
# files, lists, nested objects
|
|
120
|
+
_parse_form_object: (serializedFormObject) ->
|
|
121
|
+
formDataObject = new FormData()
|
|
122
|
+
|
|
123
|
+
for attr_name, attr_value of serializedFormObject
|
|
124
|
+
|
|
125
|
+
# special case for LIST inputs, values separated with comma
|
|
126
|
+
if attr_name.indexOf('[__LIST__') > -1
|
|
127
|
+
attr_name = attr_name.replace('__LIST__', '')
|
|
128
|
+
values = attr_value.split(',')
|
|
129
|
+
|
|
130
|
+
for value in values
|
|
131
|
+
formDataObject.append("#{ @config.resource }#{ attr_name }[]", value)
|
|
132
|
+
|
|
133
|
+
else
|
|
134
|
+
# special case for FILE inputs
|
|
135
|
+
if attr_name.startsWith('__FILE__')
|
|
136
|
+
attr_name = attr_name.replace('__FILE__', '')
|
|
137
|
+
|
|
138
|
+
formDataObject.append("#{ @config.resource }#{ attr_name }", attr_value)
|
|
139
|
+
|
|
140
|
+
return formDataObject
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# load results for search query
|
|
144
|
+
search: (@searchQuery) ->
|
|
145
|
+
@nextPage = 1
|
|
146
|
+
@_reset_data()
|
|
147
|
+
@load()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# load next page objects from database, when finished
|
|
151
|
+
# trigger 'objects_added' event
|
|
152
|
+
load: (callbacks={}) ->
|
|
153
|
+
callbacks.onSuccess ?= $.noop
|
|
154
|
+
callbacks.onError ?= $.noop
|
|
155
|
+
|
|
156
|
+
params = {}
|
|
157
|
+
|
|
158
|
+
if @pagination
|
|
159
|
+
params.page = @nextPage
|
|
160
|
+
params.perPage = @objectsPerPage
|
|
161
|
+
|
|
162
|
+
if @searchable && @searchQuery.length > 0
|
|
163
|
+
params.search = @searchQuery
|
|
164
|
+
|
|
165
|
+
params = $.param(params)
|
|
166
|
+
|
|
167
|
+
@_ajax 'GET', null, params, ((data) =>
|
|
168
|
+
@_udpate_next_page(data)
|
|
169
|
+
@_add_data_object(o) for o in data
|
|
170
|
+
|
|
171
|
+
callbacks.onSuccess(data)
|
|
172
|
+
|
|
173
|
+
$(this).trigger('objects_added', { objects: data })
|
|
174
|
+
), callbacks.onError
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# reset data and load first page
|
|
178
|
+
reset: ->
|
|
179
|
+
@searchQuery = ''
|
|
180
|
+
@nextPage = 1
|
|
181
|
+
params = {}
|
|
182
|
+
|
|
183
|
+
if @pagination
|
|
184
|
+
@lastPageLoaded = false
|
|
185
|
+
params.page = @nextPage
|
|
186
|
+
params.perPage = @objectsPerPage
|
|
187
|
+
|
|
188
|
+
params = $.param(params)
|
|
189
|
+
|
|
190
|
+
@_ajax 'GET', null, params, ((data) =>
|
|
191
|
+
@_udpate_next_page(data)
|
|
192
|
+
@_sync_with_data_objects(data)
|
|
193
|
+
|
|
194
|
+
$(this).trigger('objects_added', { objects: data })
|
|
195
|
+
), -> chr.showError('Error while loading data.')
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Author: Alexander Kravets <alex@slatestudio.com>,
|
|
3
|
+
# Slate Studio (http://www.slatestudio.com)
|
|
4
|
+
#
|
|
5
|
+
# Coding Guide:
|
|
6
|
+
# https://github.com/thoughtbot/guides/tree/master/style/coffeescript
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# MONGOSTEEN (RAILS) OBJECT STORE IMPLEMENTATION
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
class @MongosteenObjectStore extends RestObjectStore
|
|
13
|
+
# initial store configuration
|
|
14
|
+
_initialize_database: ->
|
|
15
|
+
@dataFetchLock = false
|
|
16
|
+
@ajaxConfig =
|
|
17
|
+
processData: false
|
|
18
|
+
contentType: false
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# generate rest url for resource
|
|
22
|
+
_resource_url: -> "#{ @config.path }.json"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# get form data object from serialized form object,
|
|
26
|
+
# it uses special format for object names for support of:
|
|
27
|
+
# files, lists, nested objects
|
|
28
|
+
_parse_form_object: (serializedFormObject) ->
|
|
29
|
+
formDataObject = new FormData()
|
|
30
|
+
|
|
31
|
+
for attr_name, attr_value of serializedFormObject
|
|
32
|
+
|
|
33
|
+
# special case for LIST inputs, values separated with comma
|
|
34
|
+
if attr_name.indexOf('[__LIST__') > -1
|
|
35
|
+
attr_name = attr_name.replace('__LIST__', '')
|
|
36
|
+
values = attr_value.split(',')
|
|
37
|
+
|
|
38
|
+
for value in values
|
|
39
|
+
formDataObject.append("#{ @config.resource }#{ attr_name }[]", value)
|
|
40
|
+
|
|
41
|
+
else
|
|
42
|
+
# special case for FILE inputs
|
|
43
|
+
if attr_name.startsWith('__FILE__')
|
|
44
|
+
attr_name = attr_name.replace('__FILE__', '')
|
|
45
|
+
|
|
46
|
+
formDataObject.append("#{ @config.resource }#{ attr_name }", attr_value)
|
|
47
|
+
|
|
48
|
+
return formDataObject
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Author: Alexander Kravets <alex@slatestudio.com>,
|
|
3
|
+
# Slate Studio (http://www.slatestudio.com)
|
|
4
|
+
#
|
|
5
|
+
# Coding Guide:
|
|
6
|
+
# https://github.com/thoughtbot/guides/tree/master/style/coffeescript
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# REST ARRAY STORE
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
class @RestArrayStore extends ArrayStore
|
|
13
|
+
# initial store configuration
|
|
14
|
+
_initialize_database: ->
|
|
15
|
+
@dataFetchLock = false
|
|
16
|
+
@ajaxConfig = {}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# generate rest url for resource
|
|
20
|
+
_resource_url: (type, id) ->
|
|
21
|
+
objectPath = if id then "/#{ id }" else ''
|
|
22
|
+
"#{ @config.path }#{ objectPath }"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# do requests to database api
|
|
26
|
+
_ajax: (type, id, data, success, error) ->
|
|
27
|
+
options = $.extend @ajaxConfig,
|
|
28
|
+
url: @_resource_url(type, id)
|
|
29
|
+
type: type
|
|
30
|
+
data: data
|
|
31
|
+
success: (data, textStatus, jqXHR) =>
|
|
32
|
+
success?(data)
|
|
33
|
+
setTimeout ( => @dataFetchLock = false ), 350
|
|
34
|
+
#@dataFetchLock = false
|
|
35
|
+
error: (jqXHR, textStatus, errorThrown ) =>
|
|
36
|
+
error?(jqXHR.responseJSON)
|
|
37
|
+
@dataFetchLock = false
|
|
38
|
+
|
|
39
|
+
@dataFetchLock = true
|
|
40
|
+
$.ajax options
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# check how this works with sorting enabled
|
|
44
|
+
_sync_with_data_objects: (objects) ->
|
|
45
|
+
if objects.length == 0 then return @_reset_data()
|
|
46
|
+
if @_data.length == 0 then return ( @_add_data_object(o) for o in objects )
|
|
47
|
+
|
|
48
|
+
objectsMap = {}
|
|
49
|
+
(o = @_normalize_object_id(o) ; objectsMap[o._id] = o) for o in objects
|
|
50
|
+
|
|
51
|
+
objectIds = $.map objects, (o) -> o._id
|
|
52
|
+
dataObjectIds = $.map @_data, (o) -> o._id
|
|
53
|
+
|
|
54
|
+
addObjectIds = $(objectIds).not(dataObjectIds).get()
|
|
55
|
+
updateDataObjectIds = $(objectIds).not(addObjectIds).get()
|
|
56
|
+
removeDataObjectIds = $(dataObjectIds).not(objectIds).get()
|
|
57
|
+
|
|
58
|
+
for id in removeDataObjectIds
|
|
59
|
+
@_remove_data_object(id)
|
|
60
|
+
|
|
61
|
+
for id in addObjectIds
|
|
62
|
+
@_add_data_object(objectsMap[id])
|
|
63
|
+
|
|
64
|
+
for id in updateDataObjectIds
|
|
65
|
+
@_update_data_object(id, objectsMap[id])
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# load a single object, this is used in view when
|
|
69
|
+
# store has not required item
|
|
70
|
+
loadObject: (id, callbacks={}) ->
|
|
71
|
+
callbacks.onSuccess ?= $.noop
|
|
72
|
+
callbacks.onError ?= $.noop
|
|
73
|
+
|
|
74
|
+
@_ajax 'GET', id, {}, ((data) =>
|
|
75
|
+
callbacks.onSuccess(data)
|
|
76
|
+
), callbacks.onError
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# load objects from database, when finished
|
|
80
|
+
# trigger 'objects_added' event
|
|
81
|
+
load: (callbacks={}) ->
|
|
82
|
+
callbacks.onSuccess ?= $.noop
|
|
83
|
+
callbacks.onError ?= $.noop
|
|
84
|
+
|
|
85
|
+
@_ajax 'GET', null, {}, ((data) =>
|
|
86
|
+
if data.length > 0
|
|
87
|
+
for o in data
|
|
88
|
+
@_add_data_object(o)
|
|
89
|
+
|
|
90
|
+
callbacks.onSuccess(data)
|
|
91
|
+
|
|
92
|
+
$(this).trigger('objects_added', { objects: data })
|
|
93
|
+
) callbacks.onError
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# add new object
|
|
97
|
+
push: (serializedFormObject, callbacks={}) ->
|
|
98
|
+
callbacks.onSuccess ?= $.noop
|
|
99
|
+
callbacks.onError ?= $.noop
|
|
100
|
+
|
|
101
|
+
obj = @_parse_form_object(serializedFormObject)
|
|
102
|
+
|
|
103
|
+
@_ajax 'POST', null, obj, ((data) =>
|
|
104
|
+
@_add_data_object(data)
|
|
105
|
+
callbacks.onSuccess(data)
|
|
106
|
+
), callbacks.onError
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# update objects attributes
|
|
110
|
+
update: (id, serializedFormObject, callbacks={}) ->
|
|
111
|
+
callbacks.onSuccess ?= $.noop
|
|
112
|
+
callbacks.onError ?= $.noop
|
|
113
|
+
|
|
114
|
+
obj = @_parse_form_object(serializedFormObject)
|
|
115
|
+
|
|
116
|
+
@_ajax 'PUT', id, obj, ((data) =>
|
|
117
|
+
@_update_data_object(id, data)
|
|
118
|
+
callbacks.onSuccess(data)
|
|
119
|
+
), callbacks.onError
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# delete object
|
|
123
|
+
remove: (id, callbacks={}) ->
|
|
124
|
+
callbacks.onSuccess ?= $.noop
|
|
125
|
+
callbacks.onError ?= $.noop
|
|
126
|
+
|
|
127
|
+
@_ajax 'DELETE', id, {}, ( =>
|
|
128
|
+
@_remove_data_object(id)
|
|
129
|
+
callbacks.onSuccess()
|
|
130
|
+
), callbacks.onError
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# reset data and load it again
|
|
134
|
+
reset: ->
|
|
135
|
+
@_ajax 'GET', null, {}, ((data) =>
|
|
136
|
+
@_sync_with_data_objects(data)
|
|
137
|
+
$(this).trigger('objects_added', { objects: data })
|
|
138
|
+
), -> chr.showError('Error while loading data.')
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Author: Alexander Kravets <alex@slatestudio.com>,
|
|
3
|
+
# Slate Studio (http://www.slatestudio.com)
|
|
4
|
+
#
|
|
5
|
+
# Coding Guide:
|
|
6
|
+
# https://github.com/thoughtbot/guides/tree/master/style/coffeescript
|
|
7
|
+
# -----------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# REST OBJECT STORE
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
class @RestObjectStore extends ObjectStore
|
|
13
|
+
_initialize_database: ->
|
|
14
|
+
@dataFetchLock = false
|
|
15
|
+
@ajaxConfig = {}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# generate rest url for resource
|
|
19
|
+
_resource_url: -> @config.path
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# get regular javascript object from serialized form object,
|
|
23
|
+
# which uses special format for object names for support of:
|
|
24
|
+
# - files
|
|
25
|
+
# - lists
|
|
26
|
+
# - nested objects
|
|
27
|
+
_parse_form_object: (serializedFormObject) ->
|
|
28
|
+
# this is very basic and have to be expanded to support all form inputs:
|
|
29
|
+
# - lists, files, nested objects
|
|
30
|
+
object = {}
|
|
31
|
+
for key, value of serializedFormObject
|
|
32
|
+
fieldName = key.replace('[', '').replace(']', '')
|
|
33
|
+
object[fieldName] = value
|
|
34
|
+
return object
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# do requests to database api
|
|
38
|
+
_ajax: (type, data, success, error) ->
|
|
39
|
+
options = $.extend @ajaxConfig,
|
|
40
|
+
url: @_resource_url()
|
|
41
|
+
type: type
|
|
42
|
+
data: data
|
|
43
|
+
success: (data, textStatus, jqXHR) =>
|
|
44
|
+
success?(data)
|
|
45
|
+
@dataFetchLock = false
|
|
46
|
+
error: (jqXHR, textStatus, errorThrown ) =>
|
|
47
|
+
error?(jqXHR.responseJSON)
|
|
48
|
+
@dataFetchLock = false
|
|
49
|
+
|
|
50
|
+
@dataFetchLock = true
|
|
51
|
+
$.ajax options
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# load a single object, this is used in view when
|
|
55
|
+
# store has not required item
|
|
56
|
+
loadObject: (callbacks={}) ->
|
|
57
|
+
callbacks.onSuccess ?= $.noop
|
|
58
|
+
callbacks.onError ?= $.noop
|
|
59
|
+
|
|
60
|
+
@_ajax 'GET', {}, ((data) =>
|
|
61
|
+
callbacks.onSuccess(data)
|
|
62
|
+
), callbacks.onError
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# update objects attributes
|
|
66
|
+
update: (id, serializedFormObject, callbacks={}) ->
|
|
67
|
+
callbacks.onSuccess ?= $.noop
|
|
68
|
+
callbacks.onError ?= $.noop
|
|
69
|
+
|
|
70
|
+
obj = @_parse_form_object(serializedFormObject)
|
|
71
|
+
|
|
72
|
+
@_ajax 'PUT', obj, ((data) =>
|
|
73
|
+
@_data = data
|
|
74
|
+
callbacks.onSuccess(data)
|
|
75
|
+
), callbacks.onError
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|