smart_listing 1.0.0 → 1.1.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 +31 -4
- data/Rakefile +1 -1
- data/app/assets/javascripts/smart_listing.coffee.erb +165 -123
- data/app/helpers/smart_listing/helper.rb +102 -45
- data/app/views/kaminari/smart_listing/_paginator.html.erb +2 -2
- data/app/views/smart_listing/_action_delete.html.erb +3 -2
- data/app/views/smart_listing/_action_edit.html.erb +4 -3
- data/app/views/smart_listing/_action_show.html.erb +4 -3
- data/app/views/smart_listing/_item_new.html.erb +2 -2
- data/app/views/smart_listing/_pagination_per_page_links.html.erb +1 -1
- data/app/views/smart_listing/_sortable.html.erb +2 -2
- data/app/views/smart_listing/create.js.erb +2 -0
- data/app/views/smart_listing/destroy.js.erb +1 -0
- data/app/views/smart_listing/edit.js.erb +1 -0
- data/app/views/smart_listing/index.js.erb +1 -0
- data/app/views/smart_listing/item/_destroy.js.erb +1 -1
- data/app/views/smart_listing/new.js.erb +1 -0
- data/app/views/smart_listing/update.js.erb +2 -0
- data/lib/generators/smart_listing/templates/initializer.rb +10 -1
- data/lib/smart_listing/config.rb +45 -22
- data/lib/smart_listing/version.rb +1 -1
- data/lib/smart_listing.rb +18 -15
- metadata +135 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59e85525d27d91f8ccf4ede3196a9d665e80e636
|
4
|
+
data.tar.gz: 2715e1395d0ea7eff77d9a531639b0917143212a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb5792e4ce2c755905e4ea7d07c9a5c5f50f1eca9a39f142b70ab94465e89989bc951494b310049cef91e2acac1fa82ab93eec08e399ba5ba6c6b10be2f9352b
|
7
|
+
data.tar.gz: a9caf551202a276d1c233afa7daa86c860a87d9a7d170836a471fa8a769a783cb7a5b809e4d9728d0d2d69d30066709b3c38a5e84787b4c154a0f3dc51fb5974
|
data/README.md
CHANGED
@@ -113,8 +113,8 @@ SmartListing supports two modes of sorting: implicit and explicit. Implicit mode
|
|
113
113
|
%table
|
114
114
|
%thead
|
115
115
|
%tr
|
116
|
-
%th= smart_listing.sortable "User name",
|
117
|
-
%th= smart_listing.sortable "Email",
|
116
|
+
%th= smart_listing.sortable "User name", :name
|
117
|
+
%th= smart_listing.sortable "Email", :email
|
118
118
|
%tbody
|
119
119
|
- smart_listing.collection.each do |user|
|
120
120
|
%tr
|
@@ -126,12 +126,12 @@ SmartListing supports two modes of sorting: implicit and explicit. Implicit mode
|
|
126
126
|
%p.warning No records!
|
127
127
|
```
|
128
128
|
|
129
|
-
In this case
|
129
|
+
In this case `:name` and `:email` are sorting column names. `Builder#sortable` renders special link containing column name and sort order (either `asc`, `desc`, or empty value).
|
130
130
|
|
131
131
|
You can also specify default sort order in the controller:
|
132
132
|
|
133
133
|
```ruby
|
134
|
-
@users = smart_listing_create(:users, User.active, partial: "users/listing", default_sort: {
|
134
|
+
@users = smart_listing_create(:users, User.active, partial: "users/listing", default_sort: {name: "asc"})
|
135
135
|
```
|
136
136
|
|
137
137
|
Implicit mode is convenient with simple data sets. In case you want to sort by joined column names, we advise you to use explicit sorting:
|
@@ -143,6 +143,8 @@ Implicit mode is convenient with simple data sets. In case you want to sort by j
|
|
143
143
|
|
144
144
|
Note that `:sort_attributes` are array which of course means, that order of attributes matters.
|
145
145
|
|
146
|
+
There's also a possibility to specify available sort directions using `:sort_dirs` option which is by default `[nil, "asc", "desc"]`.
|
147
|
+
|
146
148
|
### List item management and in-place editing
|
147
149
|
|
148
150
|
In order to allow managing and editing list items, we need to reorganize our views a bit. Basically, each item needs to have its own partial:
|
@@ -241,6 +243,31 @@ users_scope = users_scope.like(params[:filter]) if params[:filter]
|
|
241
243
|
|
242
244
|
Then, JS view is rendered and your SmartListing updated. That's it!
|
243
245
|
|
246
|
+
### Simplified views
|
247
|
+
|
248
|
+
You don't need to create all the JS views in case you want to simply use one SmartListing per controller. Just use helper methods without their first attribute (name) ie. `smart_listing_create(User.active, partial: "users/listing")`. Then define two helper methods:
|
249
|
+
|
250
|
+
* `smart_listing_resource` returning single object,
|
251
|
+
* `smart_listing_collection` returning collection of objects.
|
252
|
+
|
253
|
+
SmartListing default views will user these methods to render your list properly.
|
254
|
+
|
255
|
+
### More customization
|
256
|
+
|
257
|
+
Apart from standard SmartListing initializer, you can also define custom config profiles. In order to do this, use following syntax:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
SmartListing.configure(:awesome_profile) do |config|
|
261
|
+
# put your definitions here
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
In order to use this profile, create helper method named `smart_listing_config_profile` returning profile name and put into your JS `SmartListing.config.merge()` function call. `merge()` function expects parameter with config attributes hash or reads body data-attribute named `smart-listing-config`. Hash of config attributes can be obtained by using helper method `SmartListing.config(:awesome_profile).to_json`.
|
266
|
+
|
267
|
+
## Not enough?
|
268
|
+
|
269
|
+
For more information and some use cases, see the [Showcase](http://showcase.sology.eu/smart_listing)
|
270
|
+
|
244
271
|
## Credits
|
245
272
|
|
246
273
|
SmartListing uses great pagination gem Kaminari https://github.com/amatsuda/kaminari
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
14
14
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
15
|
end
|
16
16
|
|
17
|
-
APP_RAKEFILE = File.expand_path("../
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
18
|
load 'rails/tasks/engine.rake'
|
19
19
|
|
20
20
|
|
@@ -1,25 +1,46 @@
|
|
1
1
|
# Useful when SmartListing target url is different than current one
|
2
2
|
$.rails.href = (element) ->
|
3
|
-
element.attr(
|
3
|
+
element.attr("href") || element.data("<%= SmartListing.config.data_attributes(:href) %>")
|
4
|
+
|
5
|
+
class window.SmartListing
|
6
|
+
class Config
|
7
|
+
@options: <%= SmartListing.config.dump_json %>
|
8
|
+
|
9
|
+
@merge: (d) ->
|
10
|
+
$.extend true, @options, d || $("body").data("smart-listing-config")
|
11
|
+
|
12
|
+
@class: (name)->
|
13
|
+
@options["constants"]["classes"][name]
|
14
|
+
|
15
|
+
@class_name: (name) ->
|
16
|
+
".#{@class(name)}"
|
17
|
+
|
18
|
+
@data_attribute: (name)->
|
19
|
+
@options["constants"]["data_attributes"][name]
|
20
|
+
|
21
|
+
@selector: (name)->
|
22
|
+
@options["constants"]["selectors"][name]
|
23
|
+
|
24
|
+
@config: Config
|
25
|
+
|
4
26
|
|
5
|
-
class SmartListing
|
6
27
|
constructor: (e) ->
|
7
28
|
@container = e
|
8
|
-
@name = @container.attr(
|
9
|
-
@loading = @container.find(
|
10
|
-
@content = @container.find(
|
11
|
-
@status = $("
|
29
|
+
@name = @container.attr("id")
|
30
|
+
@loading = @container.find(SmartListing.config.class_name("loading"))
|
31
|
+
@content = @container.find(SmartListing.config.class_name("content"))
|
32
|
+
@status = $("#{SmartListing.config.class_name("status")} [data-#{SmartListing.config.data_attribute("main")}='#{@name}']")
|
12
33
|
@confirmed = null
|
13
34
|
@popovers = {}
|
14
35
|
|
15
|
-
@container.on
|
36
|
+
@container.on "ajax:before", (e) =>
|
16
37
|
@fadeLoading()
|
17
38
|
|
18
|
-
@container.on
|
19
|
-
if $(e.target).is(
|
39
|
+
@container.on "ajax:success", (e) =>
|
40
|
+
if $(e.target).is("#{SmartListing.config.class_name("item_actions")} #{SmartListing.config.selector("item_action_destroy")}")
|
20
41
|
# handle HEAD OK response for deletion request
|
21
|
-
editable = $(e.target).closest(
|
22
|
-
if @container.find(
|
42
|
+
editable = $(e.target).closest(SmartListing.config.class_name("editable"))
|
43
|
+
if @container.find(SmartListing.config.class_name("editable")).length == 1
|
23
44
|
@reload()
|
24
45
|
return false
|
25
46
|
else
|
@@ -33,41 +54,41 @@ class SmartListing
|
|
33
54
|
@fadeLoaded()
|
34
55
|
return false
|
35
56
|
|
36
|
-
@container.on
|
37
|
-
editable = $(event.currentTarget).closest(
|
57
|
+
@container.on "click", SmartListing.config.selector("edit_cancel"), (event) =>
|
58
|
+
editable = $(event.currentTarget).closest(SmartListing.config.class_name("editable"))
|
38
59
|
if(editable.length > 0)
|
39
60
|
# Cancel edit
|
40
61
|
@cancelEdit(editable)
|
41
62
|
else
|
42
63
|
# Cancel new record
|
43
|
-
@container.find(
|
44
|
-
@container.find(
|
64
|
+
@container.find(SmartListing.config.class_name("new_item_placeholder")).addClass(SmartListing.config.class_name("hidden"))
|
65
|
+
@container.find(SmartListing.config.class_name("new_item_action")).removeClass(SmartListing.config.class_name("hidden"))
|
45
66
|
|
46
67
|
@setAutoshow(false)
|
47
68
|
false
|
48
69
|
|
49
|
-
@container.on
|
50
|
-
$.fn.smart_listing.confirm $(event.currentTarget), $(event.currentTarget).data(
|
70
|
+
@container.on "click", "#{SmartListing.config.class_name("item_actions")} a[data-#{SmartListing.config.data_attribute("confirmation")}]", (event) =>
|
71
|
+
$.fn.smart_listing.confirm $(event.currentTarget), $(event.currentTarget).data(SmartListing.config.data_attribute("confirmation"))
|
51
72
|
|
52
|
-
@container.on
|
53
|
-
name = $(event.currentTarget).data(
|
73
|
+
@container.on "click", "#{SmartListing.config.class_name("item_actions")} a[data-#{SmartListing.config.data_attribute("popover")}]", (event) =>
|
74
|
+
name = $(event.currentTarget).data(SmartListing.config.data_attribute("popover"))
|
54
75
|
if jQuery.isFunction(@popovers[name])
|
55
76
|
@popovers[name]($(event.currentTarget))
|
56
77
|
false
|
57
78
|
|
58
79
|
|
59
|
-
@container.on
|
80
|
+
@container.on "click", "input[type=text]#{SmartListing.config.class_name("autoselect")}", (event) ->
|
60
81
|
$(this).select()
|
61
82
|
|
62
|
-
@container.on
|
83
|
+
@container.on "change", SmartListing.config.class_name("callback"), (event) =>
|
63
84
|
checkbox = $(event.currentTarget)
|
64
|
-
id = checkbox.closest(
|
85
|
+
id = checkbox.closest(SmartListing.config.selector("row")).data(SmartListing.config.data_attribute("id"))
|
65
86
|
data = {}
|
66
87
|
data[checkbox.val()] = checkbox.is(":checked")
|
67
88
|
$.ajax({
|
68
89
|
beforeSend: (xhr, settings) ->
|
69
90
|
xhr.setRequestHeader "accept", "*/*;q=0.5, " + settings.accepts.script
|
70
|
-
url: @container.data(
|
91
|
+
url: @container.data(SmartListing.config.data_attribute("callback_href")),
|
71
92
|
type: "POST",
|
72
93
|
data: data,
|
73
94
|
})
|
@@ -79,28 +100,31 @@ class SmartListing
|
|
79
100
|
$.fn.smart_listing.onLoaded(@content, @loading)
|
80
101
|
|
81
102
|
itemCount: =>
|
82
|
-
parseInt(@container.
|
103
|
+
parseInt(@container.data(SmartListing.config.data_attribute("item_count")))
|
83
104
|
|
84
105
|
maxCount: =>
|
85
|
-
parseInt(@container.data(
|
106
|
+
parseInt(@container.data(SmartListing.config.data_attribute("max_count")))
|
86
107
|
|
87
108
|
setAutoshow: (v) =>
|
88
|
-
|
109
|
+
|
110
|
+
@container.data(SmartListing.config.data_attribute("autoshow"), v)
|
89
111
|
|
90
112
|
changeItemCount: (value) =>
|
91
|
-
@container.
|
113
|
+
count = @container.data(SmartListing.config.data_attribute("item_count")) + value
|
114
|
+
@container.data(SmartListing.config.data_attribute("item_count"), count)
|
115
|
+
@container.find(SmartListing.config.selector("pagination_count")).html(count)
|
92
116
|
|
93
117
|
cancelEdit: (editable) =>
|
94
|
-
if editable.data(
|
95
|
-
editable.html(editable.data(
|
96
|
-
editable.removeClass(
|
97
|
-
editable.removeData(
|
118
|
+
if editable.data(SmartListing.config.data_attribute("inline_edit_backup"))
|
119
|
+
editable.html(editable.data(SmartListing.config.data_attribute("inline_edit_backup")))
|
120
|
+
editable.removeClass(SmartListing.config.class("inline_editing"))
|
121
|
+
editable.removeData(SmartListing.config.data_attribute("inline_edit_backup"))
|
98
122
|
|
99
123
|
# Callback called when record is added/deleted using ajax request
|
100
124
|
refresh: () =>
|
101
|
-
header = @content.find(
|
102
|
-
footer = @content.find(
|
103
|
-
no_records = @content.find(
|
125
|
+
header = @content.find(SmartListing.config.selector("head"))
|
126
|
+
footer = @content.find(SmartListing.config.class_name("pagination_per_page"))
|
127
|
+
no_records = @content.find(SmartListing.config.class_name("no_records"))
|
104
128
|
|
105
129
|
if @itemCount() == 0
|
106
130
|
header.hide()
|
@@ -113,61 +137,67 @@ class SmartListing
|
|
113
137
|
|
114
138
|
if @maxCount()
|
115
139
|
if @itemCount() >= @maxCount()
|
116
|
-
@container.find(
|
117
|
-
@container.find(
|
140
|
+
@container.find(SmartListing.config.class_name("new_item_placeholder")).addClass(SmartListing.config.class("hidden"))
|
141
|
+
@container.find(SmartListing.config.class_name("new_item_action")).addClass(SmartListing.config.class("hidden"))
|
118
142
|
else
|
119
|
-
if @container.data(
|
120
|
-
@container.find(
|
121
|
-
@container.find(
|
143
|
+
if @container.data(SmartListing.config.data_attribute("autoshow"))
|
144
|
+
@container.find(SmartListing.config.class_name("new_item_placeholder")).removeClass(SmartListing.config.class("hidden"))
|
145
|
+
@container.find(SmartListing.config.class_name("new_item_action")).addClass(SmartListing.config.class("hidden"))
|
122
146
|
else
|
123
|
-
@container.find(
|
124
|
-
@container.find(
|
147
|
+
@container.find(SmartListing.config.class_name("new_item_placeholder")).addClass(SmartListing.config.class("hidden"))
|
148
|
+
@container.find(SmartListing.config.class_name("new_item_action")).removeClass(SmartListing.config.class("hidden"))
|
125
149
|
|
126
150
|
@status.each (index, status) =>
|
127
|
-
$(status).find(
|
151
|
+
$(status).find(SmartListing.config.class_name("limit")).html(@maxCount() - @itemCount())
|
128
152
|
if @maxCount() - @itemCount() == 0
|
129
|
-
$(status).find(
|
153
|
+
$(status).find(SmartListing.config.class_name("limit_alert")).show()
|
130
154
|
else
|
131
|
-
$(status).find(
|
155
|
+
$(status).find(SmartListing.config.class_name("limit_alert")).hide()
|
132
156
|
|
133
157
|
# Trigger AJAX request to reload the list
|
134
158
|
reload: () =>
|
135
159
|
$.rails.handleRemote(@container)
|
136
160
|
|
137
|
-
params: () =>
|
138
|
-
|
161
|
+
params: (value) =>
|
162
|
+
if value
|
163
|
+
@container.data(SmartListing.config.data_attribute("params"), value)
|
164
|
+
else
|
165
|
+
@container.data(SmartListing.config.data_attribute("params"))
|
139
166
|
|
140
167
|
registerPopover: (name, callback) =>
|
141
168
|
@popovers[name] = callback
|
142
169
|
|
170
|
+
editable: (id) =>
|
171
|
+
@container.find("#{SmartListing.config.class_name("editable")}[data-#{SmartListing.config.data_attribute("id")}=#{id}]")
|
172
|
+
|
143
173
|
#################################################################################################
|
144
174
|
# Methods executed by rails UJS:
|
145
175
|
|
146
176
|
new_item: (content) =>
|
147
177
|
if !@maxCount() || (@itemCount() < @maxCount())
|
148
|
-
new_item_action = @container.find(
|
149
|
-
new_item_placeholder = @container.find(
|
178
|
+
new_item_action = @container.find(SmartListing.config.class_name("new_item_action"))
|
179
|
+
new_item_placeholder = @container.find(SmartListing.config.class_name("new_item_placeholder")).addClass(SmartListing.config.class("hidden"))
|
150
180
|
|
151
|
-
@container.find(
|
181
|
+
@container.find(SmartListing.config.class_name("editable")).each (i, v) =>
|
152
182
|
@cancelEdit($(v))
|
153
183
|
|
154
|
-
new_item_action.addClass(
|
155
|
-
new_item_placeholder.removeClass(
|
184
|
+
new_item_action.addClass(SmartListing.config.class("hidden"))
|
185
|
+
new_item_placeholder.removeClass(SmartListing.config.class("hidden"))
|
156
186
|
new_item_placeholder.html(content)
|
157
|
-
new_item_placeholder.addClass(
|
187
|
+
new_item_placeholder.addClass(SmartListing.config.class("inline_editing"))
|
158
188
|
|
159
189
|
@fadeLoaded()
|
160
190
|
|
161
191
|
create: (id, success, content) =>
|
162
|
-
new_item_action = @container.find(
|
163
|
-
new_item_placeholder = @container.find(
|
192
|
+
new_item_action = @container.find(SmartListing.config.class_name("new_item_action"))
|
193
|
+
new_item_placeholder = @container.find(SmartListing.config.class_name("new_item_placeholder"))
|
164
194
|
|
165
195
|
if success
|
166
|
-
new_item_placeholder.addClass(
|
167
|
-
new_item_action.removeClass(
|
196
|
+
new_item_placeholder.addClass(SmartListing.config.class("hidden"))
|
197
|
+
new_item_action.removeClass(SmartListing.config.class("hidden"))
|
168
198
|
|
169
|
-
new_item = $(
|
170
|
-
new_item.attr(
|
199
|
+
new_item = $("<tr />").addClass(SmartListing.config.class("editable"))
|
200
|
+
new_item.attr("data-#{SmartListing.config.data_attribute("id")}", id)
|
171
201
|
new_item.html(content)
|
172
202
|
new_item_placeholder.before(new_item)
|
173
203
|
|
@@ -183,25 +213,25 @@ class SmartListing
|
|
183
213
|
@fadeLoaded()
|
184
214
|
|
185
215
|
edit: (id, content) =>
|
186
|
-
@container.find(
|
216
|
+
@container.find(SmartListing.config.class_name("editable")).each (i, v) =>
|
187
217
|
@cancelEdit($(v))
|
188
|
-
@container.find(
|
189
|
-
@container.find(
|
218
|
+
@container.find(SmartListing.config.class_name("new_item_placeholder")).addClass(SmartListing.config.class("hidden"))
|
219
|
+
@container.find(SmartListing.config.class_name("new_item_action")).removeClass(SmartListing.config.class("hidden"))
|
190
220
|
|
191
|
-
editable = @
|
192
|
-
editable.data(
|
221
|
+
editable = @editable(id)
|
222
|
+
editable.data(SmartListing.config.data_attribute("inline_edit_backup"), editable.html())
|
193
223
|
editable.html(content)
|
194
|
-
editable.addClass(
|
224
|
+
editable.addClass(SmartListing.config.class("inline_editing"))
|
195
225
|
|
196
226
|
@container.trigger("smart_listing:edit", editable)
|
197
227
|
|
198
228
|
@fadeLoaded()
|
199
229
|
|
200
230
|
update: (id, success, content) =>
|
201
|
-
editable = @
|
231
|
+
editable = @editable(id)
|
202
232
|
if success
|
203
|
-
editable.removeClass(
|
204
|
-
editable.removeData(
|
233
|
+
editable.removeClass(SmartListing.config.class("inline_editing"))
|
234
|
+
editable.removeData(SmartListing.config.data_attribute("inline_edit_backup"))
|
205
235
|
editable.html(content)
|
206
236
|
|
207
237
|
@container.trigger("smart_listing:update:success", editable)
|
@@ -218,25 +248,28 @@ class SmartListing
|
|
218
248
|
# No need to do anything here, already handled by ajax:success handler
|
219
249
|
|
220
250
|
remove: (id) =>
|
221
|
-
editable = @
|
251
|
+
editable = @editable(id)
|
222
252
|
editable.remove()
|
223
253
|
|
224
254
|
@container.trigger("smart_listing:remove", editable)
|
225
255
|
|
226
256
|
update_list: (content, data) =>
|
227
|
-
|
228
|
-
|
257
|
+
@container.data(SmartListing.config.data_attribute("params"), $.extend(@container.data(SmartListing.config.data_attribute("params")), data[SmartListing.config.data_attribute("params")]))
|
258
|
+
@container.data(SmartListing.config.data_attribute("max_count"), data[SmartListing.config.data_attribute("max_count")])
|
259
|
+
@container.data(SmartListing.config.data_attribute("item_count"), data[SmartListing.config.data_attribute("item_count")])
|
229
260
|
|
230
261
|
@content.html(content)
|
231
262
|
|
232
263
|
@refresh()
|
233
264
|
@fadeLoaded()
|
234
265
|
|
266
|
+
@container.trigger("smart_listing:update_list", @container)
|
267
|
+
|
235
268
|
$.fn.smart_listing = () ->
|
236
269
|
map = $(this).map () ->
|
237
|
-
if !$(this).data(
|
238
|
-
$(this).data(
|
239
|
-
$(this).data(
|
270
|
+
if !$(this).data(SmartListing.config.data_attribute("main"))
|
271
|
+
$(this).data(SmartListing.config.data_attribute("main"), new SmartListing($(this)))
|
272
|
+
$(this).data(SmartListing.config.data_attribute("main"))
|
240
273
|
if map.length == 1
|
241
274
|
map[0]
|
242
275
|
else
|
@@ -263,9 +296,9 @@ $.fn.smart_listing.observeField = (field, opts = {}) ->
|
|
263
296
|
|
264
297
|
options.onChange()
|
265
298
|
|
266
|
-
field.data(
|
299
|
+
field.data(SmartListing.config.data_attribute("observed"), true)
|
267
300
|
|
268
|
-
field.bind
|
301
|
+
field.bind "keydown", (e) ->
|
269
302
|
if(key_timeout)
|
270
303
|
clearTimeout(key_timeout)
|
271
304
|
|
@@ -274,26 +307,26 @@ $.fn.smart_listing.observeField = (field, opts = {}) ->
|
|
274
307
|
, 400)
|
275
308
|
|
276
309
|
$.fn.smart_listing.showPopover = (elem, body) ->
|
277
|
-
elem.popover(
|
278
|
-
elem.popover(content: body, html: true, trigger:
|
279
|
-
elem.popover(
|
310
|
+
elem.popover("destroy")
|
311
|
+
elem.popover(content: body, html: true, trigger: "manual", title: null)
|
312
|
+
elem.popover("show")
|
280
313
|
|
281
314
|
$.fn.smart_listing.showConfirmation = (confirmation_elem, msg, confirm_callback) ->
|
282
315
|
buildPopover = (confirmation_elem, msg) ->
|
283
|
-
deletion_popover = $(
|
284
|
-
deletion_popover.append($(
|
285
|
-
deletion_popover.append($(
|
286
|
-
.append($(
|
316
|
+
deletion_popover = $("<div/>").addClass("confirmation_box")
|
317
|
+
deletion_popover.append($("<p/>").html(msg))
|
318
|
+
deletion_popover.append($("<p/>")
|
319
|
+
.append($("<button/>").html("Yes").addClass("btn btn-danger ").click (event) =>
|
287
320
|
# set @confirmed element and emulate click on icon
|
288
|
-
editable = $(event.currentTarget).closest(
|
321
|
+
editable = $(event.currentTarget).closest(SmartListing.config.class_name("editable"))
|
289
322
|
confirm_callback(confirmation_elem)
|
290
323
|
$(confirmation_elem).click()
|
291
|
-
$(confirmation_elem).popover(
|
324
|
+
$(confirmation_elem).popover("destroy")
|
292
325
|
)
|
293
326
|
.append(" ")
|
294
|
-
.append($(
|
295
|
-
editable = $(event.currentTarget).closest(
|
296
|
-
$(confirmation_elem).popover(
|
327
|
+
.append($("<button/>").html("No").addClass("btn btn-small").click (event) =>
|
328
|
+
editable = $(event.currentTarget).closest(SmartListing.config.class_name("editable"))
|
329
|
+
$(confirmation_elem).popover("destroy")
|
297
330
|
)
|
298
331
|
)
|
299
332
|
|
@@ -321,59 +354,68 @@ $.fn.smart_listing.onLoaded = (content, loader) ->
|
|
321
354
|
loader.hide()
|
322
355
|
|
323
356
|
$.fn.smart_listing_controls = () ->
|
324
|
-
|
325
|
-
|
326
|
-
smart_listing =
|
327
|
-
reset = controls.find(".<%= SmartListing.config.classes(:controls_reset) %>")
|
357
|
+
reload = (controls) ->
|
358
|
+
container = $("##{controls.data(SmartListing.config.data_attribute("main"))}")
|
359
|
+
smart_listing = container.smart_listing()
|
328
360
|
|
329
|
-
|
330
|
-
|
331
|
-
|
361
|
+
# serialize form and merge it with smart listing params
|
362
|
+
prms = {}
|
363
|
+
$.each controls.serializeArray(), (i, field) ->
|
364
|
+
prms[field.name] = field.value
|
365
|
+
prms = $.extend(smart_listing.params(), prms)
|
366
|
+
smart_listing.params(prms)
|
332
367
|
|
333
|
-
|
334
|
-
|
335
|
-
prms[$(this).data('<%= SmartListing.config.classes(:controls_reset) %>')] = null
|
368
|
+
container.trigger("ajax:before")
|
369
|
+
smart_listing.reload()
|
336
370
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
controls.attr('action', "?" + jQuery.param(prms))
|
371
|
+
$(this).each () ->
|
372
|
+
# avoid double initialization
|
373
|
+
return if $(this).data(SmartListing.config.data_attribute("controls_initialized"))
|
374
|
+
$(this).data(SmartListing.config.data_attribute("controls_initialized"), true)
|
342
375
|
|
343
|
-
|
344
|
-
|
376
|
+
controls = $(this)
|
377
|
+
smart_listing = $("##{controls.data(SmartListing.config.data_attribute("main"))}")
|
378
|
+
reset = controls.find(SmartListing.config.class_name("controls_reset"))
|
345
379
|
|
346
|
-
controls.
|
347
|
-
|
348
|
-
|
380
|
+
controls.submit ->
|
381
|
+
# setup smart listing params, reload and don"t actually submit controls form
|
382
|
+
reload(controls)
|
383
|
+
false
|
349
384
|
|
350
|
-
|
385
|
+
controls.find("input, select").change () ->
|
386
|
+
unless $(this).data(SmartListing.config.data_attribute("observed")) # do not submit controls form when changed field is observed (observing submits form by itself)
|
387
|
+
reload(controls)
|
388
|
+
|
389
|
+
$.fn.smart_listing_controls.filter(controls.find(SmartListing.config.class_name("filtering")))
|
351
390
|
|
352
391
|
$.fn.smart_listing_controls.filter = (filter) ->
|
353
|
-
form = filter.closest(
|
354
|
-
button = form.find(
|
355
|
-
icon = form.find(
|
356
|
-
field = form.find(
|
392
|
+
form = filter.closest("form")
|
393
|
+
button = form.find(SmartListing.config.selector("filtering_button"))
|
394
|
+
icon = form.find(SmartListing.config.selector("filtering_icon"))
|
395
|
+
field = form.find(SmartListing.config.selector("filtering_input"))
|
357
396
|
|
358
397
|
$.fn.smart_listing.observeField(field,
|
359
398
|
onFilled: ->
|
360
|
-
icon.removeClass(
|
361
|
-
icon.addClass(
|
362
|
-
button.removeClass(
|
399
|
+
icon.removeClass(SmartListing.config.class("filtering_search"))
|
400
|
+
icon.addClass(SmartListing.config.class("filtering_cancel"))
|
401
|
+
button.removeClass(SmartListing.config.class("filtering_disabled"))
|
363
402
|
onEmpty: ->
|
364
|
-
icon.addClass(
|
365
|
-
icon.removeClass(
|
366
|
-
button.addClass(
|
403
|
+
icon.addClass(SmartListing.config.class("filtering_search"))
|
404
|
+
icon.removeClass(SmartListing.config.class("filtering_cancel"))
|
405
|
+
button.addClass(SmartListing.config.class("filtering_disabled"))
|
367
406
|
onChange: ->
|
368
407
|
form.submit()
|
369
408
|
)
|
370
409
|
|
371
410
|
button.click ->
|
372
411
|
if field.val().length > 0
|
373
|
-
field.val(
|
374
|
-
field.trigger(
|
412
|
+
field.val("")
|
413
|
+
field.trigger("keydown")
|
375
414
|
return false
|
376
415
|
|
377
|
-
|
378
|
-
$(
|
379
|
-
$(
|
416
|
+
ready = ->
|
417
|
+
$(SmartListing.config.class_name("main")).smart_listing()
|
418
|
+
$(SmartListing.config.class_name("controls")).smart_listing_controls()
|
419
|
+
|
420
|
+
$(document).ready ready
|
421
|
+
$(document).on "page:load", ready
|