caboose-cms 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/app/assets/javascripts/caboose/model/index_table.js +87 -64
- data/app/assets/javascripts/caboose/model/index_table_bak.js +709 -0
- data/app/controllers/caboose/categories_controller.rb +17 -0
- data/app/controllers/caboose/products_controller.rb +64 -40
- data/app/models/caboose/product.rb +20 -0
- data/app/views/caboose/products/admin_index.html.erb +77 -85
- data/config/routes.rb +42 -39
- data/lib/caboose/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjM5NDdjM2NhOTc3MzhjZDk1NDI3NTYwZWRmNDAxZGEzNGUwYzJkZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NDUyMTQxN2VkYTYyMGQwYTJhM2E5MWUwZTRmNmM3ZjQ2MDQ0MDk2Ng==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjljMzZmMDZlYzEwMjJhYWUzZWY3ZmI2NDVmZWQxYTI2MjkzMWNmYmI2OWE0
|
10
|
+
YmY2ZmVlMjg5YzIzNDg1MmNlZjZjMWRmYzUyNjc5ZGZmOWI2NjRhMzYwNjNl
|
11
|
+
ZjdkYjZhMjAyZDBjNGY0M2NjOTE1YWExOWY1OTNiZGE0ZDI5MjE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
88
|
-
if (!this.bulk_update_url ) this.bulk_update_url
|
89
|
-
if (!this.bulk_delete_url ) this.bulk_delete_url
|
90
|
-
if (!this.add_url ) this.add_url
|
91
|
-
if (!this.update_url ) this.update_url
|
92
|
-
if (!this.duplicate_url ) this.duplicate_url
|
93
|
-
if (!this.
|
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.
|
231
|
-
{
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
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 ? ' ↑' : ' ↓') : '';
|
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
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
if (field.name == that.quick_edit_field)
|
282
|
-
|
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
|
-
|
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
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
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.
|
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(' '));
|
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 ? ' ↑' : ' ↓') : '';
|
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
|
+
};
|