modeljs 0.0.1
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.
- data/MIT-LICENSE +20 -0
- data/README.md +143 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/modeljs/attribute/checkbox-multiple.js +72 -0
- data/app/assets/javascripts/modeljs/attribute/checkbox.js +32 -0
- data/app/assets/javascripts/modeljs/attribute/date-time.js +30 -0
- data/app/assets/javascripts/modeljs/attribute/file.js +88 -0
- data/app/assets/javascripts/modeljs/attribute/hidden.js +19 -0
- data/app/assets/javascripts/modeljs/attribute/image.js +105 -0
- data/app/assets/javascripts/modeljs/attribute/password.js +36 -0
- data/app/assets/javascripts/modeljs/attribute/radio.js +60 -0
- data/app/assets/javascripts/modeljs/attribute/rich-text.js +40 -0
- data/app/assets/javascripts/modeljs/attribute/select.js +121 -0
- data/app/assets/javascripts/modeljs/attribute/texarea.js +42 -0
- data/app/assets/javascripts/modeljs/attribute/textjs.js +63 -0
- data/app/assets/javascripts/modeljs/attribute/time.js +31 -0
- data/app/assets/javascripts/modeljs/attribute/video.js +95 -0
- data/app/assets/javascripts/modeljs/attribute.js +69 -0
- data/app/assets/javascripts/modeljs/form/embedded.js +13 -0
- data/app/assets/javascripts/modeljs/form.js +257 -0
- data/app/assets/javascripts/modeljs/model.js +543 -0
- data/app/assets/stylesheets/modeljs/modeljs.css +199 -0
- data/lib/modeljs/engine.rb +4 -0
- data/lib/modeljs/version.rb +3 -0
- data/lib/modeljs.rb +5 -0
- data/lib/tasks/modeljs_tasks.rake +0 -0
- metadata +119 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
Model.Attribute.Select = Model.Attribute.extend({
|
3
|
+
|
4
|
+
text: '',
|
5
|
+
multiple: false,
|
6
|
+
|
7
|
+
needs_options: function()
|
8
|
+
{
|
9
|
+
return true;
|
10
|
+
},
|
11
|
+
|
12
|
+
view: function()
|
13
|
+
{
|
14
|
+
var html = this.text && this.text.length > 0 ? this.text : this.empty_text;
|
15
|
+
//return $('<a/>')
|
16
|
+
// .attr('title', 'Click to edit')
|
17
|
+
// .attr('href', 'javascript:{};')
|
18
|
+
// .addClass('model_attribute_select')
|
19
|
+
// .html(html);
|
20
|
+
return $('<div/>')
|
21
|
+
.html(html);
|
22
|
+
},
|
23
|
+
|
24
|
+
form: function()
|
25
|
+
{
|
26
|
+
var form = $('<form/>')
|
27
|
+
var select = $('<select></select>')
|
28
|
+
.attr('id', this.base)
|
29
|
+
.attr('name', this.base);
|
30
|
+
|
31
|
+
if (this.multiple)
|
32
|
+
{
|
33
|
+
select.attr('multiple', 'multiple');
|
34
|
+
select.attr('size', '9');
|
35
|
+
}
|
36
|
+
|
37
|
+
var this2 = this;
|
38
|
+
var options = Model.get_attribute_options(this.model.name, this.name);
|
39
|
+
$.each(options, function(i, option)
|
40
|
+
{
|
41
|
+
if (option.children != null) // Option group
|
42
|
+
{
|
43
|
+
var optgroup = $('<optgroup></optgroup>');
|
44
|
+
optgroup.attr('label', option.title);
|
45
|
+
|
46
|
+
$.each(option.children, function(j, option2)
|
47
|
+
{
|
48
|
+
var opt = $('<option></option>')
|
49
|
+
.attr('text', option2.text)
|
50
|
+
.val(option2.value);
|
51
|
+
|
52
|
+
if (!this2.multiple)
|
53
|
+
opt.attr('selected', (option2.value == this2.value));
|
54
|
+
else
|
55
|
+
{
|
56
|
+
opt.attr('selected', false);
|
57
|
+
for (var k=0; k<this2.value.length; k++)
|
58
|
+
if (option2.value == this2.value[k])
|
59
|
+
{
|
60
|
+
opt.attr('selected', true);
|
61
|
+
break;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
optgroup.append(opt);
|
65
|
+
});
|
66
|
+
|
67
|
+
select.append(optgroup);
|
68
|
+
}
|
69
|
+
else
|
70
|
+
{
|
71
|
+
var opt = $('<option></option>')
|
72
|
+
.val(option.value)
|
73
|
+
.text(option.text);
|
74
|
+
|
75
|
+
if (!this2.multiple)
|
76
|
+
{
|
77
|
+
opt.attr('selected', (option.value == this2.value));
|
78
|
+
}
|
79
|
+
else
|
80
|
+
{
|
81
|
+
opt.attr('selected', false);
|
82
|
+
for (var j=0; j<this2.value.length; j++)
|
83
|
+
if (option.value == this2.value[j])
|
84
|
+
{
|
85
|
+
opt.attr('selected', true);
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
select.append(opt);
|
90
|
+
}
|
91
|
+
});
|
92
|
+
form.append(select);
|
93
|
+
if (this.multiple)
|
94
|
+
{
|
95
|
+
form.append("<br/>");
|
96
|
+
form.append(
|
97
|
+
$('<input/>')
|
98
|
+
.attr('type', 'button')
|
99
|
+
.val('Clear')
|
100
|
+
.addClass('update_btn')
|
101
|
+
.click(function() { $('#' + this.base).selectedIndex = -1; })
|
102
|
+
);
|
103
|
+
}
|
104
|
+
|
105
|
+
return form;
|
106
|
+
},
|
107
|
+
|
108
|
+
form_value: function()
|
109
|
+
{
|
110
|
+
if (!this.multiple)
|
111
|
+
return $('#' + this.base + ' option:selected').val();
|
112
|
+
|
113
|
+
var select = $('#' + this.base);
|
114
|
+
val = [];
|
115
|
+
$('#' + this.base + ' option:selected').each(function(i, opt) {
|
116
|
+
val[val.length] = $(opt).val();
|
117
|
+
});
|
118
|
+
return val;
|
119
|
+
}
|
120
|
+
|
121
|
+
});
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
Model.Attribute.Textarea = Model.Attribute.extend({
|
3
|
+
|
4
|
+
show_controls: true,
|
5
|
+
normal_text: false,
|
6
|
+
width: 200,
|
7
|
+
height: 100,
|
8
|
+
|
9
|
+
view: function()
|
10
|
+
{
|
11
|
+
html = this.empty_text;
|
12
|
+
if (this.text && this.text.length > 0) html = this.text;
|
13
|
+
else if (this.value && this.value.length > 0) html = this.value;
|
14
|
+
//return $('<a/>')
|
15
|
+
// .attr('title', 'Click to edit')
|
16
|
+
// .attr('href', 'javascript:{};')
|
17
|
+
// .css({
|
18
|
+
// display: 'block',
|
19
|
+
// width: this.width
|
20
|
+
// })
|
21
|
+
// .html(html);
|
22
|
+
return $('<div/>')
|
23
|
+
.css({
|
24
|
+
display: 'block',
|
25
|
+
width: this.width
|
26
|
+
})
|
27
|
+
.html(html);
|
28
|
+
},
|
29
|
+
|
30
|
+
form: function()
|
31
|
+
{
|
32
|
+
return $('<form/>')
|
33
|
+
.append($('<textarea/>')
|
34
|
+
.attr('id', this.base)
|
35
|
+
.attr('name', this.base)
|
36
|
+
.val(this.value)
|
37
|
+
.css('width', this.width)
|
38
|
+
.css('height', this.height)
|
39
|
+
);
|
40
|
+
}
|
41
|
+
|
42
|
+
});
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
Model.Attribute.Text = Model.Attribute.extend({
|
3
|
+
|
4
|
+
show_reminder: true,
|
5
|
+
|
6
|
+
view: function()
|
7
|
+
{
|
8
|
+
var html = false;
|
9
|
+
if (typeof(this.value) == 'string')
|
10
|
+
html = this.value && this.value.length > 0 ? this.value : this.empty_text;
|
11
|
+
else if (typeof(this.value) == 'number')
|
12
|
+
html = this.value != null ? this.value : this.empty_text;
|
13
|
+
else
|
14
|
+
html = this.value;
|
15
|
+
|
16
|
+
//return $('<a/>')
|
17
|
+
// .attr('title', 'Click to edit')
|
18
|
+
// .attr('href', 'javascript:{};')
|
19
|
+
// .html(html);
|
20
|
+
return $('<div/>')
|
21
|
+
.html(html);
|
22
|
+
},
|
23
|
+
|
24
|
+
form: function()
|
25
|
+
{
|
26
|
+
var this2 = this;
|
27
|
+
var input = $('<input/>')
|
28
|
+
.attr('type', 'text')
|
29
|
+
.attr('id', this.base)
|
30
|
+
.attr('name', this.base)
|
31
|
+
.val(this.value);
|
32
|
+
if (this.show_reminder)
|
33
|
+
input.keyup(function (){ this2.flash_reminder(); })
|
34
|
+
if (this.css)
|
35
|
+
input.css(this.css);
|
36
|
+
var form = $('<form/>').append(input);
|
37
|
+
if (this.show_reminder)
|
38
|
+
form.append($('<span/>').attr('id', this.base + '_reminder').css('font-size', '75%'));
|
39
|
+
|
40
|
+
return form;
|
41
|
+
},
|
42
|
+
|
43
|
+
flash_reminder: function()
|
44
|
+
{
|
45
|
+
$('#' + this.base + '_reminder')
|
46
|
+
.html(' (Enter to update, Escape to cancel)')
|
47
|
+
.delay(1000)
|
48
|
+
.fadeOut({ done: function() { $(this).empty().show(); }});
|
49
|
+
},
|
50
|
+
|
51
|
+
post_form_display: function()
|
52
|
+
{
|
53
|
+
// Put the focus at the end of the string
|
54
|
+
$('#' + this.base).focus();
|
55
|
+
val = $('#' + this.base).val();
|
56
|
+
$('#' + this.base).val('');
|
57
|
+
$('#' + this.base).val(val);
|
58
|
+
|
59
|
+
if (this.show_reminder)
|
60
|
+
this.flash_reminder();
|
61
|
+
}
|
62
|
+
|
63
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
Model.Attribute.Time = Model.Attribute.extend({
|
3
|
+
|
4
|
+
view: function()
|
5
|
+
{
|
6
|
+
var html = this.value && this.value.length > 0 ? this.value : this.empty_text;
|
7
|
+
return $('<a/>')
|
8
|
+
.attr('title', 'Click to edit')
|
9
|
+
.attr('href', 'javascript:{};')
|
10
|
+
.addClass('model_attribute_text')
|
11
|
+
.html(html);
|
12
|
+
},
|
13
|
+
|
14
|
+
form: function()
|
15
|
+
{
|
16
|
+
return $('<form/>')
|
17
|
+
.append($('<input/>')
|
18
|
+
.attr('type', 'text')
|
19
|
+
.attr('id', this.base)
|
20
|
+
.attr('name', this.base)
|
21
|
+
.val(this.value)
|
22
|
+
.addClass('text_box')
|
23
|
+
);
|
24
|
+
},
|
25
|
+
|
26
|
+
post_form_display: function()
|
27
|
+
{
|
28
|
+
$('#' + this.base).timepicker({ ampm: true });
|
29
|
+
}
|
30
|
+
|
31
|
+
});
|
@@ -0,0 +1,95 @@
|
|
1
|
+
|
2
|
+
Model.Attribute.Video = Model.Attribute.extend({
|
3
|
+
|
4
|
+
show_reminder: true,
|
5
|
+
thumb_width: 320,
|
6
|
+
thumb_height: 240,
|
7
|
+
|
8
|
+
view: function()
|
9
|
+
{
|
10
|
+
var html = false;
|
11
|
+
if (typeof(this.value) == 'string')
|
12
|
+
html = this.value && this.value.length > 0 ? this.value : this.empty_text;
|
13
|
+
else if (typeof(this.value) == 'number')
|
14
|
+
html = this.value != null ? this.value : this.empty_text;
|
15
|
+
else
|
16
|
+
html = this.value;
|
17
|
+
var div = $('<div/>').html(html);
|
18
|
+
var iframe = this.video_iframe(this.value);
|
19
|
+
if (iframe)
|
20
|
+
div.append($('<br/>')).append(iframe);
|
21
|
+
return div;
|
22
|
+
},
|
23
|
+
|
24
|
+
form: function()
|
25
|
+
{
|
26
|
+
var this2 = this;
|
27
|
+
var input = $('<input/>')
|
28
|
+
.attr('type', 'text')
|
29
|
+
.attr('id', this.base)
|
30
|
+
.attr('name', this.base)
|
31
|
+
.val(this.value);
|
32
|
+
if (this.show_reminder)
|
33
|
+
input.keyup(function (){ this2.flash_reminder(); })
|
34
|
+
if (this.css)
|
35
|
+
input.css(this.css);
|
36
|
+
var form = $('<form/>').append(input);
|
37
|
+
if (this.show_reminder)
|
38
|
+
form.append($('<span/>').attr('id', this.base + '_reminder').css('font-size', '75%'));
|
39
|
+
|
40
|
+
var iframe = this.video_iframe(this.value);
|
41
|
+
if (iframe)
|
42
|
+
form.append($('<br/>')).append(iframe);
|
43
|
+
|
44
|
+
return form;
|
45
|
+
},
|
46
|
+
|
47
|
+
flash_reminder: function()
|
48
|
+
{
|
49
|
+
$('#' + this.base + '_reminder')
|
50
|
+
.html(' (Enter to update, Escape to cancel)')
|
51
|
+
.delay(1000)
|
52
|
+
.fadeOut({ done: function() { $(this).empty().show(); }});
|
53
|
+
},
|
54
|
+
|
55
|
+
post_form_display: function()
|
56
|
+
{
|
57
|
+
// Put the focus at the end of the string
|
58
|
+
$('#' + this.base).focus();
|
59
|
+
val = $('#' + this.base).val();
|
60
|
+
$('#' + this.base).val('');
|
61
|
+
$('#' + this.base).val(val);
|
62
|
+
|
63
|
+
if (this.show_reminder)
|
64
|
+
this.flash_reminder();
|
65
|
+
},
|
66
|
+
|
67
|
+
video_iframe: function()
|
68
|
+
{
|
69
|
+
if (this.value == null || this.value.length == 0)
|
70
|
+
return false;
|
71
|
+
|
72
|
+
if (this.value.match(/youtube\.com/))
|
73
|
+
{
|
74
|
+
var v = this.value.replace("youtube.com/watch?v=", '');
|
75
|
+
return $('<iframe/>')
|
76
|
+
.attr('type', 'text/html')
|
77
|
+
.attr('width', this.thumb_width)
|
78
|
+
.attr('height', this.thumb_height)
|
79
|
+
.attr('frameborder', '0')
|
80
|
+
.attr('src', "http://www.youtube.com/embed/" + v + "?autoplay=0");
|
81
|
+
}
|
82
|
+
if (this.value.match(/vimeo\.com/))
|
83
|
+
{
|
84
|
+
var v = this.value.replace("vimeo.com/", '');
|
85
|
+
return $('<iframe/>')
|
86
|
+
.attr('type', 'text/html')
|
87
|
+
.attr('width', this.thumb_width)
|
88
|
+
.attr('height', this.thumb_height)
|
89
|
+
.attr('frameborder', '0')
|
90
|
+
.attr('src', "http://player.vimeo.com/video/" + v);
|
91
|
+
}
|
92
|
+
return false;
|
93
|
+
}
|
94
|
+
|
95
|
+
});
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
Model.Attribute = Class.extend({
|
3
|
+
name: '',
|
4
|
+
nice_name: '',
|
5
|
+
value: '',
|
6
|
+
model: false,
|
7
|
+
base: '', // model.name + '_' + model.id + '_' + attribute.name
|
8
|
+
type: false,
|
9
|
+
container: false,
|
10
|
+
controls: false,
|
11
|
+
show_controls: false,
|
12
|
+
message: false,
|
13
|
+
empty_text: '',
|
14
|
+
update_url: false, // If this attribute has a special update URL
|
15
|
+
custom_form: false, // If the attribute needs a custom form (used in file and image)
|
16
|
+
css: false,
|
17
|
+
|
18
|
+
init: function(params)
|
19
|
+
{
|
20
|
+
for (var thing in params)
|
21
|
+
this[thing] = params[thing];
|
22
|
+
this.set_base(this.base);
|
23
|
+
if (!this.nice_name) this.nice_name = this.name.replace('_', ' ').capitalize();
|
24
|
+
},
|
25
|
+
|
26
|
+
set_base: function(base)
|
27
|
+
{
|
28
|
+
this.base = base;
|
29
|
+
if (!this.container) this.container = this.base + '_container';
|
30
|
+
if (!this.controls) this.controls = this.base + '_controls';
|
31
|
+
if (!this.message) this.message = this.base + '_message';
|
32
|
+
},
|
33
|
+
|
34
|
+
// Whether or not the attribute needs to go get options via ajax
|
35
|
+
needs_options: function() { return false; },
|
36
|
+
|
37
|
+
// Returns the viewable representation of the attribute.
|
38
|
+
view: function() { return false; },
|
39
|
+
|
40
|
+
// Returns a form without update or cancel buttons (Assumes options already populated)
|
41
|
+
form: function() { return false; },
|
42
|
+
|
43
|
+
// Returns the current value in the visible form.
|
44
|
+
form_value: function() { return $('#' + this.base).val(); },
|
45
|
+
|
46
|
+
// Returns the values form the form that will be sent to ajax_update
|
47
|
+
form_values: function() {
|
48
|
+
var vals = {};
|
49
|
+
vals[this.name] = this.form_value();
|
50
|
+
return vals;
|
51
|
+
},
|
52
|
+
|
53
|
+
// Runs after the view or form is displayed on the screen.
|
54
|
+
post_view_display: function() {},
|
55
|
+
post_form_display: function() { $('#' + this.base).focus(); },
|
56
|
+
|
57
|
+
// Notes
|
58
|
+
loading: function(str) { this.show_message('loading_small', str); },
|
59
|
+
note: function(str) { this.show_message('note_small' , str); },
|
60
|
+
success: function(str) { this.show_message('note_small success' , str); },
|
61
|
+
error: function(str) { this.show_message('note_small error' , str); },
|
62
|
+
show_message: function(class_names, str) {
|
63
|
+
$('#' + this.message).empty().removeClass('loading_small');
|
64
|
+
$('#' + this.message).addClass(class_names).html(str);
|
65
|
+
},
|
66
|
+
|
67
|
+
// If the attribute needs to handle any finished uploads
|
68
|
+
upload_finished: function(e, data) {}
|
69
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
Class: Model.Form
|
3
|
+
Author: William Barry (william@nine.is)
|
4
|
+
Description: Abstract form class to encapsulate add and edit forms for models.
|
5
|
+
*/
|
6
|
+
|
7
|
+
Model.Form.Embedded = Class.extend({
|
8
|
+
|
9
|
+
add: function() { return false; },
|
10
|
+
edit: function() { return false; },
|
11
|
+
listing: function() { return false; },
|
12
|
+
|
13
|
+
});
|
@@ -0,0 +1,257 @@
|
|
1
|
+
/*
|
2
|
+
Class: Model.Form
|
3
|
+
Author: William Barry (william@nine.is)
|
4
|
+
Description: Abstract form class to encapsulate add and edit forms for models.
|
5
|
+
*/
|
6
|
+
|
7
|
+
Model.Form = Class.extend({
|
8
|
+
|
9
|
+
class_name: 'Model.Form',
|
10
|
+
model: false,
|
11
|
+
message: false,
|
12
|
+
adding_message: null,
|
13
|
+
deleting_message: null,
|
14
|
+
delete_message: null,
|
15
|
+
|
16
|
+
// Listing info
|
17
|
+
listing_models: false,
|
18
|
+
|
19
|
+
init: function(model, params)
|
20
|
+
{
|
21
|
+
this.model = model;
|
22
|
+
if (params)
|
23
|
+
for (var thing in params)
|
24
|
+
this[thing] = params[thing];
|
25
|
+
|
26
|
+
if (!this.message ) this.message = model.name + '_message';
|
27
|
+
if (!this.adding_message ) this.adding_message = 'Adding ' + this.model.name + '...';
|
28
|
+
if (!this.deleting_message) this.deleting_message = 'Deleting ' + this.model.name + '...';
|
29
|
+
if (!this.delete_message ) this.delete_message = "Are you sure you want to delete the " + this.model.name + "? This can't be undone.";
|
30
|
+
},
|
31
|
+
|
32
|
+
// Returns the form for adding the model or false for an embedded form.
|
33
|
+
add: function()
|
34
|
+
{
|
35
|
+
var m = this.model;
|
36
|
+
var tbody = $('<tbody/>');
|
37
|
+
$(m.attributes).each(function(i, a) {
|
38
|
+
if (a.type == 'hidden')
|
39
|
+
return;
|
40
|
+
tbody.append($('<tr/>')
|
41
|
+
.append($('<td/>').css('vertical-align', 'top').html(a.nice_name + ':'))
|
42
|
+
.append($('<td/>').css('vertical-align', 'top').attr('id', m.name + '_' + m.id + '_' + a.name + '_container')
|
43
|
+
.append(a.form().children())
|
44
|
+
)
|
45
|
+
);
|
46
|
+
});
|
47
|
+
var form = $('<form/>')
|
48
|
+
.attr('id', 'new_' + m.name + '_form')
|
49
|
+
.submit(function() { return false; })
|
50
|
+
.append($('<table/>').append(tbody))
|
51
|
+
.append($('<div/>').attr('id', this.message_div))
|
52
|
+
.append($('<p/>')
|
53
|
+
.append($('<input/>').attr('type', 'submit').val('Add ' + m.name).click(function() { m.ajax_add(); }))
|
54
|
+
.append($('<input/>').attr('type', 'button').val('Back').click(function() { window.location = m.listing_url; }))
|
55
|
+
);
|
56
|
+
return form;
|
57
|
+
},
|
58
|
+
|
59
|
+
// Runs after the add form has been displayed
|
60
|
+
post_add_display: function() {},
|
61
|
+
|
62
|
+
// Returns the form for editing a model or false for an embedded form.
|
63
|
+
edit: function()
|
64
|
+
{
|
65
|
+
var m = this.model;
|
66
|
+
|
67
|
+
var this2 = this;
|
68
|
+
var tbody = $('<tbody/>');
|
69
|
+
$(m.attributes).each(function(i, a) {
|
70
|
+
if (a.type == 'hidden')
|
71
|
+
return;
|
72
|
+
tbody.append($('<tr/>')
|
73
|
+
.append($('<td/>').css('vertical-align', 'top').html(a.nice_name + ':'))
|
74
|
+
.append($('<td/>').css('vertical-align', 'top').attr('id', m.name + '_' + m.id + '_' + a.name + '_container'))
|
75
|
+
);
|
76
|
+
});
|
77
|
+
|
78
|
+
var div = $('<div/>')
|
79
|
+
.append($('<table/>').append(tbody))
|
80
|
+
.append($('<div/>').attr('id', this.message))
|
81
|
+
.append($('<p/>')
|
82
|
+
.append($('<input/>').attr('type', 'button').val('Back').click(function() { window.location = m.listing_url; }))
|
83
|
+
.append(' ')
|
84
|
+
.append($('<input/>').attr('type', 'button').val('Delete ' + m.name).click(function() { m.ajax_delete(); }))
|
85
|
+
);
|
86
|
+
return div;
|
87
|
+
},
|
88
|
+
|
89
|
+
// Runs after the edit form has been displayed
|
90
|
+
post_edit_display: function() {},
|
91
|
+
|
92
|
+
listing_view: function()
|
93
|
+
{
|
94
|
+
var tr = $('<tr/>');
|
95
|
+
var m = this.model;
|
96
|
+
$(this.model.attributes).each(function(i, a) {
|
97
|
+
if (a.type == 'hidden') return;
|
98
|
+
tr.append(
|
99
|
+
$('<td/>')
|
100
|
+
.attr('id', m.name + '_' + m.id + '_' + a.name + '_container')
|
101
|
+
.append(a.view())
|
102
|
+
);
|
103
|
+
});
|
104
|
+
return tr;
|
105
|
+
},
|
106
|
+
|
107
|
+
post_listing_view_display: function() {},
|
108
|
+
|
109
|
+
// Returns a listing table of models or false for an embedded listing
|
110
|
+
listing_form: function()
|
111
|
+
{
|
112
|
+
var m = this.model;
|
113
|
+
var count = m.unhidden_attribute_count();
|
114
|
+
var tr = $('<tr/>').attr('id', m.name + '_' + m.id + '_listing_container');
|
115
|
+
$(this.model.attributes).each(function(i, a) {
|
116
|
+
if (a.type == 'hidden')
|
117
|
+
return;
|
118
|
+
var c = '';
|
119
|
+
if (i == 0) c = 'edit_listing_first_cell';
|
120
|
+
else if (i == count-1) c = 'edit_listing_last_cell';
|
121
|
+
else c = 'edit_listing_cell';
|
122
|
+
|
123
|
+
tr.append($('<td/>')
|
124
|
+
.css('vertical-align', 'top')
|
125
|
+
.addClass(c)
|
126
|
+
.attr('id', m.name + '_' + m.id + '_' + a.name + '_container')
|
127
|
+
);
|
128
|
+
});
|
129
|
+
return tr;
|
130
|
+
},
|
131
|
+
|
132
|
+
// Runs after the listing has been displayed
|
133
|
+
post_listing_form_display: function() {},
|
134
|
+
|
135
|
+
listing_view: function()
|
136
|
+
{
|
137
|
+
var m = this.model;
|
138
|
+
var tr = $('<tr/>').attr('id', m.name + '_' + m.id + '_listing_container');
|
139
|
+
$(this.model.attributes).each(function(i, a) {
|
140
|
+
if (a.type == 'hidden')
|
141
|
+
return;
|
142
|
+
tr.append($('<td/>').css('vertical-align', 'top').attr('id', m.name + '_' + m.id + '_' + a.name + '_container'));
|
143
|
+
});
|
144
|
+
return tr;
|
145
|
+
},
|
146
|
+
|
147
|
+
post_listing_view_display: function() {},
|
148
|
+
|
149
|
+
// Gets the latest rows for the listing
|
150
|
+
refresh_listing_models: function(done)
|
151
|
+
{
|
152
|
+
var this2 = this;
|
153
|
+
var obj = Model.parse_url(this.model.listing_url);
|
154
|
+
$.ajax({
|
155
|
+
url: obj.url,
|
156
|
+
type: obj.verb,
|
157
|
+
success: function(models) {
|
158
|
+
this2.refresh_listing_models_helper(models);
|
159
|
+
done();
|
160
|
+
},
|
161
|
+
error: function() {
|
162
|
+
this2.ajax_error('Error');
|
163
|
+
}
|
164
|
+
});
|
165
|
+
},
|
166
|
+
|
167
|
+
refresh_listing_models_helper: function(models)
|
168
|
+
{
|
169
|
+
var this2 = this;
|
170
|
+
this.listing_models = [];
|
171
|
+
$(models).each(function(i, m) {
|
172
|
+
|
173
|
+
var attribs = [];
|
174
|
+
$(m.attributes).each(function(i, a) {
|
175
|
+
|
176
|
+
// Find the original attribute with the same name
|
177
|
+
var attrib = false;
|
178
|
+
$(this2.model.attributes_original).each(function(j, a2) {
|
179
|
+
if (a2.name == a.name)
|
180
|
+
{
|
181
|
+
attrib = $.extend(true, {}, a2);
|
182
|
+
return false;
|
183
|
+
}
|
184
|
+
});
|
185
|
+
|
186
|
+
// Copy new data into the original attribute hash
|
187
|
+
for (var thing in a)
|
188
|
+
attrib[thing] = a[thing];
|
189
|
+
attrib.base = this2.model.name + '_' + m.id + '_' + attrib.name;
|
190
|
+
|
191
|
+
attribs.push(attrib);
|
192
|
+
});
|
193
|
+
var params = {
|
194
|
+
name: this2.model.name,
|
195
|
+
id: m.id,
|
196
|
+
form: this2.class_name,
|
197
|
+
attributes: attribs,
|
198
|
+
create_url: this2.model.create_url,
|
199
|
+
update_url: this2.model.update_url,
|
200
|
+
delete_url: this2.model.delete_url,
|
201
|
+
listing_url: this2.model.listing_url,
|
202
|
+
listing_edit: this2.model.listing_edit,
|
203
|
+
listing_delete: this2.model.listing_delete,
|
204
|
+
listing_empty_text: this2.model.listing_empty_text,
|
205
|
+
is_listing: true
|
206
|
+
};
|
207
|
+
var m2 = new Model(params);
|
208
|
+
this2.listing_models.push(m2);
|
209
|
+
});
|
210
|
+
},
|
211
|
+
|
212
|
+
// Returns the values of the add form that will be sent to model.ajax_add
|
213
|
+
add_values: function()
|
214
|
+
{
|
215
|
+
var m = this.model;
|
216
|
+
var data = {};
|
217
|
+
$(m.attributes).each(function(i, a) {
|
218
|
+
data[a.name] = a.form_value();
|
219
|
+
});
|
220
|
+
return data;
|
221
|
+
},
|
222
|
+
|
223
|
+
// Show a confirmation screen
|
224
|
+
confirm: function(params)
|
225
|
+
{
|
226
|
+
var this2 = this;
|
227
|
+
$('#' + this.message).empty()
|
228
|
+
.append($('<div/>')
|
229
|
+
.addClass('note2 error')
|
230
|
+
.append($('<p/>').append(params.message))
|
231
|
+
.append($('<p/>')
|
232
|
+
.append($('<input />').attr('type', 'button').val('Yes').click(params.yes))
|
233
|
+
.append(" ")
|
234
|
+
.append($('<input />').attr('type', 'button').val('No').click(function() { $('#' + this2.message).empty(); }))
|
235
|
+
)
|
236
|
+
);
|
237
|
+
},
|
238
|
+
|
239
|
+
ajax_success: function(resp)
|
240
|
+
{
|
241
|
+
if (resp.text) $('#' + this.message).empty().append($('<p/>').addClass('note' ).html(resp.text));
|
242
|
+
else if (resp.success) $('#' + this.message).empty().append($('<p/>').addClass('note success').html(resp.success));
|
243
|
+
else if (resp.error) $('#' + this.message).empty().append($('<p/>').addClass('note error' ).html(resp.error));
|
244
|
+
else if (resp.flash) $('#' + this.message).empty().append($('<p/>').html(resp.flash).delay(2000).fadeOut().delay(2000).queue(function() { $(this).remove(); }));
|
245
|
+
else if (resp.redirect) window.location = resp.redirect;
|
246
|
+
else $('#' + this.message).empty();
|
247
|
+
},
|
248
|
+
|
249
|
+
ajax_error: function(str) { this.error(str); },
|
250
|
+
|
251
|
+
// Notes
|
252
|
+
loading: function(str) { this.show_message('loading' , str); },
|
253
|
+
note: function(str) { this.show_message('note' , str); },
|
254
|
+
success: function(str) { this.show_message('note success' , str); },
|
255
|
+
error: function(str) { this.show_message('note error' , str); },
|
256
|
+
show_message: function(class_names, str) { $('#' + this.message).empty().append($('<p/>').addClass(class_names).html(str)); }
|
257
|
+
});
|