livelist-rails 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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;