livelist-rails 0.0.10 → 0.0.11

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.
@@ -4,55 +4,45 @@ class window.Utilities
4
4
 
5
5
  class window.LiveList extends Utilities
6
6
  constructor: (options) ->
7
- @globalOptions.listSelector = options.list.renderTo
8
- @globalOptions.eventName = "livelist:#{options.global.resourceName}"
9
- @globalOptions.urlPrefix = "/#{options.global.resourceName}"
10
-
11
- @setOptions(options.global, @globalOptions)
12
-
13
- @search = new Search(@globalOptions, options.search)
14
- @filters = new Filters(@globalOptions, options.filters)
15
- @pagination = new Pagination(@globalOptions, options.pagination)
16
- @list = new List(@search, @filters, @pagination, @globalOptions, options.list)
17
-
18
- globalOptions:
19
- data: null
20
- resourceName: 'items'
21
- resourceNameSingular: 'item'
7
+ @listSelector = options.list.renderTo
8
+ @resourceName = options.global.resourceName
9
+ @resourceNameSingular = options.global.resourceNameSingular
10
+ @eventName = "livelist:#{@resourceName}"
11
+ @urlPrefix = "/#{@resourceName}"
12
+ @search = new Search(options.search, @)
13
+ @filters = new Filters(options.filters, @)
14
+ @pagination = new Pagination(options.pagination, @)
15
+ @list = new List(options.list, @)
22
16
 
23
17
  class window.List extends Utilities
24
- constructor: (search, filters, pagination, globalOptions, options = {}) ->
25
- @data = globalOptions.data
18
+ constructor: (options, livelist) ->
26
19
  @fetchRequest = null
27
- @search = search
28
- @filters = filters
29
- @pagination = pagination
20
+ @livelist = livelist
30
21
 
31
- @setOptions(globalOptions)
32
- @listTemplate = "{{##{@resourceName}}}{{>#{@resourceNameSingular}}}{{/#{@resourceName}}}"
22
+ @listTemplate = "{{##{@livelist.resourceName}}}{{>#{@livelist.resourceNameSingular}}}{{/#{@livelist.resourceName}}}"
33
23
  @listItemTemplate = '<li>{{id}}</li>'
34
24
  @fetchingIndicationClass = 'updating'
35
- @setOptions(options)
25
+ @renderTo = "ul##{@livelist.resourceName}"
36
26
 
37
- $(@renderTo).bind(@eventName, (event, params) => @fetch(presets: null, page: params?.page))
27
+ @setOptions(options)
38
28
 
39
- presets = @filters.presets()
40
- @fetch(presets: presets)
29
+ $(@renderTo).bind(@livelist.eventName, (event, params) => @fetch(presets: null, page: params?.page))
30
+ @fetch(presets: @livelist.filters.getPresets())
41
31
 
42
32
  displayFetchingIndication: => $(@renderTo).addClass(@fetchingIndicationClass)
43
33
  removeFetchingIndication: => $(@renderTo).removeClass(@fetchingIndicationClass)
44
34
 
45
35
  renderIndex: (data, textStatus, jqXHR) =>
46
- @data = data
36
+ @livelist.data = data
47
37
  @render()
48
- @pagination.render(@data)
49
- @filters.render(@data)
38
+ @livelist.pagination.render(@livelist.data)
39
+ @livelist.filters.render(@livelist.data)
50
40
 
51
41
  fetch: (options) ->
52
42
  @fetchRequest.abort() if @fetchRequest
53
- searchTerm = @search.searchTerm()
43
+ searchTerm = @livelist.search.searchTerm()
54
44
  params = {}
55
- params.filters = @filters.setPresets(options.presets)
45
+ params.filters = @livelist.filters.setPresets(options.presets)
56
46
 
57
47
  if searchTerm
58
48
  params.q = searchTerm
@@ -60,37 +50,38 @@ class window.List extends Utilities
60
50
  params.page = options.page
61
51
 
62
52
  @fetchRequest = $.ajax(
63
- url : @urlPrefix
53
+ url : @livelist.urlPrefix
54
+ type : @livelist.httpMethod
64
55
  dataType : 'json'
65
56
  data : params
66
- type : @httpMethod
67
57
  beforeSend : @displayFetchingIndication
68
58
  success : @renderIndex
69
59
  )
70
60
 
71
61
  render: ->
72
62
  partials = {}
73
- partials[@resourceNameSingular] = @listItemTemplate
74
- listHTML = Mustache.to_html(@listTemplate, @data, partials)
63
+ partials[@livelist.resourceNameSingular] = @listItemTemplate
64
+ listHTML = Mustache.to_html(@listTemplate, @livelist.data, partials)
75
65
  $(@renderTo).html( listHTML )
