caboose-cms 0.5.5 → 0.5.6

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OThhZmNiZGRmMDU2M2ZjN2ZmOGQyNTljYjk2NGVhZTcwNGQzYzU2MQ==
4
+ YjM5NDdjM2NhOTc3MzhjZDk1NDI3NTYwZWRmNDAxZGEzNGUwYzJkZQ==
5
5
  data.tar.gz: !binary |-
6
- NDdjNGEyYWZjMzk1MjI3ZTc2MWFlMmQ2OTc5NmY4YjkzYmEzMzk1OA==
6
+ NDUyMTQxN2VkYTYyMGQwYTJhM2E5MWUwZTRmNmM3ZjQ2MDQ0MDk2Ng==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- NDU3NzE3ZDZlZjJhNWE5Y2FkNjVkNjI4NTUyMjg4YmJkMmMwYjk2ZjIwMmU2
10
- NWUxODA0ODRkY2U1N2U4YWI1YWU3NzU4MjRlYWVkODFiZDZlMjZmZmQ0ZDc3
11
- MTgyYWRkNTE3ZWRjYmNiNGRhZTZhZDEwZTAwMzgwYmM0ZWMxNDI=
9
+ ZjljMzZmMDZlYzEwMjJhYWUzZWY3ZmI2NDVmZWQxYTI2MjkzMWNmYmI2OWE0
10
+ YmY2ZmVlMjg5YzIzNDg1MmNlZjZjMWRmYzUyNjc5ZGZmOWI2NjRhMzYwNjNl
11
+ ZjdkYjZhMjAyZDBjNGY0M2NjOTE1YWExOWY1OTNiZGE0ZDI5MjE=
12
12
  data.tar.gz: !binary |-
