smart_listing 0.9.1 → 0.9.2
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/LICENSE +1 -1
- data/README.md +4 -0
- data/app/assets/javascripts/smart_listing/smart_listing.coffee +247 -247
- data/app/helpers/smart_listing/application_helper.rb +3 -3
- data/app/helpers/smart_listing/helper.rb +257 -257
- data/lib/smart_listing.rb +117 -112
- data/lib/smart_listing/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aec78db2f43e9f78c7420c7a21efdd506da3dbe6
|
4
|
+
data.tar.gz: 8297a520f5c771c428aa2dddbb3219e1696a5e0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 542635bdcc49d20e137793ee6e54dc46731c271fedd49d053b5e27c642b362e664b06ffc7f7d65774177f1efa63db6d85252481b9d7c9ad05275f775770393dc
|
7
|
+
data.tar.gz: fa82edc043dc01ac02e53b6d1a8a28388be34ca1e67a4b89061473cd60f5fef975c447679a02cbb479df0e95ced1093f28f41014f0e9666b5fb139fdd6550b6b
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,3 +2,7 @@ SmartListing
|
|
2
2
|
==========
|
3
3
|
|
4
4
|
SmartListing helps creating sortable lists of ActiveRecord collections with pagination, filtering and inline editing.
|
5
|
+
|
6
|
+
Created by Sology http://www.sology.eu
|
7
|
+
|
8
|
+
Initial development sponsored by Smart Language Apps Limited http://smartlanguageapps.com/
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Useful when smart list target url is different than current one
|
2
2
|
$.rails.href = (element) ->
|
3
|
-
|
3
|
+
element.attr('href') || element.data('href')
|
4
4
|
|
5
5
|
$.fn.observeField = (opts = {}) ->
|
6
6
|
field = $(this)
|
@@ -35,280 +35,280 @@ $.fn.observeField = (opts = {}) ->
|
|
35
35
|
, 400)
|
36
36
|
|
37
37
|
class SmartListing
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
38
|
+
constructor: (e) ->
|
39
|
+
@container = e
|
40
|
+
@name = @container.attr('id')
|
41
|
+
@loading = @container.find('.loading')
|
42
|
+
@content = @container.find('.content')
|
43
|
+
@status = $(".smart_listing_status[data-smart-listing='#{@name}']")
|
44
|
+
@confirmed = null
|
45
|
+
|
46
|
+
createPopover = (confirmation_elem, msg) =>
|
47
|
+
deletion_popover = $('<div/>').addClass('confirmation_box')
|
48
|
+
deletion_popover.append($('<p/>').html(msg))
|
49
|
+
deletion_popover.append($('<p/>')
|
50
|
+
.append($('<button/>').html('Yes').addClass('btn btn-danger ').click (event) =>
|
51
|
+
# set @confirmed element and emulate click on icon
|
52
|
+
editable = $(event.currentTarget).closest('.editable')
|
53
|
+
@confirmed = confirmation_elem
|
54
|
+
$(confirmation_elem).click()
|
55
|
+
$(confirmation_elem).popover('destroy')
|
56
|
+
)
|
57
|
+
.append($('<button/>').html('No').addClass('btn btn-small').click (event) =>
|
58
|
+
editable = $(event.currentTarget).closest('.editable')
|
59
|
+
$(confirmation_elem).popover('destroy')
|
60
|
+
)
|
61
|
+
)
|
62
|
+
|
63
|
+
@container.on 'ajax:before', (e) =>
|
64
|
+
@fadeLoading()
|
65
|
+
|
66
|
+
@container.on 'ajax:success', (e) =>
|
67
|
+
if $(e.target).is('.actions a.destroy')
|
68
|
+
# handle HEAD OK response for deletion request
|
69
|
+
editable = $(e.target).closest('.editable')
|
70
|
+
if @container.find(".editable").length == 1
|
71
|
+
@reload()
|
72
|
+
return false
|
73
|
+
else
|
74
|
+
editable.remove()
|
75
|
+
|
76
|
+
@changeItemCount(-1)
|
77
|
+
@refresh()
|
78
|
+
|
79
|
+
@fadeLoaded()
|
80
|
+
return false
|
81
|
+
|
82
|
+
@container.on 'click', 'button.cancel', (event) =>
|
83
|
+
editable = $(event.currentTarget).closest('.editable')
|
84
|
+
if(editable.length > 0)
|
85
|
+
# Cancel edit
|
86
|
+
@cancelEdit(editable)
|
87
|
+
else
|
88
|
+
# Cancel new record
|
89
|
+
@container.find('.new_item_placeholder').addClass('disabled')
|
90
|
+
@container.find('.new_item_action').removeClass('disabled')
|
91
|
+
false
|
92
|
+
|
93
|
+
@container.on 'click', '.actions a[data-confirmation]', (event) =>
|
94
|
+
# Check if we are confirming the right element
|
95
|
+
if(@confirmed != event.currentTarget)
|
96
|
+
# We need confirmation
|
97
|
+
@container.find('.actions a').popover('destroy')
|
98
|
+
$(event.currentTarget).popover(content: createPopover(event.currentTarget, $(event.currentTarget).data('confirmation')), html: true, trigger: 'manual')
|
99
|
+
$(event.currentTarget).popover('show')
|
100
|
+
false
|
101
|
+
else
|
102
|
+
# Confirmed, reset flag and go ahead with deletion
|
103
|
+
@confirmed = null
|
104
|
+
true
|
105
|
+
|
106
|
+
@container.on 'click', 'input[type=text].autoselect', (event) ->
|
107
|
+
$(this).select()
|
108
|
+
|
109
|
+
fadeLoading: =>
|
110
|
+
@content.stop(true).fadeTo(500, 0.2)
|
111
|
+
@loading.show()
|
112
|
+
@loading.stop(true).fadeTo(500, 1)
|
113
|
+
|
114
|
+
fadeLoaded: =>
|
115
|
+
@content.stop(true).fadeTo(500, 1)
|
116
|
+
@loading.stop(true).fadeTo 500, 0, () =>
|
117
|
+
@loading.hide()
|
118
|
+
|
119
|
+
@content.find('.play').each () ->
|
120
|
+
self.loadAudio($(this).data('key'), $(this).data('target'))
|
121
|
+
|
122
|
+
itemCount: =>
|
123
|
+
parseInt(@container.find('.pagination_per_page .count').html())
|
124
|
+
|
125
|
+
maxCount: =>
|
126
|
+
parseInt(@container.data('max-count'))
|
127
|
+
|
128
|
+
changeItemCount: (value) =>
|
129
|
+
@container.find('.pagination_per_page .count').html(@itemCount() + value)
|
130
|
+
|
131
|
+
cancelEdit: (editable) =>
|
132
|
+
if editable.data('smart_listing_edit_backup')
|
133
|
+
editable.html(editable.data('smart_listing_edit_backup'))
|
134
|
+
editable.removeClass('info')
|
135
|
+
editable.removeData('smart_listing_edit_backup')
|
136
|
+
|
137
|
+
# Callback called when record is added/deleted using ajax request
|
138
|
+
refresh: () =>
|
139
|
+
header = @content.find('thead')
|
140
|
+
footer = @content.find('.pagination_per_page')
|
141
|
+
no_records = @content.find('.no_records')
|
142
|
+
|
143
|
+
if @itemCount() == 0
|
144
|
+
header.hide()
|
145
|
+
footer.hide()
|
146
|
+
no_records.show()
|
147
|
+
else
|
148
|
+
header.show()
|
149
|
+
footer.show()
|
150
|
+
no_records.hide()
|
151
|
+
|
152
|
+
if @maxCount()
|
153
|
+
if @itemCount() >= @maxCount()
|
154
|
+
if @itemCount()
|
155
|
+
@container.find('.new_item_action').addClass('disabled')
|
156
|
+
@container.find('.new_item_action .btn').addClass('disabled')
|
157
|
+
else
|
158
|
+
@container.find('.new_item_action').removeClass('disabled')
|
159
|
+
@container.find('.new_item_action .btn').removeClass('disabled')
|
160
|
+
|
161
|
+
@status.each (index, status) =>
|
162
|
+
$(status).find('.smart_listing_limit').html(@maxCount() - @itemCount())
|
163
|
+
if @maxCount() - @itemCount() == 0
|
164
|
+
$(status).find('.smart_listing_limit_alert').show()
|
165
|
+
else
|
166
|
+
$(status).find('.smart_listing_limit_alert').hide()
|
167
|
+
|
168
|
+
# Trigger AJAX request to reload the list
|
169
|
+
reload: () =>
|
170
|
+
$.rails.handleRemote(@container)
|
171
|
+
|
172
|
+
params: () =>
|
173
|
+
@container.data('params')
|
174
|
+
|
175
175
|
#################################################################################################
|
176
|
-
|
176
|
+
# Methods executed by rails UJS:
|
177
177
|
|
178
|
-
|
179
|
-
|
180
|
-
|
178
|
+
new_item: (content) =>
|
179
|
+
new_item_action = @container.find('.new_item_action')
|
180
|
+
new_item_placeholder = @container.find('.new_item_placeholder').addClass('disabled')
|
181
181
|
|
182
|
-
|
183
|
-
|
182
|
+
@container.find('.editable').each (i, v) =>
|
183
|
+
@cancelEdit($(v))
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
185
|
+
new_item_action.addClass('disabled')
|
186
|
+
new_item_placeholder.removeClass('disabled')
|
187
|
+
new_item_placeholder.html(content)
|
188
|
+
new_item_placeholder.addClass('info')
|
189
189
|
|
190
|
-
|
190
|
+
@fadeLoaded()
|
191
191
|
|
192
|
-
|
193
|
-
|
194
|
-
|
192
|
+
create: (id, success, content) =>
|
193
|
+
new_item_action = @container.find('.new_item_action')
|
194
|
+
new_item_placeholder = @container.find('.new_item_placeholder')
|
195
195
|
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
if success
|
197
|
+
new_item_placeholder.addClass('disabled')
|
198
|
+
new_item_action.removeClass('disabled')
|
199
199
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
200
|
+
new_item = $('<tr />').addClass('editable')
|
201
|
+
new_item.attr('data-id', id)
|
202
|
+
new_item.html(content)
|
203
|
+
new_item_placeholder.before(new_item)
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
205
|
+
@changeItemCount(1)
|
206
|
+
@refresh()
|
207
|
+
else
|
208
|
+
new_item_placeholder.html(content)
|
209
209
|
|
210
|
-
|
210
|
+
@fadeLoaded()
|
211
211
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
212
|
+
edit: (id, content) =>
|
213
|
+
@container.find('.editable').each (i, v) =>
|
214
|
+
@cancelEdit($(v))
|
215
|
+
@container.find('.new_item_placeholder').addClass('disabled')
|
216
|
+
@container.find('.new_item_action').removeClass('disabled')
|
217
217
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
218
|
+
editable = @container.find(".editable[data-id=#{id}]")
|
219
|
+
editable.data('smart_listing_edit_backup', editable.html())
|
220
|
+
editable.html(content)
|
221
|
+
editable.addClass('info')
|
222
222
|
|
223
|
-
|
223
|
+
@fadeLoaded()
|
224
224
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
225
|
+
update: (id, success, content) =>
|
226
|
+
editable = @container.find(".editable[data-id=#{id}]")
|
227
|
+
if success
|
228
|
+
editable.removeClass('info')
|
229
|
+
editable.removeData('smart_listing_edit_backup')
|
230
|
+
editable.html(content)
|
231
231
|
|
232
|
-
|
233
|
-
|
234
|
-
|
232
|
+
@refresh()
|
233
|
+
else
|
234
|
+
editable.html(content)
|
235
235
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
236
|
+
@fadeLoaded()
|
237
|
+
|
238
|
+
destroy: (id, destroyed) =>
|
239
|
+
# No need to do anything here, already handled by ajax:success handler
|
240
|
+
|
241
|
+
update_list: (content, data) =>
|
242
|
+
$.each data, (key, value) =>
|
243
|
+
@container.data(key, value)
|
244
244
|
|
245
|
-
|
245
|
+
@content.html(content)
|
246
246
|
|
247
|
-
|
248
|
-
|
247
|
+
@refresh()
|
248
|
+
@fadeLoaded()
|
249
249
|
|
250
250
|
$.fn.smart_listing = () ->
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
251
|
+
map = $(this).map () ->
|
252
|
+
if !$(this).data('smart-listing')
|
253
|
+
$(this).data('smart-listing', new SmartListing($(this)))
|
254
|
+
$(this).data('smart-listing')
|
255
|
+
if map.length == 1
|
256
|
+
map[0]
|
257
|
+
else
|
258
|
+
map
|
259
259
|
|
260
260
|
$.fn.handleSmartListingControls = () ->
|
261
|
-
|
262
|
-
|
263
|
-
|
261
|
+
$(this).each () ->
|
262
|
+
controls = $(this)
|
263
|
+
smart_listing = $("##{controls.data('smart-listing')}")
|
264
264
|
|
265
|
-
|
266
|
-
|
267
|
-
|
265
|
+
controls.submit ->
|
266
|
+
# Merges smart list params with the form action url before submitting.
|
267
|
+
# This preserves smart list settings (page, sorting etc.).
|
268
268
|
|
269
|
-
|
270
|
-
|
271
|
-
|
269
|
+
prms = $.extend({}, smart_listing.smart_listing().params())
|
270
|
+
if $(this).data('reset')
|
271
|
+
prms[$(this).data('reset')] = null
|
272
272
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
273
|
+
if $.rails.href(smart_listing)
|
274
|
+
# If smart list has different target url than current one
|
275
|
+
controls.attr('action', $.rails.href(smart_listing) + "?" + jQuery.param(prms))
|
276
|
+
else
|
277
|
+
controls.attr('action', "?" + jQuery.param(prms))
|
278
278
|
|
279
|
-
|
280
|
-
|
279
|
+
smart_listing.trigger('ajax:before')
|
280
|
+
true
|
281
281
|
|
282
|
-
|
283
|
-
|
284
|
-
|
282
|
+
controls.find('input, select').change () ->
|
283
|
+
unless $(this).data('observed') # do not submit controls form when changed field is observed (observing submits form by itself)
|
284
|
+
controls.submit()
|
285
285
|
|
286
286
|
$.fn.handleSmartListingFilter = () ->
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
287
|
+
filter = $(this)
|
288
|
+
form = filter.closest('form')
|
289
|
+
button = filter.find('button')
|
290
|
+
icon = filter.find('i')
|
291
|
+
field = filter.find('input')
|
292
|
+
|
293
|
+
field.observeField(
|
294
|
+
onFilled: ->
|
295
|
+
icon.removeClass('icon-search')
|
296
|
+
icon.addClass('icon-remove')
|
297
|
+
button.removeClass('disabled')
|
298
|
+
onEmpty: ->
|
299
|
+
icon.addClass('icon-search')
|
300
|
+
icon.removeClass('icon-remove')
|
301
|
+
button.addClass('disabled')
|
302
|
+
onChange: ->
|
303
|
+
form.submit()
|
304
|
+
)
|
305
|
+
|
306
|
+
button.click ->
|
307
|
+
if field.val().length > 0
|
308
|
+
field.val('')
|
309
|
+
field.trigger('keydown')
|
310
310
|
|
311
311
|
$ ->
|
312
|
-
|
313
|
-
|
314
|
-
|
312
|
+
$('.smart_listing').smart_listing()
|
313
|
+
$('.smart_listing_controls').handleSmartListingControls()
|
314
|
+
$('.smart_listing_controls .filter').handleSmartListingFilter()
|