ajax_scaffold_generator 2.2.1 → 3.0.0
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/README +1 -1
- data/ajax_scaffold_generator.rb +97 -22
- data/templates/{style.css → ajax_scaffold.css} +451 -364
- data/templates/ajax_scaffold.js +126 -0
- data/templates/ajax_scaffold_helper.rb +95 -0
- data/templates/arrow_down.gif +0 -0
- data/templates/arrow_up.gif +0 -0
- data/templates/controller.rb +93 -42
- data/templates/error.gif +0 -0
- data/templates/form_scaffolding.rhtml +1 -1
- data/templates/helper.rb +2 -6
- data/templates/indicator.gif +0 -0
- data/templates/information.gif +0 -0
- data/templates/layout.rhtml +2 -1
- data/templates/lib_ajax_scaffold_util.rb +26 -0
- data/templates/lib_content_column_patch.rb +10 -0
- data/templates/partial_column_headings.rhtml +12 -0
- data/templates/partial_form_messages.rhtml +5 -0
- data/templates/partial_item.rhtml +30 -21
- data/templates/partial_messages.rhtml +10 -0
- data/templates/partial_new_edit.rhtml +38 -0
- data/templates/partial_pagination_links.rhtml +14 -0
- data/templates/rjs_create.rjs +17 -0
- data/templates/rjs_destroy.rjs +10 -0
- data/templates/rjs_edit.rjs +16 -0
- data/templates/rjs_new.rjs +14 -0
- data/templates/rjs_update.rjs +17 -0
- data/templates/view_component.rhtml +51 -0
- data/templates/view_list.rhtml +1 -59
- data/templates/warning.gif +0 -0
- metadata +22 -8
- data/templates/partial_form_errors.rhtml +0 -9
- data/templates/script.js +0 -423
- data/templates/view_edit.rhtml +0 -36
- data/templates/view_index.rhtml +0 -1
- data/templates/view_new.rhtml +0 -33
@@ -0,0 +1,126 @@
|
|
1
|
+
/*
|
2
|
+
AjaxScaffoldGenerator version 3.0.0
|
3
|
+
(c) 2006 Richard White <rrwhite@gmail.com>
|
4
|
+
|
5
|
+
AjaxScaffoldGenerator is freely distributable under the terms of an MIT-style license.
|
6
|
+
|
7
|
+
For details, see the AjaxScaffoldGenerator web site: http://www.ajaxscaffold.com/
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*
|
11
|
+
* The following is a cross browser way to move around <tr> elements in a <table> or <tbody>
|
12
|
+
*/
|
13
|
+
|
14
|
+
var Abstract = new Object();
|
15
|
+
Abstract.Table = function() {};
|
16
|
+
Abstract.Table.prototype = {
|
17
|
+
tagTest: function(element, tagName) {
|
18
|
+
return $(element).tagName.toLowerCase() == tagName.toLowerCase();
|
19
|
+
}
|
20
|
+
};
|
21
|
+
|
22
|
+
Abstract.TableRow = function() {};
|
23
|
+
Abstract.TableRow.prototype = Object.extend(new Abstract.Table(), {
|
24
|
+
initialize: function(targetTableRow, sourceTableRow) {
|
25
|
+
try {
|
26
|
+
var sourceTableRow = $(sourceTableRow);
|
27
|
+
var targetTableRow = $(targetTableRow);
|
28
|
+
|
29
|
+
if (targetTableRow == null || !this.tagTest(targetTableRow,'tr')
|
30
|
+
|| sourceTableRow == null || !this.tagTest(sourceTableRow,'tr')) {
|
31
|
+
throw("TableRow: both parameters must be a <tr> tag.");
|
32
|
+
}
|
33
|
+
|
34
|
+
var tableOrTbody = this.findParentTableOrTbody(targetTableRow);
|
35
|
+
|
36
|
+
var newRow = tableOrTbody.insertRow(this.getNewRowIndex(targetTableRow) - this.getRowOffset(tableOrTbody));
|
37
|
+
newRow.parentNode.replaceChild(sourceTableRow, newRow);
|
38
|
+
|
39
|
+
} catch (e) {
|
40
|
+
alert(e);
|
41
|
+
}
|
42
|
+
},
|
43
|
+
getRowOffset: function(tableOrTbody) {
|
44
|
+
//If we are inserting into a tablebody we would need figure out the rowIndex of the first
|
45
|
+
// row in that tbody and subtract that offset from the new row index
|
46
|
+
var rowOffset = 0;
|
47
|
+
if (this.tagTest(tableOrTbody,'tbody')) {
|
48
|
+
rowOffset = tableOrTbody.rows[0].rowIndex;
|
49
|
+
}
|
50
|
+
return rowOffset;
|
51
|
+
},
|
52
|
+
findParentTableOrTbody: function(element) {
|
53
|
+
var element = $(element);
|
54
|
+
// Completely arbitrary value
|
55
|
+
var maxSearchDepth = 3;
|
56
|
+
var currentSearchDepth = 1;
|
57
|
+
var current = element;
|
58
|
+
while (currentSearchDepth <= maxSearchDepth) {
|
59
|
+
current = current.parentNode;
|
60
|
+
if (this.tagTest(current, 'tbody') || this.tagTest(current, 'table')) {
|
61
|
+
return current;
|
62
|
+
}
|
63
|
+
currentSearchDepth++;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
var TableRow = new Object();
|
69
|
+
|
70
|
+
TableRow.MoveBefore = Class.create();
|
71
|
+
TableRow.MoveBefore.prototype = Object.extend(new Abstract.TableRow(), {
|
72
|
+
getNewRowIndex: function(target) {
|
73
|
+
return target.rowIndex;
|
74
|
+
}
|
75
|
+
});
|
76
|
+
|
77
|
+
TableRow.MoveAfter = Class.create();
|
78
|
+
TableRow.MoveAfter.prototype = Object.extend(new Abstract.TableRow(), {
|
79
|
+
getNewRowIndex: function(target) {
|
80
|
+
return target.rowIndex+1;
|
81
|
+
}
|
82
|
+
});
|
83
|
+
|
84
|
+
/*
|
85
|
+
* The following are simple utility methods
|
86
|
+
*/
|
87
|
+
|
88
|
+
var AjaxScaffold = {
|
89
|
+
stripe: function(tableBody) {
|
90
|
+
var even = false;
|
91
|
+
var tableBody = $(tableBody);
|
92
|
+
var tableRows = tableBody.getElementsByTagName("tr");
|
93
|
+
var length = tableBody.rows.length;
|
94
|
+
|
95
|
+
for (var i = 0; i < length; i++) {
|
96
|
+
var tableRow = tableBody.rows[i];
|
97
|
+
//Make sure to skip rows that are create or edit rows or messages
|
98
|
+
if (!Element.hasClassName(tableRow, "create")
|
99
|
+
&& !Element.hasClassName(tableRow, "update")) {
|
100
|
+
|
101
|
+
if (even) {
|
102
|
+
Element.addClassName(tableRow, "even");
|
103
|
+
} else {
|
104
|
+
Element.removeClassName(tableRow, "even");
|
105
|
+
}
|
106
|
+
even = !even;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
},
|
110
|
+
displayMessageIfEmpty: function(tableBody, emptyMessageElement) {
|
111
|
+
// Check to see if this was the last element in the list
|
112
|
+
if ($(tableBody).rows.length == 0) {
|
113
|
+
Element.show($(emptyMessageElement));
|
114
|
+
}
|
115
|
+
},
|
116
|
+
removeSortClasses: function(scaffoldId) {
|
117
|
+
$$('#' + scaffoldId + ' td.sorted').each(function(element) {
|
118
|
+
Element.removeClassName(element, "sorted");
|
119
|
+
});
|
120
|
+
$$('#' + scaffoldId + ' th.sorted').each(function(element) {
|
121
|
+
Element.removeClassName(element, "sorted");
|
122
|
+
Element.removeClassName(element, "asc");
|
123
|
+
Element.removeClassName(element, "desc");
|
124
|
+
});
|
125
|
+
}
|
126
|
+
}
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module AjaxScaffoldHelper
|
2
|
+
|
3
|
+
def column_value(data_object, column)
|
4
|
+
column_value = data_object.send(column.name)
|
5
|
+
|
6
|
+
if column_value.instance_of? Time
|
7
|
+
column_value = format_time(column_value)
|
8
|
+
elsif column_value.instance_of? Date
|
9
|
+
column_value = format_date(column_value)
|
10
|
+
end
|
11
|
+
|
12
|
+
column_value
|
13
|
+
end
|
14
|
+
|
15
|
+
def format_time(time)
|
16
|
+
time.strftime("%m/%d/%Y %I:%M %p")
|
17
|
+
end
|
18
|
+
|
19
|
+
def format_date(date)
|
20
|
+
date.strftime("%m/%d/%Y")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Generates a temporary id for creating a new element
|
24
|
+
def generate_temporary_id
|
25
|
+
(Time.now.to_f*1000).to_i.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def pagination_ajax_links(paginator, params)
|
29
|
+
params = params.merge(:controller => 'widgets', :action => 'list')
|
30
|
+
pagination_links_each(paginator, {}) do |n|
|
31
|
+
link_to_remote n,
|
32
|
+
{ :url => params.merge(:page => n ),
|
33
|
+
:update => scaffold_content_id(params) },
|
34
|
+
{ :href => url_for(params.merge(:page => n )) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def column_class(column_name, column_value, sort_column)
|
39
|
+
class_name = String.new
|
40
|
+
class_name += "empty " if column_empty?(column_value)
|
41
|
+
class_name += "sorted " if (!sort_column.nil? && column_name == sort_column)
|
42
|
+
class_name
|
43
|
+
end
|
44
|
+
|
45
|
+
def column_empty?(column_value)
|
46
|
+
column_value.nil? || (column_value.empty? rescue false)
|
47
|
+
end
|
48
|
+
|
49
|
+
def loading_indicator_tag(options)
|
50
|
+
"<img src=\"/images/indicator.gif\" style=\"display: none;\" id=\"#{loading_indicator_id(options)}\" alt=\"loading indicator\" class=\"loading-indicator\" />"
|
51
|
+
end
|
52
|
+
|
53
|
+
# The following are a bunch of helper methods to produce the common scaffold view id's
|
54
|
+
|
55
|
+
def scaffold_content_id(options)
|
56
|
+
"#{options[:scaffold_id]}-content"
|
57
|
+
end
|
58
|
+
|
59
|
+
def scaffold_tbody_id(options)
|
60
|
+
"#{options[:scaffold_id]}-tbody"
|
61
|
+
end
|
62
|
+
|
63
|
+
def scaffold_messages_id(options)
|
64
|
+
"#{options[:scaffold_id]}-messages"
|
65
|
+
end
|
66
|
+
|
67
|
+
def empty_message_id(options)
|
68
|
+
"#{options[:scaffold_id]}-empty-message"
|
69
|
+
end
|
70
|
+
|
71
|
+
def element_row_id(options)
|
72
|
+
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def element_cell_id(options)
|
76
|
+
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-cell"
|
77
|
+
end
|
78
|
+
|
79
|
+
def element_form_id(options)
|
80
|
+
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-form"
|
81
|
+
end
|
82
|
+
|
83
|
+
def loading_indicator_id(options)
|
84
|
+
if options[:id].nil?
|
85
|
+
"#{options[:scaffold_id]}-#{options[:action]}-loading-indicator"
|
86
|
+
else
|
87
|
+
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-loading-indicator"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def element_messages_id(options)
|
92
|
+
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-messages"
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
Binary file
|
Binary file
|
data/templates/controller.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
class <%= controller_class_name %>Controller < ApplicationController
|
2
|
-
|
2
|
+
include AjaxScaffoldUtil
|
3
|
+
|
4
|
+
after_filter :clear_flashes
|
5
|
+
|
3
6
|
<% unless suffix -%>
|
4
7
|
def index
|
5
|
-
|
8
|
+
redirect_to :action => 'list'
|
6
9
|
end
|
7
10
|
<% end -%>
|
8
11
|
|
@@ -15,64 +18,112 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
15
18
|
# If you have multiple scaffolds on the same view then you will want to change this to
|
16
19
|
# to whatever controller/action shows all the views
|
17
20
|
# (ex: redirect_to :controller => 'AdminConsole', :action => 'index')
|
18
|
-
redirect_to :action => '
|
21
|
+
redirect_to :action => 'list'
|
19
22
|
end
|
20
23
|
|
21
|
-
def list
|
22
|
-
@<%= plural_name %> = <%= model_name %>.find :all
|
23
|
-
render :layout => false
|
24
|
+
def list
|
24
25
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
|
27
|
+
# All posts to change scaffold level variables like sort values or page changes go through this action
|
28
|
+
def component_update
|
29
29
|
if request.xhr?
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# If this is an AJAX request then we just want to delegate to the component to rerender itself
|
31
|
+
component
|
32
|
+
else
|
33
|
+
# If this is from a client without javascript we want to update the session parameters and then delegate
|
34
|
+
# back to whatever page is displaying the scaffold, which will then rerender all scaffolds with these update parameters
|
35
|
+
update_params :default_scaffold_id => "<%= singular_name %>", :default_sort => "id", :default_sort_direction => "asc"
|
36
|
+
return_to_main
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def component
|
41
|
+
update_params :default_scaffold_id => "<%= singular_name %>", :default_sort => "id", :default_sort_direction => "asc"
|
33
42
|
|
34
|
-
|
43
|
+
@sort_by = session[params[:scaffold_id]][:sort] + " " + session[params[:scaffold_id]][:sort_direction]
|
44
|
+
@paginator, @<%= plural_name %> = paginate(:<%= plural_name %>, :order_by => @sort_by, :per_page => 25)
|
35
45
|
|
36
|
-
|
37
|
-
# render :inline => "Error text goes here", :layout => false, :status => 500
|
38
|
-
end
|
46
|
+
render :action => "component", :layout => false
|
39
47
|
end
|
40
48
|
|
41
|
-
def
|
42
|
-
@<%= singular_name %> = <%= model_name %>.new
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def new
|
50
|
+
@<%= singular_name %> = <%= model_name %>.new
|
51
|
+
@successful = true
|
52
|
+
|
53
|
+
return if request.xhr?
|
54
|
+
|
55
|
+
# Javascript disabled fallback
|
56
|
+
if @successful
|
57
|
+
@options = { :action => "create" }
|
58
|
+
render :partial => "new_edit", :layout => true
|
59
|
+
else
|
60
|
+
return_to_main
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create
|
65
|
+
begin
|
66
|
+
@<%= singular_name %> = <%= model_name %>.new(params[:<%= singular_name %>])
|
67
|
+
@successful = @<%= singular_name %>.save
|
68
|
+
rescue
|
69
|
+
flash[:error], @successful = $!.to_s, false
|
70
|
+
end
|
71
|
+
|
72
|
+
return if request.xhr?
|
73
|
+
if @successful
|
74
|
+
return_to_main
|
51
75
|
else
|
52
|
-
|
53
|
-
render :
|
76
|
+
@options = { :scaffold_id => params[:scaffold_id], :action => "create" }
|
77
|
+
render :partial => 'new_edit', :layout => true
|
54
78
|
end
|
55
79
|
end
|
56
80
|
|
57
|
-
def edit
|
58
|
-
|
59
|
-
|
81
|
+
def edit
|
82
|
+
begin
|
83
|
+
@<%= singular_name %> = <%= model_name %>.find(params[:id])
|
84
|
+
@successful = !@<%= singular_name %>.nil?
|
85
|
+
rescue
|
86
|
+
flash[:error], @successful = $!.to_s, false
|
87
|
+
end
|
88
|
+
|
89
|
+
return if request.xhr?
|
90
|
+
|
91
|
+
if @successful
|
92
|
+
@options = { :scaffold_id => params[:scaffold_id], :action => "update", :id => params[:id] }
|
93
|
+
render :partial => 'new_edit', :layout => true
|
94
|
+
else
|
95
|
+
return_to_main
|
96
|
+
end
|
60
97
|
end
|
61
98
|
|
62
99
|
def update
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
100
|
+
begin
|
101
|
+
@<%= singular_name %> = <%= model_name %>.find(params[:id])
|
102
|
+
@successful = @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
|
103
|
+
rescue
|
104
|
+
flash[:error], @successful = $!.to_s, false
|
105
|
+
end
|
106
|
+
|
107
|
+
return if request.xhr?
|
108
|
+
|
109
|
+
if @successful
|
110
|
+
return_to_main
|
67
111
|
else
|
68
|
-
|
69
|
-
render :
|
112
|
+
@options = { :action => "update" }
|
113
|
+
render :partial => 'new_edit', :layout => true
|
70
114
|
end
|
71
115
|
end
|
72
116
|
|
73
|
-
def destroy
|
74
|
-
|
75
|
-
|
76
|
-
|
117
|
+
def destroy
|
118
|
+
begin
|
119
|
+
@successful = <%= model_name %>.find(params[:id]).destroy
|
120
|
+
rescue
|
121
|
+
flash[:error], @successful = $!.to_s, false
|
122
|
+
end
|
123
|
+
|
124
|
+
return if request.xhr?
|
125
|
+
|
126
|
+
# Javascript disabled fallback
|
127
|
+
return_to_main
|
77
128
|
end
|
78
129
|
end
|
data/templates/error.gif
CHANGED
Binary file
|
@@ -1 +1 @@
|
|
1
|
-
<%= all_input_tags(@model_instance, @singular_name, {}) %>
|
1
|
+
<%= all_input_tags(@model_instance, @singular_name, { :exclude => %w(created_on created_at updated_on updated_at) }) %>
|
data/templates/helper.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
module <%= controller_class_name %>Helper
|
2
|
-
|
2
|
+
include AjaxScaffoldHelper
|
3
|
+
|
3
4
|
def num_columns
|
4
5
|
<%= model_name %>.content_columns.length + 1
|
5
6
|
end
|
6
|
-
|
7
|
-
# This can be moved into application_helper.rb
|
8
|
-
def loading_indicator_tag(scope,id)
|
9
|
-
"<img src=\"/images/indicator.gif\" style=\"display: none;\" id=\"#{scope}-#{id}-loading-indicator\" alt=\"loading indicator\" class=\"loading-indicator\" />"
|
10
|
-
end
|
11
7
|
|
12
8
|
end
|
data/templates/indicator.gif
CHANGED
Binary file
|
Binary file
|
data/templates/layout.rhtml
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
<head>
|
6
6
|
<title><%= Inflector.titleize(plural_name) %></title>
|
7
7
|
<%%= stylesheet_link_tag 'ajax_scaffold', :media => 'all' %>
|
8
|
-
<%%= javascript_include_tag
|
8
|
+
<%%= javascript_include_tag :defaults %>
|
9
|
+
<%%= javascript_include_tag 'rico_corner', 'ajax_scaffold' %>
|
9
10
|
</head>
|
10
11
|
<body>
|
11
12
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module AjaxScaffoldUtil
|
2
|
+
|
3
|
+
def clear_flashes
|
4
|
+
#We want to clear flashes so they don't appear on a page reload
|
5
|
+
if request.xhr?
|
6
|
+
flash.keys.each do |flash_key|
|
7
|
+
flash[flash_key] = nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def store_or_get_from_session(id_key, value_key)
|
13
|
+
session[id_key][value_key] = params[value_key] if !params[value_key].nil?
|
14
|
+
params[value_key] ||= session[id_key][value_key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_params(options)
|
18
|
+
@scaffold_id = params[:scaffold_id] ||= options[:default_scaffold_id]
|
19
|
+
session[@scaffold_id] ||= {:sort => options[:default_sort], :sort_direction => options[:default_sort_direction], :page => 1}
|
20
|
+
|
21
|
+
store_or_get_from_session(@scaffold_id, :sort)
|
22
|
+
store_or_get_from_session(@scaffold_id, :sort_direction)
|
23
|
+
store_or_get_from_session(@scaffold_id, :page)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|