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.
@@ -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
@@ -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 => 'index'
21
+ redirect_to :action => 'list'
19
22
  end
20
23
 
21
- def list<%= suffix %>
22
- @<%= plural_name %> = <%= model_name %>.find :all
23
- render :layout => false
24
+ def list
24
25
  end
25
-
26
- def new<%= suffix %>
27
- @<%= singular_name %> = <%= model_name %>.new
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
- @temp_id = Time.new.to_i
31
- @headers['<%= singular_name %>-id'] = @temp_id
32
- @headers['Content-Type'] = 'text/html; charset=utf-8'
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
- render :layout => false
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
- # If you want to send an error message:
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 create<%= suffix %>
42
- @<%= singular_name %> = <%= model_name %>.new(params[:<%= singular_name %>])
43
- if @<%= singular_name %>.save
44
- if request.xhr?
45
- @headers['<%= singular_name %>-id'] = @<%= singular_name %>.id
46
- @headers['Content-Type'] = 'text/html; charset=utf-8'
47
- render :partial => '<%= singular_name %><%= suffix %>', :layout => false, :locals => { :hidden => true }
48
- else
49
- return_to_main
50
- end
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
- render :partial => 'form_errors', :layout => false, :status => 500 if request.xhr?
53
- render :action => 'new' if not request.xhr?
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<%= suffix %>
58
- @<%= singular_name %> = <%= model_name %>.find(params[:id])
59
- render :layout => false if request.xhr?
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
- @<%= singular_name %> = <%= model_name %>.find(params[:id])
64
- if @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
65
- render :partial => '<%= singular_name %><%= suffix %>', :layout => false, :locals => { :hidden => true } if request.xhr?
66
- return_to_main if not request.xhr?
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
- render :partial => 'form_errors', :layout => false, :status => 500 if request.xhr?
69
- render :action => 'edit' if not request.xhr?
112
+ @options = { :action => "update" }
113
+ render :partial => 'new_edit', :layout => true
70
114
  end
71
115
  end
72
116
 
73
- def destroy<%= suffix %>
74
- <%= model_name %>.find(params[:id]).destroy
75
- render :nothing => true if request.xhr?
76
- return_to_main if not request.xhr?
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
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) }) %>
@@ -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
Binary file
Binary file
@@ -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 'prototype', 'effects', 'rico_corner', 'ajax_scaffold' %>
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