76
66
  @removeFetchingIndication()
77
67
 
78
68
  window.LiveList.version = '0.0.5'
79
69
 
80
70
  class window.Filters extends Utilities
81
- constructor: (globalOptions, options = {}) ->
82
- @setOptions(globalOptions)
71
+ constructor: (options, livelist) ->
72
+ @livelist = livelist
83
73
  @filters = if options.presets then _.keys(options.presets) else []
84
74
  @initializeCookies()
85
75
  @setOptions(options)
86
- $('input.filter_option', @renderTo).live( 'change', => $(@listSelector).trigger(@eventName) )
76
+
77
+ $('input.filter_option', @renderTo).live( 'change', => $(@livelist.listSelector).trigger(@livelist.eventName) )
87
78
  $(@advancedOptionsToggleSelector).click(@handleAdvancedOptionsClick)
88
79
 
89
80
  initializeCookies: ->
90
81
  if jQuery.cookie && @useCookies && @cookieName
91
82
  @cookieName = 'livelist_filter_presets'
92
83
 
93
- presets: ->
84
+ getPresets: ->
94
85
  cookie = jQuery.cookie(@cookieName) if jQuery.cookie && @useCookies
95
86
  if @useCookies && cookie
96
87
  JSON.parse(cookie)
@@ -101,7 +92,7 @@ class window.Filters extends Utilities
101
92
  filters = {}
102
93
  if jQuery.isEmptyObject(presets)
103
94
  filters = @selections()
104
- @setCookie() if jQuery.cookie
95
+ @setCookie(filters) if jQuery.cookie
105
96
  else
106
97
  filters = presets
107
98
  filters
@@ -151,11 +142,25 @@ class window.Filters extends Utilities
151
142
  )
152
143
  )
153
144
 
145
+ sortOptions: (filters) ->
146
+ _.map( filters, (filter) ->
147
+ filter.options = _.sortBy( filter.options, (option) -> option.name)
148
+ filter
149
+ )
150
+
151
+ sort: (filters) ->
152
+ _.sortBy( filters, (filter) -> filter.name )
153
+
154
154
  render: (data) ->
155
+ #What is this for?
155
156
  @filters = _.pluck( data.filters, 'filter_slug' )
157
+
158
+ @sort(data.filters)
159
+ @sortOptions(data.filters)
160
+
156
161
  filtersHTML = Mustache.to_html(@template, data)
157
162
  $(@renderTo).html( filtersHTML )
158
- if @noFiltersSelected(data) && data[@resourceName].length > 0
163
+ if @noFiltersSelected(data) && data[@livelist.resourceName].length > 0
159
164
  $('input[type="checkbox"]', @renderTo).attr('checked', 'checked')
160
165
 
161
166
 
@@ -164,12 +169,12 @@ class window.Filters extends Utilities
164
169
  $(@renderTo).slideToggle()
165
170
 
166
171
  class window.Pagination extends Utilities
167
- constructor: (globalOptions, options = {}) ->
172
+ constructor: (options, livelist) ->
173
+ @livelist = livelist
168
174
  @pagination = null
169
175
  @maxPages = 30
170
176
 
171
- @setOptions(globalOptions)
172
- @emptyListMessage = "<p>No #{@resourceName} matched your filter criteria</p>"
177
+ @emptyListMessage = "<p>No #{@livelist.resourceName} matched your filter criteria</p>"
173
178
  @setOptions(options)
174
179
 
175
180
  $("#{@renderTo} a").live( 'click', (event) -> event.preventDefault() )
