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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41dcdfa429d72c12038175a0eb1252ad399b2a71
4
- data.tar.gz: d277995fe1f1474795326b8db38c0fd07b307c0f
3
+ metadata.gz: 59e85525d27d91f8ccf4ede3196a9d665e80e636
4
+ data.tar.gz: 2715e1395d0ea7eff77d9a531639b0917143212a
5
5
  SHA512:
6
- metadata.gz: 6feb82a31cbe7dfdad359b3427325447a4ea63ad425189c752da1e93a9e1612ca32adb2d0f08f489193f9a29854721cf849b6e78f33c67f8789e8546d937e24c
7
- data.tar.gz: c958ec953a3b49097490e90affb1785af82fa62c8318feafc7d3a72f37ebd86e8ca977dd9e47171dda0a289633e72c6819befa15995ce3ca0e857b526354544a
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", "name"
117
- %th= smart_listing.sortable "Email", "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 `"name"` and `"email"` are sorting column names. `Builder#sortable` renders special link containing column name and sort order (either `asc`, `desc`, or empty value).
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: {:name: "asc"})
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("../test/dummy/Rakefile", __FILE__)
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('href') || element.data('<%= SmartListing.config.data_attributes(:href) %>')
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('id')
9
- @loading = @container.find(".<%= SmartListing.config.classes(:loading) %>")
10
- @content = @container.find(".<%= SmartListing.config.classes(:content) %>")
11
- @status = $(".<%= SmartListing.config.classes(:status) %>[data-<%= SmartListing.config.data_attributes(:main) %>='#{@name}']")
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 'ajax:before', (e) =>
36
+ @container.on "ajax:before", (e) =>
16
37
  @fadeLoading()
17
38
 
18
- @container.on 'ajax:success', (e) =>
19
- if $(e.target).is('.<%= SmartListing.config.classes(:item_actions) %> <%= SmartListing.config.selectors(:item_action_destroy) %>')
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('.<%= SmartListing.config.classes(:editable) %>')
22
- if @container.find(".<%= SmartListing.config.classes(:editable) %>").length == 1
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 'click', '<%= SmartListing.config.selectors(:edit_cancel) %>', (event) =>
37
- editable = $(event.currentTarget).closest('.<%= SmartListing.config.classes(:editable) %>')
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('.<%= SmartListing.config.classes(:new_item_placeholder) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
44
- @container.find('.<%= SmartListing.config.classes(:new_item_action) %>').removeClass('<%= SmartListing.config.classes(:hidden) %>')
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 'click', '.<%= SmartListing.config.classes(:item_actions) %> a[data-<%= SmartListing.config.data_attributes(:confirmation) %>]', (event) =>
50
- $.fn.smart_listing.confirm $(event.currentTarget), $(event.currentTarget).data('<%= SmartListing.config.data_attributes(:confirmation) %>')
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 'click', '.<%= SmartListing.config.classes(:item_actions) %> a[data-<%= SmartListing.config.data_attributes(:popover) %>]', (event) =>
53
- name = $(event.currentTarget).data('<%= SmartListing.config.data_attributes(:popover) %>')
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 'click', 'input[type=text].<%= SmartListing.config.classes(:autoselect) %>', (event) ->
80
+ @container.on "click", "input[type=text]#{SmartListing.config.class_name("autoselect")}", (event) ->
60
81
  $(this).select()
61
82
 
62
- @container.on 'change', '.<%= SmartListing.config.classes(:callback) %>', (event) =>
83
+ @container.on "change", SmartListing.config.class_name("callback"), (event) =>
63
84
  checkbox = $(event.currentTarget)
64
- id = checkbox.closest("<%= SmartListing.config.selectors(:row) %>").data("<%= SmartListing.config.data_attributes(:id) %>")
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("<%= SmartListing.config.data_attributes(:callback_href) %>"),
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.find('.<%= SmartListing.config.classes(:pagination_per_page) %> .<%= SmartListing.config.classes(:pagination_count) %>').html())
103
+ parseInt(@container.data(SmartListing.config.data_attribute("item_count")))
83
104
 
84
105
  maxCount: =>
85
- parseInt(@container.data('<%= SmartListing.config.data_attributes(:max_count) %>'))
106
+ parseInt(@container.data(SmartListing.config.data_attribute("max_count")))
86
107
 
87
108
  setAutoshow: (v) =>
88
- @container.data('<%= SmartListing.config.data_attributes(:autoshow) %>', v)
109
+
110
+ @container.data(SmartListing.config.data_attribute("autoshow"), v)
89
111
 