13
- OWNlOTNiNDBkNDhiZmFkYjdhZDExZWU3MTMzNjY2NjA2NWU1NzBmOTc1M2Zl
14
- YWIyOTI2M2NiNDkyMDc1MmI1MTljMmEyMjk0NDg1YjVjYzM5OWJjYzExMGM1
15
- OTgzZDg4OWI0Y2RjYzI1OWM3NTllNDdhMzI1MmQ3MzMxYTFhZjg=
13
+ NDllYmUzMDlmZWIxNjc5NGQ2OTgwNzI1YjFjNzk3ZmVhZTkyZDJlYmM5Yjc3
14
+ ZmU0YTc0OGQxMTgwNTM0YTU4NDNiZWFhOWQwM2UwZjlkNjcxOTUyYjAwMjM1
15
+ NGJiNDhhNjY5ZWRjNGM5OWRhMTY3ODc0YjEyM2FmZmI4YWY1MGY=
@@ -16,6 +16,7 @@ IndexTable.prototype = {
16
16
 
17
17
  // Where to get model json data
18
18
  refresh_url: false,
19
+ refresh_single_url: false,
19
20
 
20
21
  // Where to send bulk updates
21
22
  bulk_update_url: false,
@@ -71,8 +72,8 @@ IndexTable.prototype = {
71
72
  //============================================================================
72
73
 
73
74
  models: [],
74
- model_ids: [],
75
- quick_edit_field: false, // The field currently being edited
75
+ model_ids: [],
76
+ quick_edit_model_id: false, // The id of the model currently being edited
76
77
  refresh_count: 0,
77
78
  pager: {
78
79
  options: { page: 1 },
@@ -84,18 +85,39 @@ IndexTable.prototype = {
84
85
  this[thing] = params[thing];
85
86
 
86
87
  var that = this;
87
- if (!this.refresh_url ) this.refresh_url = this.base_url + '/json';
88
- if (!this.bulk_update_url ) this.bulk_update_url = this.base_url + '/bulk';
89
- if (!this.bulk_delete_url ) this.bulk_delete_url = this.base_url + '/bulk';
90
- if (!this.add_url ) this.add_url = this.base_url;
91
- if (!this.update_url ) this.update_url = function(model_id) { return this.base_url + '/' + model_id; };
92
- if (!this.duplicate_url ) this.duplicate_url = function(model_id) { return this.base_url + '/' + model_id + '/duplicate'; };
93
- if (!this.row_click_handler ) this.row_click_handler = function(model_id) { window.location = this.base_url + '/' + model_id; };
88
+ if (!this.refresh_url ) this.refresh_url = this.base_url + '/json';
89
+ if (!this.bulk_update_url ) this.bulk_update_url = this.base_url + '/bulk';
90
+ if (!this.bulk_delete_url ) this.bulk_delete_url = this.base_url + '/bulk';
91
+ if (!this.add_url ) this.add_url = this.base_url;
92
+ if (!this.update_url ) this.update_url = function(model_id) { return that.base_url + '/' + model_id; };
93
+ if (!this.duplicate_url ) this.duplicate_url = function(model_id) { return that.base_url + '/' + model_id + '/duplicate'; };
94
+ if (!this.refresh_single_url) this.refresh_single_url = function(model_id) { return that.base_url + '/' + model_id + '/json'; };
95
+ if (!this.row_click_handler ) this.row_click_handler = function(model_id, e) {
96
+ if (that.quick_edit_model_id == model_id)
97
+ {
98
+ if ($(e.target).prop('tagName') == 'TD')
99
+ that.quick_edit_model_id = false;
100
+ else
101
+ return;
102
+ }
103
+ else
104
+ that.quick_edit_model_id = model_id;
105
+ that.print();
106
+ };
107
+ this.init_fields();
94
108
 
95
109
  $(window).on('hashchange', function() { that.refresh(); });
96
110
  this.refresh();
97
111
  },
98
112
 
113
+ init_fields: function()
114
+ {
115
+ var that = this;
116
+ $.each(this.fields, function(i, f) {
117
+ if (f.editable == null) f.editable = true;
118
+ });
119
+ },
120
+
99
121
  parse_querystring: function()
100
122
  {
101
123
  var b = {};
@@ -179,6 +201,25 @@ IndexTable.prototype = {
179
201
  });
180
202
  },
181
203
 
204
+ refresh_single: function(model_id)
205
+ {
206
+ var that = this;
207
+ $.ajax({
208
+ url: that.refresh_single_url(model_id),
209
+ type: 'get',
210
+ success: function(resp) {
211
+ for (var i=0; i<that.models.length; i++)
212
+ {
213
+ if (that.models[i].id == model_id)
214
+ {
215
+ that.models[i] = resp;
216
+ break;
217
+ }
218
+ }
219
+ }
220
+ });
221
+ },
222
+
182
223
  print: function()
183
224
  {
184
225
  var that = this;
@@ -226,28 +267,26 @@ IndexTable.prototype = {
226
267
  .append(controls);
227
268
  $('#' + that.container + '_columns').hide();
228
269
  }
229
-
230
- if (that.quick_edit_field)
231
- {
232
- $.each(that.models, function(i, m) {
233
- $.each(that.fields, function(j, field) {
234
- if (field.show && field.name == that.quick_edit_field)
235
- {
236
- var attrib = $.extend({}, field);
237
- attrib['value'] = field.value(m);
238
- attrib['fixed_placeholder'] = false;
239
- //if (field.text)
240
- // attrib['text'] = field.text(m);
241
- new ModelBinder({
242
- name: 'Model',
243
- id: m.id,
244
- update_url: that.update_url(m.id),
245
- authenticity_token: that.form_authenticity_token,
246
- attributes: [attrib]
247
- });
248
- }
249
- });
250
- });
270
+
271
+ if (that.quick_edit_model_id)
272
+ {
273
+ var m = that.model_for_id(that.quick_edit_model_id);
274
+ $.each(that.fields, function(j, field) {
275
+ if (field.show && field.editable)
276
+ {
277
+ var attrib = $.extend({}, field);
278
+ attrib['value'] = field.value(m);
279
+ attrib['fixed_placeholder'] = false;
280
+ attrib['after_update'] = function() { that.refresh_single(m.id); };
281
+ new ModelBinder({
282
+ name: 'Model',
283
+ id: m.id,
284
+ update_url: that.update_url(m.id),
285
+ authenticity_token: that.form_authenticity_token,
286
+ attributes: [attrib]
287
+ });
288
+ }
289
+ });
251
290
  }
252
291
  },
253
292
 
@@ -262,39 +301,27 @@ IndexTable.prototype = {
262
301
  $.each(this.fields, function(i, field) {
263
302
  if (field.show)
264
303
  {
265
- var s = field.sort ? field.sort : field.name;
266
- console.log("field.name = " + field.name);
267
- console.log("that.pager.options.sort = " + that.pager.options.sort);
268
- console.log("that.pager.options.desc = " + that.pager.options.desc);
269
- console.log("------------------------------");
304
+ var s = field.sort ? field.sort : field.name;
270
305
  var arrow = that.pager.options.sort == s ? (parseInt(that.pager.options.desc) == 1 ? ' &uarr;' : ' &darr;') : '';
271
306
  var link = that.pager_hash({
272
307
  sort: s,
273
308
  desc: (that.pager.options.sort == s ? (parseInt(that.pager.options.desc) == 1 ? '0' : '1') : '0')
274
309
  });
275
310
 
276
- var input = $('<input/>').attr('type', 'checkbox').attr('id', 'quick_edit_' + field.name).val(field.name)
277
- .change(function() {
278
- that.quick_edit_field = $(this).prop('checked') ? $(this).val() : false;
279
- that.refresh();
280
- });
281
- if (field.name == that.quick_edit_field)
282
- input.prop('checked', 'true');
311
+ //var input = $('<input/>').attr('type', 'checkbox').attr('id', 'quick_edit_' + field.name).val(field.name)
312
+ // .change(function() {
313
+ // that.quick_edit_field = $(this).prop('checked') ? $(this).val() : false;
314
+ // that.refresh();
315
+ // });
316
+ //if (field.name == that.quick_edit_field)
317
+ // input.prop('checked', 'true');
283
318
  tr.append($('<th/>')
284
- .append(input).append('<br/>')
319
+ //.append(input).append('<br/>')
285
320
  .append($('<a/>')
286
321
  .attr('id', 'quick_edit_' + field.name).val(field.name)
287
322
  .attr('href', link)
288
323
  .data('sort', s)
289
- .html(field.nice_name + arrow)
290
- //.mousedown(function(e) {
291
- // if (e.which == 3) // right click
292
- // {
293
- // var field_name = $(this).attr('id').replace('quick_edit_', '');
294
- // that.quick_edit_field = that.quick_edit_field == field_name ? false : field_name;
295
- // that.refresh();
296
- // }
297
- //})
324
+ .html(field.nice_name + arrow)
298
325
  )
299
326
  );
300
327
  }
@@ -328,21 +355,17 @@ IndexTable.prototype = {
328
355
  if (that.model_ids.indexOf(m.id) > -1)
329
356
  checkbox.prop('checked', 'true');
330
357
  tr.append($('<td/>').append(checkbox));
331
- }
332
-
333
- if (!that.quick_edit_field)
334
- {
335
- tr.click(function(e) {
336
- var model_id = $(this).attr('id').replace('model_row_', '');
337
- that.row_click_handler(model_id);
338
- });
339
- }
340
-
358
+ }
359
+ tr.click(function(e) {
360
+ var model_id = $(this).attr('id').replace('model_row_', '');
361
+ that.row_click_handler(model_id, e);
362
+ });
363
+
341
364
  $.each(that.fields, function(j, field) {
342
365
  if (field.show)
343
366
  {
344
367
  var td = $('<td/>');
345
- if (that.quick_edit_field == field.name)
368
+ if (field.editable && that.quick_edit_model_id == m.id)
346
369
  td.append($('<div/>').attr('id', 'model_' + m.id + '_' + field.name));
347
370
  else
348
371
  td.html(field.text ? field.text(m) : field.value(m));
@@ -0,0 +1,709 @@
1
+
2
+ var IndexTable = function(params) { this.init(params); }
3
+ IndexTable.prototype = {
4
+
5
+ //============================================================================
6
+ // Required parameters
7
+ //============================================================================
8
+
9
+ form_authenticity_token: false,
10
+
11
+ // Container for the table
12
+ container: 'models',
13
+
14
+ // Base URL used for default refresh/update/delete/bulk URLs
15
+ base_url: false,
16
+
17
+ // Where to get model json data
18
+ refresh_url: false,
19
+ refresh_single_url: false,
20
+
21
+ // Where to send bulk updates
22
+ bulk_update_url: false,
23
+
24
+ // Where to send bulk deletes
25
+ bulk_delete_url: false,
26
+
27
+ // Where to send normal updates
28
+ // Example: function(model_id) { return '/admin/models/' + model_id; }
29
+ update_url: false,
30
+
31
+ // Where to send duplicate calls
32
+ // Example: function(model_id) { return '/admin/models/' + model_id + '/duplicate' },
33
+ duplicate_url: false,
34
+
35
+ // Where to post new models
36
+ add_url: false,
37
+
38
+ // What to do when a row is clicked
39
+ // Example: function (model_id) { return '/admin/models/' + model_id; }
40
+ row_click_handler: false,
41
+
42
+ // Array of fields you want to show in the table (given as model binder attributes with additional text and value functions)
43
+ // [{
44
+ // show: true,
45
+ // bulk_edit: true,
46
+ // name: 'title',
47
+ // nice_name: 'Title',
48
+ // type: 'text',
49
+ // text: function(obj) { return obj.title; },
50
+ // value: function(obj) { return obj.id; },
51
+ // options_url: '/admin/dogs/collar-options'
52
+ // fixed_placeholder: false,
53
+ // width: 200,
54
+ // }]
55
+ fields: [],
56
+
57
+ // The post/get in the original request
58
+ post_get: false,
59
+
60
+ allow_bulk_edit: true,
61
+ allow_bulk_delete: true,
62
+ allow_duplicate: true,
63
+
64
+ no_models_text: "There are no models right now.",
65
+ new_model_text: 'New',
66
+ new_model_fields: [
67
+ { name: 'name', nice_name: 'Name', type: 'text', width: 400 }
68
+ ],
69
+
70
+ //============================================================================
71
+ // End of required parameters
72
+ //============================================================================
73
+
74
+ models: [],
75
+ model_ids: [],
76
+ quick_edit_field: false, // The field currently being edited
77
+ quick_edit_model_id: false, // The id of the model currently being edited
78
+ refresh_count: 0,
79
+ pager: {
80
+ options: { page: 1 },
81
+ params: {}
82
+ },
83
+
84
+ init: function(params) {
85
+ for (var thing in params)
86
+ this[thing] = params[thing];
87
+
88
+ var that = this;
89
+ if (!this.refresh_url ) this.refresh_url = this.base_url + '/json';
90
+ if (!this.bulk_update_url ) this.bulk_update_url = this.base_url + '/bulk';
91
+ if (!this.bulk_delete_url ) this.bulk_delete_url = this.base_url + '/bulk';
92
+ if (!this.add_url ) this.add_url = this.base_url;
93
+ if (!this.update_url ) this.update_url = function(model_id) { return that.base_url + '/' + model_id; };
94
+ if (!this.duplicate_url ) this.duplicate_url = function(model_id) { return that.base_url + '/' + model_id + '/duplicate'; };
95
+ if (!this.refresh_single_url) this.refresh_single_url = function(model_id) { return that.base_url + '/' + model_id + '/json'; };
96
+ if (!this.row_click_handler ) this.row_click_handler = function(model_id, e) {
97
+ if (that.quick_edit_model_id == model_id)
98
+ {
99
+ if ($(e.target).prop('tagName') == 'TD')
100
+ that.quick_edit_model_id = false;
101
+ else
102
+ return;
103
+ }
104
+ else
105
+ that.quick_edit_model_id = model_id;
106
+ that.print();
107
+ };
108
+ this.init_fields();
109
+
110
+ $(window).on('hashchange', function() { that.refresh(); });
111
+ this.refresh();
112
+ },
113
+
114
+ init_fields: function()
115
+ {
116
+ var that = this;
117
+ $.each(this.fields, function(i, f) {
118
+ if (f.editable == null) f.editable = true;
119
+ });
120
+ },
121
+
122
+ parse_querystring: function()
123
+ {
124
+ var b = {};
125
+
126
+ // Get the hash values
127
+ var a = window.location.hash;
128
+ if (a.length > 0)
129
+ {
130
+ a = a.substr(1).split('&');
131
+ for (var i=0; i<a.length; ++i)
132
+ {
133
+ var p = a[i].split('=', 2);
134
+ if (p.length == 1) b[p[0]] = "";
135
+ else b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
136
+ }
137
+ }
138
+
139
+ // Get the querystring values
140
+ a = window.location.search;
141
+ if (a.length > 0)
142
+ {
143
+ a = a.substr(1).split('&');
144
+ for (var i=0; i<a.length; ++i)
145
+ {
146
+ var p = a[i].split('=', 2);
147
+ if (p.length == 1) b[p[0]] = "";
148
+ else b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
149
+ }
150
+ }
151
+
152
+ // Set both hash and querystring values in the pager
153
+ for (var i in b)
154
+ {
155
+ if (i == 'sort' || i == 'desc' || i == 'page')
156
+ this.pager.options[i] = b[i];
157
+ else
158
+ this.pager.params[i] = b[i];
159
+ }
160
+
161
+ // If there's a querystring, then redirect to hash
162
+ //if (window.location.search.length > 0)
163
+ //{
164
+ // //alert('Testing');
165
+ // //window.location = this.pager_url({ base_url: window.location.pathname }).replace('?', '#');
166
+ //}
167
+ },
168
+
169
+ refresh: function()
170
+ {
171
+ this.pager = { options: { page: 1 }, params: {}};
172
+ this.parse_querystring();
173
+
174
+ var that = this;
175
+ var $el = $('#' + this.container + '_columns').length > 0 ? $('#' + this.container + '_table_container') : $('#' + this.container);
176
+ $el.html("<p class='loading'>Refreshing...</p>");
177
+ $.ajax({
178
+ url: that.refresh_url,
179
+ type: 'get',
180
+ data: that.pager_params(),
181
+ success: function(resp) {
182
+ for (var thing in resp['pager'])
183
+ that.pager[thing] = resp['pager'][thing];
184
+ that.models = resp['models'];
185
+ for (var i=0; i<that.models.length; i++)
186
+ {
187
+ var m = that.models[i];
188
+ m.id = parseInt(m.id);
189
+ }
190
+ that.print();
191
+
192
+ // Set the history state
193
+ //var qs = that.pager_querystring();
194
+ //if (that.refresh_count > 0 && qs != window.location.hash)
195
+ //{
196
+ // if(history.pushState) history.pushState(null, null, '#' + qs);
197
+ // else location.hash = '#' + qs;
198
+ //}
199
+ that.refresh_count += 1;
200
+ },
201
+ error: function() { $('#' + this.container).html("<p class='note error'>Error retrieving data.</p>"); }
202
+ });
203
+ },
204
+
205
+ refresh_single: function(model_id)
206
+ {
207
+ var that = this;
208
+ $.ajax({
209
+ url: that.refresh_single_url(model_id),
210
+ type: 'get',
211
+ success: function(resp) {
212
+ for (var i=0; i<that.models.length; i++)
213
+ {
214
+ if (that.models[i].id == model_id)
215
+ {
216
+ that.models[i] = resp;
217
+ break;
218
+ }
219
+ }
220
+ }
221
+ });
222
+ },
223
+
224
+ print: function()
225
+ {
226
+ var that = this;
227
+
228
+ if (that.models == null || that.models.length == 0)
229
+ {
230
+ $('#' + that.container).empty()
231
+ .append($('<p/>').append(that.new_model_link()))
232
+ .append($('<div/>').attr('id', that.container + '_new_form_container'))
233
+ .append($('<p/>').append(that.no_models_text));
234
+ return;
235
+ }
236
+
237
+ var tbody = $('<tbody/>').append(this.table_headers());
238
+ $.each(that.models, function(i, m) {
239
+ tbody.append(that.table_row(m));
240
+ });
241
+ var table = $('<table/>').addClass('data').css('margin-bottom', '10px').append(tbody);
242
+ var pager_div = this.pager_div();
243
+
244
+ if ($('#' + this.container + '_columns').length > 0)
245
+ {
246
+ $('#' + this.container + '_table_container').empty().append(table);
247
+ $('#' + this.container + '_pager').empty().append(pager_div);
248
+ $('#' + this.container + '_new_form_container').empty();
249
+ }
250
+ else
251
+ {
252
+ var columns = this.column_checkboxes();
253
+ var controls = $('<p/>');
254
+ if (this.allow_bulk_edit ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_edit' ).val('Bulk Edit' ).click(function(e) { that.bulk_edit(); })).append(' ');
255
+ if (this.allow_bulk_delete ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_bulk_delete').val('Bulk Delete').click(function(e) { that.bulk_delete(); })).append(' ');
256
+ if (this.allow_duplicate ) controls.append($('<input/>').attr('type', 'button').attr('id', this.container + '_duplicate' ).val('Duplicate' ).click(function(e) { that.duplicate(); }));
257
+
258
+ $('#' + that.container).empty()
259
+ .append($('<p/>')
260
+ .append(that.new_model_link()).append(' | ')
261
+ .append($('<a/>').attr('href', '#').html('Show/Hide Columns').click(function(e) { e.preventDefault(); $('#' + that.container + '_columns').slideToggle(); }))
262
+ )
263
+ .append($('<div/>').attr('id', that.container + '_new_form_container'))
264
+ .append($('<div/>').attr('id', that.container + '_columns').append(columns))
265
+ .append($('<div/>').attr('id', that.container + '_table_container').append(table))
266
+ .append($('<div/>').attr('id', that.container + '_pager').append(pager_div))
267
+ .append($('<div/>').attr('id', that.container + '_message'))
268
+ .append(controls);
269
+ $('#' + that.container + '_columns').hide();
270
+ }
271
+
272
+ if (that.quick_edit_field)
273
+ {
274
+ $.each(that.models, function(i, m) {
275
+ $.each(that.fields, function(j, field) {
276
+ if (field.show && field.name == that.quick_edit_field)
277
+ {
278
+ var attrib = $.extend({}, field);
279
+ attrib['value'] = field.value(m);
280
+ attrib['fixed_placeholder'] = false;
281
+ //if (field.text)
282
+ // attrib['text'] = field.text(m);
283
+ new ModelBinder({
284
+ name: 'Model',
285
+ id: m.id,
286
+ update_url: that.update_url(m.id),
287
+ authenticity_token: that.form_authenticity_token,
288
+ attributes: [attrib]
289
+ });
290
+ }
291
+ });
292
+ });
293
+ }
294
+ if (that.quick_edit_model_id)
295
+ {
296
+ var m = that.model_for_id(that.quick_edit_model_id);
297
+ $.each(that.fields, function(j, field) {
298
+ if (field.show && field.editable)
299
+ {
300
+ var attrib = $.extend({}, field);
301
+ attrib['value'] = field.value(m);
302
+ attrib['fixed_placeholder'] = false;
303
+ attrib['after_update'] = function() { that.refresh_single(m.id); };
304
+ new ModelBinder({
305
+ name: 'Model',
306
+ id: m.id,
307
+ update_url: that.update_url(m.id),
308
+ authenticity_token: that.form_authenticity_token,
309
+ attributes: [attrib]
310
+ });
311
+ }
312
+ });
313
+ }
314
+ },
315
+
316
+ table_headers: function()
317
+ {
318
+ var that = this;
319
+ var tr = $('<tr/>');
320
+
321
+ if (this.allow_bulk_edit || this.allow_bulk_delete || this.allow_duplicate)
322
+ tr.append($('<th/>').html('&nbsp;'));
323
+
324
+ $.each(this.fields, function(i, field) {
325
+ if (field.show)
326
+ {
327
+ var s = field.sort ? field.sort : field.name;
328
+ var arrow = that.pager.options.sort == s ? (parseInt(that.pager.options.desc) == 1 ? ' &uarr;' : ' &darr;') : '';
329
+ var link = that.pager_hash({
330
+ sort: s,
331
+ desc: (that.pager.options.sort == s ? (parseInt(that.pager.options.desc) == 1 ? '0' : '1') : '0')
332
+ });
333
+
334
+ var input = $('<input/>').attr('type', 'checkbox').attr('id', 'quick_edit_' + field.name).val(field.name)
335
+ .change(function() {
336
+ that.quick_edit_field = $(this).prop('checked') ? $(this).val() : false;
337
+ that.refresh();
338
+ });
339
+ if (field.name == that.quick_edit_field)
340
+ input.prop('checked', 'true');
341
+ tr.append($('<th/>')
342
+ .append(input).append('<br/>')
343
+ .append($('<a/>')
344
+ .attr('id', 'quick_edit_' + field.name).val(field.name)
345
+ .attr('href', link)
346
+ .data('sort', s)
347
+ .html(field.nice_name + arrow)
348
+ )
349
+ );
350
+ }
351
+ });
352
+ return tr;
353
+ },
354
+
355
+ table_row: function(m)
356
+ {
357
+ var that = this;
358
+
359
+ var tr = $('<tr/>').attr('id', 'model_row_' + m.id);
360
+
361
+ if (that.allow_bulk_edit || that.allow_bulk_delete || that.allow_duplicate)
362
+ {
363
+ var checkbox = $('<input/>').attr('type', 'checkbox').attr('id', 'model_' + m.id)
364
+ .click(function(e) {
365
+ e.stopPropagation();
366
+ var model_id = $(this).attr('id').replace('model_', '');
367
+ if (model_id == 'NaN')
368
+ alert("Error: invalid model id.");
369
+ else
370
+ {
371
+ model_id = parseInt(model_id);
372
+ var checked = $(this).prop('checked');
373
+ var i = that.model_ids.indexOf(model_id);
374
+ if (checked && i == -1) that.model_ids.push(model_id);
375
+ if (!checked && i > -1) that.model_ids.splice(i, 1);
376
+ }
377
+ });
378
+ if (that.model_ids.indexOf(m.id) > -1)
379
+ checkbox.prop('checked', 'true');
380
+ tr.append($('<td/>').append(checkbox));
381
+ }
382
+
383
+ if (!that.quick_edit_field)
384
+ {
385
+ tr.click(function(e) {
386
+ var model_id = $(this).attr('id').replace('model_row_', '');
387
+ that.row_click_handler(model_id, e);
388
+ });
389
+ }
390
+
391
+ $.each(that.fields, function(j, field) {
392
+ if (field.show)
393
+ {
394
+ var td = $('<td/>');
395
+ if (field.editable && (that.quick_edit_model_id == m.id || that.quick_edit_field == field.name))
396
+ td.append($('<div/>').attr('id', 'model_' + m.id + '_' + field.name));
397
+ else
398
+ td.html(field.text ? field.text(m) : field.value(m));
399
+ tr.append(td);
400
+ }
401
+ });
402
+ return tr;
403
+ },
404
+
405
+ column_checkboxes: function()
406
+ {
407
+ var that = this;
408
+ var div = $('<div/>').attr('id', that.container + '_columns');
409
+ $.each(this.fields, function(i, field) {
410
+ var input = $('<input/>')
411
+ .attr('type', 'checkbox')
412
+ .attr('id', 'field_' + field.name)
413
+ .click(function(e) {
414
+ var field_name = $(this).attr('id').replace('field_', '');
415
+ var checked = $(this).prop('checked');
416
+ $.each(that.fields, function(j, f) {
417
+ if (f.name == field_name)
418
+ {
419
+ f.show = checked;
420
+ that.print();
421
+ }
422
+ });
423
+ });
424
+ if (field.show)
425
+ input.prop('checked', 'true');
426
+
427
+ div.append($('<div/>').addClass('label_with_checkbox')
428
+ .append(input)
429
+ .append($('<label/>').attr('for', 'field_' + field.name).html(field.nice_name))
430
+ );
431
+ });
432
+ return div;
433
+ },
434
+
435
+ bulk_edit: function()
436
+ {
437
+ var that = this;
438
+ if (this.model_ids.length == 0)
439
+ {
440
+ $('#message').html("<p class='note error'>Please select at least one row.</p>");
441
+ return;
442
+ }
443
+ var div = $('<div/>')
444
+ .append($('<h2/>').html('Bulk Edit Jobs'))
445
+ .append($('<p/>').html('Any change you make the fields below will apply to all the selected rows.'));
446
+ $.each(this.fields, function(i, field) {
447
+ if (field.bulk_edit == true)
448
+ div.append($('<p/>').append($('<div/>').attr('id', 'bulkmodel_1_' + field.name)));
449
+ });
450
+ div.append($('<input/>').attr('type','button').val('Finished').click(function() { $('#message').empty(); }));
451
+ $('#message').empty().append(div);
452
+
453
+ var params = this.model_ids.map(function(model_id) { return 'model_ids[]=' + model_id; }).join('&');
454
+ var attribs = [];
455
+ $.each(this.fields, function(i, field) {
456
+ if (field.bulk_edit == true)
457
+ {
458
+ var attrib = $.extend({}, field);
459
+ attrib['value'] = '';
460
+ attrib['after_update'] = function() { that.refresh(); };
461
+ attrib['width'] = 600;
462
+ attribs.push(attrib);
463
+ }
464
+ });
465
+
466
+ m = new ModelBinder({
467
+ name: 'BulkModel',
468
+ id: 1,
469
+ update_url: that.bulk_update_url + '?' + params,
470
+ authenticity_token: this.form_authenticity_token,
471
+ attributes: attribs
472
+ });
473
+ },
474
+
475
+ bulk_delete: function(confirm)
476
+ {
477
+ var that = this;
478
+ if (this.model_ids.length == 0)
479
+ {
480
+ $('#message').html("<p class='note error'>Please select at least one row.</p>");
481
+ return;
482
+ }
483
+ if (!confirm)
484
+ {
485
+ var p = $('<p/>').addClass('note').addClass('warning')
486
+ .append('Are you sure you want to delete the selected rows? ')
487
+ .append($('<input/>').attr('type','button').val('Yes').click(function() { that.bulk_delete(true); }))
488
+ .append($('<input/>').attr('type','button').val('No').click(function() { $('#message').empty(); }));
489
+ $('#message').empty().append(p);
490
+ return;
491
+ }
492
+ var params = this.model_ids.map(function(model_id) { return 'model_ids[]=' + model_id; }).join('&');
493
+ $('#' + this.container).html("<p class='loading'>Refreshing...</p>");
494
+ $.ajax({
495
+ url: that.bulk_delete_url,
496
+ type: 'delete',
497
+ data: {
498
+ model_ids: that.model_ids
499
+ },
500
+ success: function(resp) {
501
+ $('#message').empty();
502
+ that.refresh();
503
+ }
504
+ });
505
+ },
506
+
507
+ model_for_id: function(model_id)
508
+ {
509
+ for (var i=0; i<this.models.length; i++)
510
+ if (this.models[i].id == model_id)
511
+ return this.models[i];
512
+ return false;
513
+ },
514
+
515
+ duplicate: function(count)
516
+ {
517
+ var that = this;
518
+ if (this.model_ids.length == 0)
519
+ {
520
+ var p = $('<p/>').addClass('note error').html("Please select a row.");
521
+ $('#message').empty().append(p);
522
+ return;
523
+ }
524
+ if (this.model_ids.length > 1)
525
+ {
526
+ var p = $('<p/>').addClass('note error').html("Please select a single row.");
527
+ $('#message').empty().append(p);
528
+ return;
529
+ }
530
+ if (!count)
531
+ {
532
+ var p = $('<p/>').addClass('note')
533
+ .append('How many times do you want this duplicated?')
534
+ .append($('<input/>').attr('type', 'text').attr('id', 'count').css('width', '50'))
535
+ .append('<br />')
536
+ .append($('<input/>').attr('type', 'button').val('Cancel').click(function(e) { $('#message').empty(); })).append(' ')
537
+ .append($('<input/>').attr('type', 'button').val('Duplicate').click(function(e) { that.duplicate($('#count').val()); return false; }));
538
+ $('#message').empty().append(p);
539
+ return;
540
+ }
541
+ $('#message').html("<p class='loading'>Duplicating...</p>");
542
+ $.ajax({
543
+ url: that.duplicate_url(that.model_ids[0]),
544
+ type: 'post',
545
+ data: { count: count },
546
+ success: function(resp) {
547
+ if (resp.error) $('#message').html("<p class='note error'>" + resp.error + "</p>");
548
+ if (resp.success) { $('#message').empty(); that.refresh(); }
549
+ }
550
+ });
551
+ },
552
+
553
+ pager_div: function(summary)
554
+ {
555
+ var that = this;
556
+ var p = this.pager;
557
+
558
+ // Set default parameter values if not present
559
+ if (!p.options.items_per_page) p.options.items_per_page = 10
560
+ if (!p.options.page) p.options.page = 1
561
+
562
+ var page = parseInt(p.options.page);
563
+
564
+ // Max links to show (must be odd)
565
+ var total_links = 5;
566
+ var prev_page = page - 1;
567
+ var next_page = page + 1;
568
+ var total_pages = Math.ceil(parseFloat(p.options.item_count)/parseFloat(p.options.items_per_page));
569
+ var start = 1;
570
+ var stop = 1;
571
+
572
+ if (total_pages < total_links)
573
+ {
574
+ start = 1;
575
+ stop = total_pages;
576
+ }
577
+ else
578
+ {
579
+ start = page - Math.floor(total_links/2);
580
+ if (start < 1) start = 1;
581
+ stop = start + total_links - 1
582
+
583
+ if (stop > total_pages)
584
+ {
585
+ stop = total_pages;
586
+ start = stop - total_links;
587
+ if (start < 1) start = 1;
588
+ }
589
+ }
590
+
591
+ var div = $('<div/>').addClass('pager');
592
+ if (summary)
593
+ div.append($('<p/>').html("Results: showing page " + page + " of " + total_pages));
594
+
595
+ if (total_pages > 1)
596
+ {
597
+ var div2 = $('<div/>').addClass('page_links');
598
+ if (page > 1)
599
+ div2.append($('<a/>').attr('href', this.pager_hash({ page: prev_page })).html('Previous').click(function(e) { that.hash_click(e, this); }));
600
+ for (i=start; i<=stop; i++)
601
+ {
602
+ if (page != i)
603
+ div2.append($('<a/>').attr('href', this.pager_hash({ page: i })).html(i).click(function(e) { that.hash_click(e, this); }));
604
+ else
605
+ div2.append($('<span/>').addClass('current_page').html(i));
606
+ }
607
+ if (page < total_pages)
608
+ div2.append($('<a/>').attr('href', this.pager_hash({ page: next_page })).html('Next').click(function(e) { that.hash_click(e, this); }));
609
+ div.append(div2);
610
+ }
611
+ return div;
612
+ },
613
+
614
+ hash_click: function(e, el) {
615
+ e.preventDefault();
616
+ e.stopPropagation();
617
+ window.location.hash = $(el).attr('href').substr(1);
618
+ this.refresh();
619
+ },
620
+
621
+ pager_params: function(h)
622
+ {
623
+ var that = this;
624
+ var p = $.extend({}, this.pager.params);
625
+ if (this.pager.options)
626
+ {
627
+ if (this.pager.options.sort) p.sort = this.pager.options.sort;
628
+ if (this.pager.options.desc) p.desc = this.pager.options.desc ? 1 : 0;
629
+ if (this.pager.options.page) p.page = this.pager.options.page;
630
+ }
631
+ if (h)
632
+ {
633
+ for (var i in h)
634
+ {
635
+ //console.log('' + i + ' = ' + h[i]);
636
+ //console.log(typeof(h[i]));
637
+ //console.log('-------------------');
638
+ if (typeof(h[i]) == 'boolean')
639
+ p[i] = h[i] ? 1 : 0;
640
+ else
641
+ p[i] = h[i];
642
+ }
643
+ }
644
+ return p;
645
+ },
646
+
647
+ pager_hash: function(h)
648
+ {
649
+ var p = this.pager_params(h);
650
+ var qs = [];
651
+ $.each(p, function(k,v) { qs.push('' + k + '=' + encodeURIComponent(v)); });
652
+ return '#' + qs.join('&');
653
+ },
654
+
655
+ /****************************************************************************/
656
+
657
+ new_model_link: function()
658
+ {
659
+ var that = this;
660
+ return $('<a/>').attr('href', '#').html(that.new_model_text).click(function(e) { e.preventDefault(); that.new_form(); });
661
+ },
662
+
663
+ new_form: function()
664
+ {
665
+ var that = this;
666
+ if (!$('#' + that.container + '_new_form_container').is(':empty'))
667
+ {
668
+ $('#' + that.container + '_new_form_container').slideUp(function() {
669
+ $('#' + that.container + '_new_form_container').empty();
670
+ });
671
+ return;
672
+ }
673
+
674
+ var form = $('<form/>').attr('id', 'new_form')
675
+ .append($('<input/>').attr('type', 'hidden').attr('name', 'authenticity_token').val(that.form_authenticity_token));
676
+ $.each(this.new_model_fields, function(i, f) {
677
+ form.append($('<p/>').append($('<input/>').attr('type', 'text').attr('name', f.name).attr('placeholder', f.nice_name).css('width', '' + f.width + 'px')));
678
+ });
679
+ form
680
+ .append($('<div/>').attr('id', 'new_message'))
681
+ .append($('<p>')
682
+ .append($('<input/>').attr('type', 'button').val('Cancel').click(function(e) { $('#' + that.container + '_new_form_container').empty(); }))
683
+ .append(' ')
684
+ .append($('<input/>').attr('type', 'submit').val('Add').click(function(e) { that.add_model(); return false; }))
685
+ );
686
+ $('#' + that.container + '_new_form_container').hide().empty().append(
687
+ $('<div/>').addClass('note').css('margin-bottom', '10px')
688
+ .append($('<h2/>').css('margin-top', 0).css('padding-top', 0).html(that.new_model_text))
689
+ .append(form)
690
+ ).slideDown();
691
+ },
692
+
693
+ add_model: function()
694
+ {
695
+ var that = this;
696
+ $('#new_message').html("<p class='loading'>Adding...</p>");
697
+ $.ajax({
698
+ url: this.add_url,
699
+ type: 'post',
700
+ data: $('#new_form').serialize(),
701
+ success: function(resp) {
702
+ if (resp.error) $('#new_message').html("<p class='note error'>" + resp.error + "</p>");
703
+ if (resp.redirect || resp.refresh) that.refresh();
704
+ }
705
+ });
706
+ },
707
+
708
+
709
+ };