@@ -201,13 +206,13 @@ class window.Pagination extends Utilities
201
206
  '''
202
207
 
203
208
  pagesJSON: (currentPage, totalPages) ->
204
- groupSize = @maxPages / 2
205
- firstPage = if currentPage < groupSize then 1 else currentPage - groupSize
209
+ groupSize = Math.floor(@maxPages / 2)
210
+ firstPage = if currentPage <= groupSize then 1 else currentPage - groupSize
206
211
  previousPage = firstPage + groupSize * 2 - 1
207
212
  lastPage = if previousPage >= totalPages then totalPages else previousPage
208
213
  _.map([firstPage..lastPage], (page) ->
209
214
  page: page
210
- currentPage: -> currentPage is page
215
+ currentPage: currentPage is page
211
216
  )
212
217
 
213
218
  paginationJSON: (pagination) ->
@@ -217,7 +222,7 @@ class window.Pagination extends Utilities
217
222
  currentPage : pagination.current_page
218
223
  nextPage : pagination.next_page
219
224
  previousPage : pagination.previous_page
220
- urlPrefix : @urlPrefix
225
+ urlPrefix : @livelist.urlPrefix
221
226
  pages : @pagesJSON(pagination.current_page, pagination.total_pages)
222
227
  }
223
228
 
@@ -228,11 +233,11 @@ class window.Pagination extends Utilities
228
233
 
229
234
  handlePaginationLinkClick: (event) =>
230
235
  event.preventDefault()
231
- $(@listSelector).trigger(@eventName, {page: $(event.target).data('page')})
236
+ $(@livelist.listSelector).trigger(@livelist.eventName, {page: $(event.target).data('page')})
232
237
 
233
238
  class window.Search extends Utilities
234
- constructor: (globalOptions, options = {}) ->
235
- @setOptions(globalOptions)
239
+ constructor: (options, livelist) ->
240
+ @livelist = livelist
236
241
  @setOptions(options)
237
242
  $(@formSelector).submit( (event) => @handleSearchFormSubmit(event) )
238
243
 
@@ -242,4 +247,4 @@ class window.Search extends Utilities
242
247
 
243
248
  handleSearchFormSubmit: (event) =>
244
249
  event.preventDefault()
245
- $(@listSelector).trigger(@eventName)
250
+ $(@livelist.listSelector).trigger(@livelist.eventName)
@@ -26,22 +26,17 @@
26
26
  __extends(LiveList, _super);
27
27
 
28
28
  function LiveList(options) {
29
- this.globalOptions.listSelector = options.list.renderTo;
30
- this.globalOptions.eventName = "livelist:" + options.global.resourceName;
31
- this.globalOptions.urlPrefix = "/" + options.global.resourceName;
32
- this.setOptions(options.global, this.globalOptions);
33
- this.search = new Search(this.globalOptions, options.search);
34
- this.filters = new Filters(this.globalOptions, options.filters);
35
- this.pagination = new Pagination(this.globalOptions, options.pagination);
36
- this.list = new List(this.search, this.filters, this.pagination, this.globalOptions, options.list);
29
+ this.listSelector = options.list.renderTo;
30
+ this.resourceName = options.global.resourceName;
31
+ this.resourceNameSingular = options.global.resourceNameSingular;
32
+ this.eventName = "livelist:" + this.resourceName;
33
+ this.urlPrefix = "/" + this.resourceName;
34
+ this.search = new Search(options.search, this);
35
+ this.filters = new Filters(options.filters, this);
36
+ this.pagination = new Pagination(options.pagination, this);
37
+ this.list = new List(options.list, this);
37
38
  }
38
39
 
39
- LiveList.prototype.globalOptions = {
40
- data: null,
41
- resourceName: 'items',
42
- resourceNameSingular: 'item'
43
- };
44
-
45
40
  return LiveList;
46
41
 
47
42
  })(Utilities);
@@ -50,32 +45,26 @@
50
45
 
51
46
  __extends(List, _super);
52
47
 
53
- function List(search, filters, pagination, globalOptions, options) {
54
- var presets,
55
- _this = this;
56
- if (options == null) options = {};
48
+ function List(options, livelist) {
57
49
  this.renderIndex = __bind(this.renderIndex, this);
58
50
  this.removeFetchingIndication = __bind(this.removeFetchingIndication, this);
59
51
  this.displayFetchingIndication = __bind(this.displayFetchingIndication, this);
60
- this.data = globalOptions.data;
52
+ var _this = this;
61
53
  this.fetchRequest = null;
62
- this.search = search;
63
- this.filters = filters;
64
- this.pagination = pagination;
65
- this.setOptions(globalOptions);
66
- this.listTemplate = "{{#" + this.resourceName + "}}{{>" + this.resourceNameSingular + "}}{{/" + this.resourceName + "}}";
54
+ this.livelist = livelist;
55
+ this.listTemplate = "{{#" + this.livelist.resourceName + "}}{{>" + this.livelist.resourceNameSingular + "}}{{/" + this.livelist.resourceName + "}}";
67
56
  this.listItemTemplate = '<li>{{id}}</li>';
68
57
  this.fetchingIndicationClass = 'updating';
58
+ this.renderTo = "ul#" + this.livelist.resourceName;
69
59
  this.setOptions(options);
70
- $(this.renderTo).bind(this.eventName, function(event, params) {
60
+ $(this.renderTo).bind(this.livelist.eventName, function(event, params) {
71
61
  return _this.fetch({
72
62
  presets: null,
73
63
  page: params != null ? params.page : void 0
74
64
  });
75
65
  });
76
- presets = this.filters.presets();
77
66
  this.fetch({
78
- presets: presets
67
+ presets: this.livelist.filters.getPresets()
79
68
  });
80
69
  }
81
70
 
@@ -88,25 +77,25 @@
88
77
  };
89
78
 
90
79
  List.prototype.renderIndex = function(data, textStatus, jqXHR) {
91
- this.data = data;
80
+ this.livelist.data = data;
92
81
  this.render();
93
- this.pagination.render(this.data);
94
- return this.filters.render(this.data);
82
+ this.livelist.pagination.render(this.livelist.data);
83
+ return this.livelist.filters.render(this.livelist.data);
95
84
  };
96
85
 
97
86
  List.prototype.fetch = function(options) {
98
87
  var params, searchTerm;
99
88
  if (this.fetchRequest) this.fetchRequest.abort();
100
- searchTerm = this.search.searchTerm();
89
+ searchTerm = this.livelist.search.searchTerm();
101
90
  params = {};
102
- params.filters = this.filters.setPresets(options.presets);
91
+ params.filters = this.livelist.filters.setPresets(options.presets);
103
92
  if (searchTerm) params.q = searchTerm;
104
93
  if (options.page) params.page = options.page;
105
94
  return this.fetchRequest = $.ajax({
106
- url: this.urlPrefix,
95
+ url: this.livelist.urlPrefix,
96
+ type: this.livelist.httpMethod,
107
97
  dataType: 'json',
108
98
  data: params,
109
- type: this.httpMethod,
110
99
  beforeSend: this.displayFetchingIndication,
111
100
  success: this.renderIndex
112
101
  });
@@ -115,8 +104,8 @@
115
104
  List.prototype.render = function() {
116
105
  var listHTML, partials;
117
106
  partials = {};
118
- partials[this.resourceNameSingular] = this.listItemTemplate;
119
- listHTML = Mustache.to_html(this.listTemplate, this.data, partials);
107
+ partials[this.livelist.resourceNameSingular] = this.listItemTemplate;
108
+ listHTML = Mustache.to_html(this.listTemplate, this.livelist.data, partials);
120
109
  $(this.renderTo).html(listHTML);
121
110
  return this.removeFetchingIndication();
122
111
  };
@@ -131,16 +120,15 @@
131
120
 
132
121
  __extends(Filters, _super);
133
122
 
134
- function Filters(globalOptions, options) {
135
- var _this = this;
136
- if (options == null) options = {};
123
+ function Filters(options, livelist) {
137
124
  this.handleAdvancedOptionsClick = __bind(this.handleAdvancedOptionsClick, this);
138
- this.setOptions(globalOptions);
125
+ var _this = this;
126
+ this.livelist = livelist;
139
127
  this.filters = options.presets ? _.keys(options.presets) : [];
140
128
  this.initializeCookies();
141
129
  this.setOptions(options);
142
130
  $('input.filter_option', this.renderTo).live('change', function() {
143
- return $(_this.listSelector).trigger(_this.eventName);
131
+ return $(_this.livelist.listSelector).trigger(_this.livelist.eventName);
144
132
  });
145
133
  $(this.advancedOptionsToggleSelector).click(this.handleAdvancedOptionsClick);
146
134
  }
@@ -151,7 +139,7 @@
151
139
  }
152
140
  };
153
141
 
154
- Filters.prototype.presets = function() {
142
+ Filters.prototype.getPresets = function() {
155
143
  var cookie;
156
144
  if (jQuery.cookie && this.useCookies) {
157
145
  cookie = jQuery.cookie(this.cookieName);
@@ -168,7 +156,7 @@
168
156
  filters = {};
169
157
  if (jQuery.isEmptyObject(presets)) {
170
158
  filters = this.selections();
171
- if (jQuery.cookie) this.setCookie();
159
+ if (jQuery.cookie) this.setCookie(filters);
172
160
  } else {
173
161
  filters = presets;
174
162
  }
@@ -201,12 +189,29 @@
201
189
  });
202
190
  };
203
191
 
192
+ Filters.prototype.sortOptions = function(filters) {
193
+ return _.map(filters, function(filter) {
194
+ filter.options = _.sortBy(filter.options, function(option) {
195
+ return option.name;
196
+ });
197
+ return filter;
198
+ });
199
+ };
200
+
201
+ Filters.prototype.sort = function(filters) {
202
+ return _.sortBy(filters, function(filter) {
203
+ return filter.name;
204
+ });
205
+ };
206
+
204
207
  Filters.prototype.render = function(data) {
205
208
  var filtersHTML;
206
209
  this.filters = _.pluck(data.filters, 'filter_slug');
210
+ this.sort(data.filters);
211
+ this.sortOptions(data.filters);
207
212
  filtersHTML = Mustache.to_html(this.template, data);
208
213
  $(this.renderTo).html(filtersHTML);
209
- if (this.noFiltersSelected(data) && data[this.resourceName].length > 0) {
214
+ if (this.noFiltersSelected(data) && data[this.livelist.resourceName].length > 0) {
210
215
  return $('input[type="checkbox"]', this.renderTo).attr('checked', 'checked');
211
216
  }
212
217
  };
@@ -224,13 +229,11 @@
224
229
 
225
230
  __extends(Pagination, _super);
226
231
 
227
- function Pagination(globalOptions, options) {
228
- if (options == null) options = {};
229
- this.handlePaginationLinkClick = __bind(this.handlePaginationLinkClick, this);
232
+ function Pagination(options, livelist) {
233
+ this.handlePaginationLinkClick = __bind(this.handlePaginationLinkClick, this); this.livelist = livelist;
230
234
  this.pagination = null;
231
235
  this.maxPages = 30;
232
- this.setOptions(globalOptions);
233
- this.emptyListMessage = "<p>No " + this.resourceName + " matched your filter criteria</p>";
236
+ this.emptyListMessage = "<p>No " + this.livelist.resourceName + " matched your filter criteria</p>";
234
237
  this.setOptions(options);
235
238
  $("" + this.renderTo + " a").live('click', function(event) {
236
239
  return event.preventDefault();
@@ -242,8 +245,8 @@
242
245
 
243
246
  Pagination.prototype.pagesJSON = function(currentPage, totalPages) {
244
247
  var firstPage, groupSize, lastPage, previousPage, _i, _results;
245
- groupSize = this.maxPages / 2;
246
- firstPage = currentPage < groupSize ? 1 : currentPage - groupSize;
248
+ groupSize = Math.floor(this.maxPages / 2);
249
+ firstPage = currentPage <= groupSize ? 1 : currentPage - groupSize;
247
250
  previousPage = firstPage + groupSize * 2 - 1;
248
251
  lastPage = previousPage >= totalPages ? totalPages : previousPage;
249
252
  return _.map((function() {
@@ -253,9 +256,7 @@
253
256
  }).apply(this), function(page) {
254
257
  return {
255
258
  page: page,
256
- currentPage: function() {
257
- return currentPage === page;
258
- }
259
+ currentPage: currentPage === page
259
260
  };
260
261
  });
261
262
  };
@@ -267,7 +268,7 @@
267
268
  currentPage: pagination.current_page,
268
269
  nextPage: pagination.next_page,
269
270
  previousPage: pagination.previous_page,
270
- urlPrefix: this.urlPrefix,
271
+ urlPrefix: this.livelist.urlPrefix,
271
272
  pages: this.pagesJSON(pagination.current_page, pagination.total_pages)
272
273
  };
273
274
  };
@@ -281,7 +282,7 @@
281
282
 
282
283
  Pagination.prototype.handlePaginationLinkClick = function(event) {
283
284
  event.preventDefault();
284
- return $(this.listSelector).trigger(this.eventName, {
285
+ return $(this.livelist.listSelector).trigger(this.livelist.eventName, {
285
286
  page: $(event.target).data('page')
286
287
  });
287
288
  };
@@ -294,11 +295,10 @@
294
295
 
295
296
  __extends(Search, _super);
296
297
 
297
- function Search(globalOptions, options) {
298
- var _this = this;
299
- if (options == null) options = {};
298
+ function Search(options, livelist) {
300
299
  this.handleSearchFormSubmit = __bind(this.handleSearchFormSubmit, this);
301
- this.setOptions(globalOptions);
300
+ var _this = this;
301
+ this.livelist = livelist;
302
302
  this.setOptions(options);
303
303
  $(this.formSelector).submit(function(event) {
304
304
  return _this.handleSearchFormSubmit(event);
@@ -317,7 +317,7 @@
317
317
 
318
318
  Search.prototype.handleSearchFormSubmit = function(event) {
319
319
  event.preventDefault();
320
- return $(this.listSelector).trigger(this.eventName);
320
+ return $(this.livelist.listSelector).trigger(this.livelist.eventName);
321
321
  };
322
322
 
323
323
  return Search;