ajax_scaffold_generator 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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