90
112
  changeItemCount: (value) =>
91
- @container.find('.<%= SmartListing.config.classes(:pagination_per_page) %> .<%= SmartListing.config.classes(:pagination_count) %>').html(@itemCount() + value)
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('<%= SmartListing.config.data_attributes(:inline_edit_backup) %>')
95
- editable.html(editable.data('<%= SmartListing.config.data_attributes(:inline_edit_backup) %>'))
96
- editable.removeClass('<%= SmartListing.config.classes(:inline_editing) %>')
97
- editable.removeData('<%= SmartListing.config.data_attributes(:inline_edit_backup) %>')
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('<%= SmartListing.config.selectors(:head) %>')
102
- footer = @content.find('.<%= SmartListing.config.classes(:pagination_per_page) %>')
103
- no_records = @content.find('.<%= SmartListing.config.classes(:no_records) %>')
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('.<%= SmartListing.config.classes(:new_item_placeholder) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
117
- @container.find('.<%= SmartListing.config.classes(:new_item_action) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
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('<%= SmartListing.config.data_attributes(:autoshow) %>')
120
- @container.find('.<%= SmartListing.config.classes(:new_item_placeholder) %>').removeClass('<%= SmartListing.config.classes(:hidden) %>')
121
- @container.find('.<%= SmartListing.config.classes(:new_item_action) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
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('.<%= SmartListing.config.classes(:new_item_placeholder) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
124
- @container.find('.<%= SmartListing.config.classes(:new_item_action) %>').removeClass('<%= SmartListing.config.classes(:hidden) %>')
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('.<%= SmartListing.config.classes(:limit) %>').html(@maxCount() - @itemCount())
151
+ $(status).find(SmartListing.config.class_name("limit")).html(@maxCount() - @itemCount())
128
152
  if @maxCount() - @itemCount() == 0
129
- $(status).find('.<%= SmartListing.config.classes(:limit_alert) %>').show()
153
+ $(status).find(SmartListing.config.class_name("limit_alert")).show()
130
154
  else
131
- $(status).find('.<%= SmartListing.config.classes(:limit_alert) %>').hide()
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
- @container.data('<%= SmartListing.config.data_attributes(:params) %>')
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('.<%= SmartListing.config.classes(:new_item_action) %>')
149
- new_item_placeholder = @container.find('.<%= SmartListing.config.classes(:new_item_placeholder) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
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('.<%= SmartListing.config.classes(:editable) %>').each (i, v) =>
181
+ @container.find(SmartListing.config.class_name("editable")).each (i, v) =>
152
182
  @cancelEdit($(v))
153
183
 
154
- new_item_action.addClass('<%= SmartListing.config.classes(:hidden) %>')
155
- new_item_placeholder.removeClass('<%= SmartListing.config.classes(:hidden) %>')
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('<%= SmartListing.config.classes(:inline_editing) %>')
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('.<%= SmartListing.config.classes(:new_item_action) %>')
163
- new_item_placeholder = @container.find('.<%= SmartListing.config.classes(:new_item_placeholder) %>')
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('<%= SmartListing.config.classes(:hidden) %>')
167
- new_item_action.removeClass('<%= SmartListing.config.classes(:hidden) %>')
196
+ new_item_placeholder.addClass(SmartListing.config.class("hidden"))
197
+ new_item_action.removeClass(SmartListing.config.class("hidden"))
168
198
 
169
- new_item = $('<tr />').addClass('<%= SmartListing.config.classes(:editable) %>')
170
- new_item.attr('data-<%= SmartListing.config.data_attributes(:id) %>', id)
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('.<%= SmartListing.config.classes(:editable) %>').each (i, v) =>
216
+ @container.find(SmartListing.config.class_name("editable")).each (i, v) =>
187
217
  @cancelEdit($(v))
188
- @container.find('.<%= SmartListing.config.classes(:new_item_placeholder) %>').addClass('<%= SmartListing.config.classes(:hidden) %>')
189
- @container.find('.<%= SmartListing.config.classes(:new_item_action) %>').removeClass('<%= SmartListing.config.classes(:hidden) %>')
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 = @container.find(".<%= SmartListing.config.classes(:editable) %>[data-<%= SmartListing.config.data_attributes(:id) %>=#{id}]")
192
- editable.data('<%= SmartListing.config.data_attributes(:inline_edit_backup) %>', editable.html())
221
+ editable = @editable(id)
222
+ editable.data(SmartListing.config.data_attribute("inline_edit_backup"), editable.html())
193
223
  editable.html(content)
194
- editable.addClass('<%= SmartListing.config.classes(:inline_editing) %>')
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 = @container.find(".<%= SmartListing.config.classes(:editable) %>[data-<%= SmartListing.config.data_attributes(:id) %>=#{id}]")
231
+ editable = @editable(id)
202
232
  if success
203
- editable.removeClass('<%= SmartListing.config.classes(:inline_editing) %>')
204
- editable.removeData('<%= SmartListing.config.data_attributes(:inline_edit_backup) %>')
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 = @container.find(".<%= SmartListing.config.classes(:editable) %>[data-<%= SmartListing.config.data_attributes(:id) %>=#{id}]").first()
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
- $.each data, (key, value) =>
228
- @container.data(key, value)
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('<%= SmartListing.config.data_attributes(:main) %>')
238
- $(this).data('<%= SmartListing.config.data_attributes(:main) %>', new SmartListing($(this)))
239
- $(this).data('<%= SmartListing.config.data_attributes(:main) %>')
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('<%= SmartListing.config.data_attributes(:observed) %>', true)
299
+ field.data(SmartListing.config.data_attribute("observed"), true)
267
300
 
268
- field.bind 'keydown', (e) ->
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('destroy')
278
- elem.popover(content: body, html: true, trigger: 'manual', title: null)
279
- elem.popover('show')
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 = $('<div/>').addClass('confirmation_box')
284
- deletion_popover.append($('<p/>').html(msg))
285
- deletion_popover.append($('<p/>')
286
- .append($('<button/>').html('Yes').addClass('btn btn-danger ').click (event) =>
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('.<%= SmartListing.config.classes(:editable) %>')
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('destroy')
324
+ $(confirmation_elem).popover("destroy")
292
325
  )
293
326
  .append(" ")
294
- .append($('<button/>').html('No').addClass('btn btn-small').click (event) =>
295
- editable = $(event.currentTarget).closest('.<%= SmartListing.config.classes(:editable) %>')
296
- $(confirmation_elem).popover('destroy')
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
- $(this).each () ->
325
- controls = $(this)
326
- smart_listing = $("##{controls.data('<%= SmartListing.config.data_attributes(:main) %>')}")
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
- controls.submit ->
330
- # Merges smart list params with the form action url before submitting.
331
- # This preserves smart list settings (page, sorting etc.).
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
- prms = $.extend({}, smart_listing.smart_listing().params())
334
- if $(this).data('<%= SmartListing.config.classes(:controls_reset) %>')
335
- prms[$(this).data('<%= SmartListing.config.classes(:controls_reset) %>')] = null
368
+ container.trigger("ajax:before")
369
+ smart_listing.reload()
336
370
 
337
- if $.rails.href(smart_listing)
338
- # If smart list has different target url than current one
339
- controls.attr('action', $.rails.href(smart_listing) + "?" + jQuery.param(prms))
340
- else
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
- smart_listing.trigger('ajax:before')
344
- true
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.find('input, select').change () ->
347
- unless $(this).data('<%= SmartListing.config.data_attributes(:observed) %>') # do not submit controls form when changed field is observed (observing submits form by itself)
348
- controls.submit()
380
+ controls.submit ->
381
+ # setup smart listing params, reload and don"t actually submit controls form
382
+ reload(controls)
383
+ false
349
384
 
350
- $.fn.smart_listing_controls.filter(controls.find('.<%= SmartListing.config.classes(:filtering) %>'))
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('form')
354
- button = form.find('<%= SmartListing.config.selectors(:filtering_button) %>')
355
- icon = form.find('<%= SmartListing.config.selectors(:filtering_icon) %>')
356
- field = form.find('<%= SmartListing.config.selectors(:filtering_input) %>')
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('<%= SmartListing.config.classes(:filtering_search) %>')
361
- icon.addClass('<%= SmartListing.config.classes(:filtering_cancel) %>')
362
- button.removeClass('<%= SmartListing.config.classes(:filtering_disabled) %>')
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('<%= SmartListing.config.classes(:filtering_search) %>')
365
- icon.removeClass('<%= SmartListing.config.classes(:filtering_cancel) %>')
366
- button.addClass('<%= SmartListing.config.classes(:filtering_disabled) %>')
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('keydown')
412
+ field.val("")
413
+ field.trigger("keydown")
375
414
  return false
376
415
 
377
- $ ->
378
- $('.<%= SmartListing.config.classes(:main) %>').smart_listing()
379
- $('.<%= SmartListing.config.classes(:controls) %>').smart_listing_controls()
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