caboose-cms 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/caboose/modal.js +4 -0
- data/app/assets/javascripts/caboose/modal_integration.js +10 -0
- data/app/assets/javascripts/caboose/model/all.js +9 -0
- data/app/assets/javascripts/caboose/model/attribute.js +63 -0
- data/app/assets/javascripts/caboose/model/bound_checkbox.js +90 -0
- data/app/assets/javascripts/caboose/model/bound_checkbox_multiple.js +106 -0
- data/app/assets/javascripts/caboose/model/bound_control.js +68 -0
- data/app/assets/javascripts/caboose/model/bound_select.js +108 -0
- data/app/assets/javascripts/caboose/model/bound_text.js +87 -0
- data/app/assets/javascripts/caboose/model/bound_textarea.js +134 -0
- data/app/assets/javascripts/caboose/model/class.js +64 -0
- data/app/assets/javascripts/caboose/model/model.js +37 -0
- data/app/assets/javascripts/caboose/model/model_binder.js +61 -0
- data/app/assets/javascripts/caboose/shortcut.js +11 -0
- data/app/assets/javascripts/caboose/station.js +7 -5
- data/app/assets/stylesheets/caboose/modal.css +106 -1
- data/app/controllers/caboose/admin_controller.rb +1 -9
- data/app/controllers/caboose/pages_controller.rb +43 -14
- data/app/controllers/caboose/station_controller.rb +3 -0
- data/app/models/caboose/page_plugin.rb +1 -1
- data/app/models/caboose/user_plugin.rb +1 -1
- data/app/views/caboose/admin/index.html.erb +0 -4
- data/app/views/caboose/pages/edit.html.erb +6 -19
- data/app/views/caboose/pages/edit_content.html.erb +48 -0
- data/app/views/caboose/pages/edit_css.html.erb +36 -0
- data/app/views/caboose/pages/edit_js.html.erb +36 -0
- data/app/views/caboose/pages/edit_seo.html.erb +39 -0
- data/app/views/caboose/pages/edit_settings.html.erb +35 -24
- data/app/views/caboose/pages/edit_title.html.erb +29 -0
- data/app/views/caboose/pages/show.html.erb +2 -2
- data/app/views/caboose/station/index.html.erb +5 -2
- data/app/views/caboose/users/edit.html.erb +1 -1
- data/app/views/layouts/caboose/_admin_top_nav.html.erb +1 -3
- data/app/views/layouts/caboose/_top_nav.html.erb +1 -1
- data/app/views/layouts/caboose/application.html.erb +2 -2
- data/config/routes.rb +6 -1
- data/lib/caboose/version.rb +1 -1
- metadata +19 -3
- data/app/assets/javascripts/caboose/bound_input.js +0 -198
@@ -23,3 +23,13 @@ function fix_colorbox() {
|
|
23
23
|
//h = $('#cboxLoadedContent').height();
|
24
24
|
//$('#cboxLoadedContent').css('height', ''+(h+28)+'px');
|
25
25
|
}
|
26
|
+
|
27
|
+
//lastkeys = "";
|
28
|
+
//$(document).keyup(function(e) {
|
29
|
+
// if (e.keyCode == 13 && (lastkeys == "caboose" || lastkeys == "CABOOSE"))
|
30
|
+
// $.colorbox({ href: '/station', iframe: true, initialWidth: 200, initialHeight: 50, innerWidth: 200, innerHeight: 50, scrolling: false, transition: 'fade', closeButton: false, onComplete: fix_colorbox, opacity: 0.50 });
|
31
|
+
//
|
32
|
+
// lastkeys += String.fromCharCode(e.keyCode);
|
33
|
+
// if (lastkeys.length > 7)
|
34
|
+
// lastkeys = lastkeys.substr(1);
|
35
|
+
//});
|
@@ -0,0 +1,9 @@
|
|
1
|
+
//= require caboose/model/class
|
2
|
+
//= require caboose/model/model
|
3
|
+
//= require caboose/model/attribute
|
4
|
+
//= require caboose/model/model_binder
|
5
|
+
//= require caboose/model/bound_control
|
6
|
+
//= require caboose/model/bound_checkbox
|
7
|
+
//= require caboose/model/bound_select
|
8
|
+
//= require caboose/model/bound_text
|
9
|
+
//= require caboose/model/bound_textarea
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
var Attribute = function(params) {
|
3
|
+
for (var thing in params)
|
4
|
+
this[thing] = params[thing];
|
5
|
+
this.value_clean = this.value;
|
6
|
+
};
|
7
|
+
|
8
|
+
Attribute.prototype = {
|
9
|
+
name: false,
|
10
|
+
nice_name: false,
|
11
|
+
type: false,
|
12
|
+
value: false,
|
13
|
+
value_clean: false,
|
14
|
+
text: false,
|
15
|
+
|
16
|
+
update_url: false,
|
17
|
+
options_url: false,
|
18
|
+
options: false,
|
19
|
+
|
20
|
+
save: function(after) {
|
21
|
+
var this2 = this;
|
22
|
+
$.ajax({
|
23
|
+
url: this.update_url,
|
24
|
+
type: 'put',
|
25
|
+
data: this.name + '=' + this.value,
|
26
|
+
success: function(resp) {
|
27
|
+
if (resp.success)
|
28
|
+
{
|
29
|
+
if (resp.attributes && resp.attributes[this2.name])
|
30
|
+
for (var thing in resp.attributes[this2.name])
|
31
|
+
this2[thing] = resp.attributes[this2.name][thing];
|
32
|
+
this2.value_clean = this2.value;
|
33
|
+
}
|
34
|
+
if (after) after(resp);
|
35
|
+
},
|
36
|
+
error: function() {
|
37
|
+
if (after) after(false);
|
38
|
+
}
|
39
|
+
});
|
40
|
+
},
|
41
|
+
|
42
|
+
populate_options: function(after) {
|
43
|
+
if (!this.options_url)
|
44
|
+
return;
|
45
|
+
if (this.options)
|
46
|
+
{
|
47
|
+
if (after) after();
|
48
|
+
return;
|
49
|
+
}
|
50
|
+
var this2 = this;
|
51
|
+
$.ajax({
|
52
|
+
url: this.options_url,
|
53
|
+
type: 'get',
|
54
|
+
success: function(resp) {
|
55
|
+
this2.options = resp;
|
56
|
+
if (after) after();
|
57
|
+
},
|
58
|
+
error: function() {
|
59
|
+
if (after) after();
|
60
|
+
}
|
61
|
+
});
|
62
|
+
}
|
63
|
+
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
|
2
|
+
BoundCheckbox = BoundControl.extend({
|
3
|
+
|
4
|
+
//el: false,
|
5
|
+
//model: false,
|
6
|
+
//attribute: false,
|
7
|
+
//binder: false,
|
8
|
+
|
9
|
+
message: false,
|
10
|
+
placeholder: false,
|
11
|
+
|
12
|
+
init: function(params) {
|
13
|
+
|
14
|
+
for (var thing in params)
|
15
|
+
this[thing] = params[thing];
|
16
|
+
|
17
|
+
this.el = this.el ? this.el : this.model.name.toLowerCase() + '_' + this.model.id + '_' + this.attribute.name;
|
18
|
+
this.message = this.el + '_message';
|
19
|
+
this.placeholder = this.el + '_placeholder';
|
20
|
+
|
21
|
+
var this2 = this;
|
22
|
+
$('#'+this.el).wrap($('<div/>')
|
23
|
+
.attr('id', this.el + '_container')
|
24
|
+
.css('position', 'relative')
|
25
|
+
);
|
26
|
+
$('#'+this.el+'_container').empty();
|
27
|
+
$('#'+this.el+'_container').append($('<div/>')
|
28
|
+
.attr('id', this.placeholder)
|
29
|
+
.addClass('placeholder')
|
30
|
+
.append($('<span/>').html(this.attribute.nice_name + ': '))
|
31
|
+
);
|
32
|
+
$('#'+this.el+'_container').append($('<input/>')
|
33
|
+
.attr('id', this.el)
|
34
|
+
.attr('type', 'checkbox')
|
35
|
+
.css('left', $('#'+this.placeholder).outerWidth() + 10)
|
36
|
+
.attr('checked', this.attribute.value)
|
37
|
+
.on('change', function() {
|
38
|
+
this2.binder.cancel_active();
|
39
|
+
this2.binder.active_control = this;
|
40
|
+
this2.save();
|
41
|
+
})
|
42
|
+
);
|
43
|
+
$('#'+this.el+'_container').append($('<input/>')
|
44
|
+
.attr('id', this.el + '_background')
|
45
|
+
.attr('disabled', true)
|
46
|
+
.css('background', '#fff')
|
47
|
+
);
|
48
|
+
if (this.attribute.width)
|
49
|
+
$('#'+this.el+'_background').css('width' , this.attribute.width);
|
50
|
+
},
|
51
|
+
|
52
|
+
view: function() {
|
53
|
+
|
54
|
+
},
|
55
|
+
|
56
|
+
edit: function() {
|
57
|
+
|
58
|
+
},
|
59
|
+
|
60
|
+
save: function() {
|
61
|
+
|
62
|
+
this.attribute.value = $('#'+this.el).prop('checked') ? 1 : 0;
|
63
|
+
|
64
|
+
var this2 = this;
|
65
|
+
this.model.save(this.attribute, function(resp) {
|
66
|
+
$('#'+this2.el+'_check a').removeClass('loading');
|
67
|
+
if (resp.error) this2.error(resp.error);
|
68
|
+
else
|
69
|
+
{
|
70
|
+
this2.binder.active_control = this2;
|
71
|
+
if (this2.binder.success)
|
72
|
+
this2.binder.success(this2);
|
73
|
+
this2.view();
|
74
|
+
}
|
75
|
+
});
|
76
|
+
},
|
77
|
+
|
78
|
+
cancel: function() {
|
79
|
+
this.attribute.value = this.attribute.value_clean;
|
80
|
+
$('#'+this.el).attr('checked', '' + this.attribute.value ? 'true' : 'false')
|
81
|
+
this.view();
|
82
|
+
},
|
83
|
+
|
84
|
+
error: function(str) {
|
85
|
+
if (!$('#'+this.message).length)
|
86
|
+
$('#'+this.el+'_container').prepend($('<div/>').attr('id', this.message));
|
87
|
+
$('#'+this.message).html("<p class='note error'>" + str + "</p>");
|
88
|
+
}
|
89
|
+
|
90
|
+
});
|
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
BoundCheckbox = BoundControl.extend({
|
3
|
+
|
4
|
+
//el: false,
|
5
|
+
//model: false,
|
6
|
+
//attribute: false,
|
7
|
+
//binder: false,
|
8
|
+
|
9
|
+
message: false,
|
10
|
+
placeholder: false,
|
11
|
+
checkboxes: false,
|
12
|
+
|
13
|
+
init: function(params) {
|
14
|
+
|
15
|
+
for (var thing in params)
|
16
|
+
this[thing] = params[thing];
|
17
|
+
|
18
|
+
this.el = this.el ? this.el : this.model.name.toLowerCase() + '_' + this.model.id + '_' + this.attribute.name;
|
19
|
+
this.message = this.el + '_message';
|
20
|
+
this.placeholder = this.el + '_placeholder';
|
21
|
+
|
22
|
+
var this2 = this;
|
23
|
+
$('#'+this.el).wrap($('<div/>')
|
24
|
+
.attr('id', this.el + '_container')
|
25
|
+
.css('position', 'relative')
|
26
|
+
);
|
27
|
+
$('#'+this.el+'_container').empty();
|
28
|
+
$('#'+this.el+'_container').append($('<div/>')
|
29
|
+
.attr('id', this.placeholder)
|
30
|
+
.addClass('placeholder')
|
31
|
+
.append($('<span/>').html(this.attribute.nice_name + ': '))
|
32
|
+
);
|
33
|
+
$('#'+this.el+'_container').append($('<input/>')
|
34
|
+
.attr('id', this.el + '_background')
|
35
|
+
.attr('disabled', true)
|
36
|
+
.css('background', '#fff')
|
37
|
+
);
|
38
|
+
if (this.attribute.width)
|
39
|
+
$('#'+this.el+'_background').css('width' , this.attribute.width);
|
40
|
+
|
41
|
+
var this2 = this;
|
42
|
+
this.attribute.populate_options(function() {
|
43
|
+
var tbody = $('<tbody/>');
|
44
|
+
$.each(this2.options, function(i, option) {
|
45
|
+
tbody.append($('<tr/>')
|
46
|
+
.append($('<td/>')
|
47
|
+
.attr('id', this2.el + '_' + i)
|
48
|
+
.attr('type', 'checkbox')
|
49
|
+
.attr('checked', this2.attribute.value)
|
50
|
+
.on('change', function() {
|
51
|
+
//this2.binder.cancel_active();
|
52
|
+
//this2.binder.active_control = this;
|
53
|
+
//this2.save();
|
54
|
+
})
|
55
|
+
)
|
56
|
+
.append($('<label/>')
|
57
|
+
.attr('for', this2.el + '_' + i)
|
58
|
+
.html(option.text)
|
59
|
+
)
|
60
|
+
);
|
61
|
+
});
|
62
|
+
$('#'+this.el+'_container').append(
|
63
|
+
$('<table/>').append(tbody)
|
64
|
+
);
|
65
|
+
);
|
66
|
+
},
|
67
|
+
|
68
|
+
view: function() {
|
69
|
+
|
70
|
+
},
|
71
|
+
|
72
|
+
edit: function() {
|
73
|
+
|
74
|
+
},
|
75
|
+
|
76
|
+
save: function() {
|
77
|
+
|
78
|
+
this.attribute.value = $('#'+this.el).prop('checked') ? 1 : 0;
|
79
|
+
|
80
|
+
var this2 = this;
|
81
|
+
this.model.save(this.attribute, function(resp) {
|
82
|
+
$('#'+this2.el+'_check a').removeClass('loading');
|
83
|
+
if (resp.error) this2.error(resp.error);
|
84
|
+
else
|
85
|
+
{
|
86
|
+
this2.binder.active_control = this2;
|
87
|
+
if (this2.binder.success)
|
88
|
+
this2.binder.success(this2);
|
89
|
+
this2.view();
|
90
|
+
}
|
91
|
+
});
|
92
|
+
},
|
93
|
+
|
94
|
+
cancel: function() {
|
95
|
+
this.attribute.value = this.attribute.value_clean;
|
96
|
+
$('#'+this.el).attr('checked', '' + this.attribute.value ? 'true' : 'false')
|
97
|
+
this.view();
|
98
|
+
},
|
99
|
+
|
100
|
+
error: function(str) {
|
101
|
+
if (!$('#'+this.message).length)
|
102
|
+
$('#'+this.el+'_container').prepend($('<div/>').attr('id', this.message));
|
103
|
+
$('#'+this.message).html("<p class='note error'>" + str + "</p>");
|
104
|
+
}
|
105
|
+
|
106
|
+
});
|
@@ -0,0 +1,68 @@
|
|
1
|
+
|
2
|
+
BoundControl = Class.extend({
|
3
|
+
|
4
|
+
el: false, // The DOM element to which the object is bound
|
5
|
+
model: false, // The model to which the control is bound
|
6
|
+
attribute: false, // The attribute of the model
|
7
|
+
binder: false, // The model binder
|
8
|
+
|
9
|
+
init: function(params) {}, // Constructor
|
10
|
+
view: function() {}, // Sets the control in a view state
|
11
|
+
edit: function() {}, // Sets the control in an edit state
|
12
|
+
save: function() {}, // Sends the value in the control to the model to be saved
|
13
|
+
cancel: function() {}, // Cancels the edit
|
14
|
+
error: function(str) {}, // Shows an error
|
15
|
+
|
16
|
+
show_loader: function() {
|
17
|
+
var w = $('#'+this.el).outerWidth();
|
18
|
+
var h = 40; //$('#'+this.el).outerHeight();
|
19
|
+
var this2 = this;
|
20
|
+
|
21
|
+
if (!$('#'+this.el+'_check').length)
|
22
|
+
{
|
23
|
+
$('#'+this.el+'_container').prepend($('<div/>')
|
24
|
+
.attr('id', this.el + '_check')
|
25
|
+
.addClass('bound_input_check')
|
26
|
+
.css('position', 'absolute')
|
27
|
+
.css('top', 0)
|
28
|
+
.css('left', w-h-1)
|
29
|
+
.css('width', h+2)
|
30
|
+
.css('overflow', 'hidden')
|
31
|
+
.append($('<a/>')
|
32
|
+
.addClass('loading')
|
33
|
+
.html('✓')
|
34
|
+
.css('width', h)
|
35
|
+
.css('margin-left', h)
|
36
|
+
.attr('href', '#')
|
37
|
+
.click(function(event) { event.preventDefault(); })
|
38
|
+
)
|
39
|
+
);
|
40
|
+
}
|
41
|
+
$('#'+this.el+'_check a')
|
42
|
+
.addClass('loading')
|
43
|
+
.css('margin-left', h);
|
44
|
+
$('#'+this.el+'_check a').animate({ 'margin-left': 0 }, 300);
|
45
|
+
},
|
46
|
+
|
47
|
+
hide_loader: function() {
|
48
|
+
this.hide_check();
|
49
|
+
},
|
50
|
+
|
51
|
+
show_check: function(duration) {
|
52
|
+
$('#'+this.el+'_check a').removeClass('loading');
|
53
|
+
if (duration)
|
54
|
+
{
|
55
|
+
var this2 = this;
|
56
|
+
setTimeout(function() { this2.hide_check(); }, duration);
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
hide_check: function() {
|
61
|
+
var h = $('#'+this.el).outerHeight();
|
62
|
+
var this2 = this;
|
63
|
+
$('#'+this.el+'_check a').animate({ 'margin-left': h }, 300, function() {
|
64
|
+
$('#'+this2.check).remove();
|
65
|
+
});
|
66
|
+
}
|
67
|
+
|
68
|
+
});
|
@@ -0,0 +1,108 @@
|
|
1
|
+
|
2
|
+
BoundSelect = BoundControl.extend({
|
3
|
+
|
4
|
+
//el: false,
|
5
|
+
//model: false,
|
6
|
+
//attribute: false,
|
7
|
+
//binder: false,
|
8
|
+
|
9
|
+
message: false,
|
10
|
+
placeholder: false,
|
11
|
+
|
12
|
+
init: function(params) {
|
13
|
+
|
14
|
+
for (var thing in params)
|
15
|
+
this[thing] = params[thing];
|
16
|
+
|
17
|
+
this.el = this.el ? this.el : this.model.name.toLowerCase() + '_' + this.model.id + '_' + this.attribute.name;
|
18
|
+
this.message = this.el + '_message';
|
19
|
+
this.placeholder = this.el + '_placeholder';
|
20
|
+
|
21
|
+
$('#'+this.el).wrap($('<div/>')
|
22
|
+
.attr('id', this.el + '_container')
|
23
|
+
.css('position', 'relative')
|
24
|
+
);
|
25
|
+
$('#'+this.el+'_container').empty();
|
26
|
+
$('#'+this.el+'_container').append($('<div/>')
|
27
|
+
.attr('id', this.placeholder)
|
28
|
+
.addClass('placeholder')
|
29
|
+
.append($('<span/>')
|
30
|
+
.html(this.attribute.nice_name + ': ')
|
31
|
+
)
|
32
|
+
);
|
33
|
+
$('#'+this.el+'_container').append($('<input/>')
|
34
|
+
.attr('id', this.el)
|
35
|
+
.attr('placeholder', 'empty')
|
36
|
+
.on('focus', function() { this2.edit(); })
|
37
|
+
.val(this.attribute.text)
|
38
|
+
);
|
39
|
+
if (this.attribute.width)
|
40
|
+
$('#'+this.el).css('width', this.attribute.width);
|
41
|
+
|
42
|
+
var w = $('#'+this.placeholder).outerWidth();
|
43
|
+
$('#'+this.el)
|
44
|
+
.css('padding-left', '+=' + w)
|
45
|
+
.css('width', '-=' + w);
|
46
|
+
|
47
|
+
var this2 = this;
|
48
|
+
this.attribute.populate_options(function() {
|
49
|
+
var select = $('<select/>')
|
50
|
+
.attr('id', this2.el + '_select')
|
51
|
+
.addClass('fake')
|
52
|
+
.css('width', $('#'+this2.el).outerWidth())
|
53
|
+
.on('change', function() {
|
54
|
+
$('#'+this2.el).val($('#'+this2.el+'_select').val());
|
55
|
+
this2.save();
|
56
|
+
});
|
57
|
+
|
58
|
+
$.each(this2.attribute.options, function(i, option) {
|
59
|
+
var opt = $('<option/>')
|
60
|
+
.val(option.value)
|
61
|
+
.html(option.text);
|
62
|
+
if (option.value == this2.attribute.value)
|
63
|
+
opt.attr('selected', 'true');
|
64
|
+
select.append(opt);
|
65
|
+
});
|
66
|
+
$('#'+this2.el+'_container').append(select);
|
67
|
+
$('#'+this2.el+'_select').css('width', $('#'+this2.el).outerWidth());
|
68
|
+
});
|
69
|
+
},
|
70
|
+
|
71
|
+
view: function() {
|
72
|
+
|
73
|
+
},
|
74
|
+
|
75
|
+
edit: function() {
|
76
|
+
this.binder.cancel_active();
|
77
|
+
this.binder.active_control = this;
|
78
|
+
},
|
79
|
+
|
80
|
+
save: function() {
|
81
|
+
this.attribute.value = $('#'+this.el).val();
|
82
|
+
var this2 = this;
|
83
|
+
this.model.save(this.attribute, function(resp) {
|
84
|
+
$('#'+this2.el+'_check a').removeClass('loading');
|
85
|
+
if (resp.error) this2.error(resp.error);
|
86
|
+
else
|
87
|
+
{
|
88
|
+
this2.binder.active_control = this2;
|
89
|
+
if (this2.binder.success)
|
90
|
+
this2.binder.success(this2);
|
91
|
+
this2.view();
|
92
|
+
}
|
93
|
+
});
|
94
|
+
},
|
95
|
+
|
96
|
+
cancel: function() {
|
97
|
+
this.attribute.value = this.attribute.value_clean;
|
98
|
+
$('#'+this.el).val(this.attribute.value);
|
99
|
+
this.view();
|
100
|
+
},
|
101
|
+
|
102
|
+
error: function(str) {
|
103
|
+
if (!$('#'+this.message).length)
|
104
|
+
$('#'+this.el+'_container').prepend($('<div/>').attr('id', this.message));
|
105
|
+
$('#'+this.message).html("<p class='note error'>" + str + "</p>");
|
106
|
+
}
|
107
|
+
|
108
|
+
});
|