/
ajax_scaffold.rb
208 lines (166 loc) · 6.02 KB
/
ajax_scaffold.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
module AjaxScaffold
class ScaffoldColumn
attr_reader :name, :eval, :sort_sql, :label
# Only options[:name] is required. It will infer the eval and sort values
# based on the given class.
def initialize(klass, options)
@name = options[:name]
@eval = options[:eval].nil? ? Inflector.tableize(klass.to_s).singularize + "." + @name : options[:eval]
@label = options[:label].nil? ? Inflector.titleize(@name) : options[:label]
@sortable = options[:sortable].nil? ? true : options[:sortable]
@sort_sql = options[:sort_sql].nil? ? klass.table_name + "." + @name : options[:sort_sql] unless !@sortable
end
def sortable?
@sortable
end
end
module Model
module ClassMethods
def build_scaffold_columns
scaffold_columns = Array.new
content_columns.each do |column|
scaffold_columns << ScaffoldColumn.new(self, { :name => column.name })
end
scaffold_columns
end
def build_scaffold_columns_hash
scaffold_columns_hash = Hash.new
scaffold_columns.each do |scaffold_column|
scaffold_columns_hash[scaffold_column.name] = scaffold_column
end
scaffold_columns_hash
end
end
end
module Common
def current_sort(params)
session[params[:scaffold_id]][:sort]
end
def current_sort_direction(params)
session[params[:scaffold_id]][:sort_direction]
end
end
module Controller
include AjaxScaffold::Common
def default_per_page
25
end
def clear_flashes
#We want to clear flashes so they don't appear on a page reload
if request.xhr?
flash.keys.each do |flash_key|
flash[flash_key] = nil
end
end
end
def store_or_get_from_session(id_key, value_key)
session[id_key][value_key] = params[value_key] if !params[value_key].nil?
params[value_key] ||= session[id_key][value_key]
end
def update_params(options)
@scaffold_id = params[:scaffold_id] ||= options[:default_scaffold_id]
session[@scaffold_id] ||= {:sort => options[:default_sort], :sort_direction => options[:default_sort_direction], :page => 1}
store_or_get_from_session(@scaffold_id, :sort)
store_or_get_from_session(@scaffold_id, :sort_direction)
store_or_get_from_session(@scaffold_id, :page)
end
end
module Helper
include AjaxScaffold::Common
def format_column(column_value)
if column_empty?(column_value)
empty_column_text
elsif column_value.instance_of? Time
format_time(column_value)
elsif column_value.instance_of? Date
format_date(column_value)
else
column_value.to_s
end
end
def format_time(time)
time.strftime("%m/%d/%Y %I:%M %p")
end
def format_date(date)
date.strftime("%m/%d/%Y")
end
def column_empty?(column_value)
column_value.nil? || (column_value.empty? rescue false)
end
def empty_column_text
"-"
end
# Generates a temporary id for creating a new element
def generate_temporary_id
(Time.now.to_f*1000).to_i.to_s
end
def pagination_ajax_links(paginator, params)
pagination_links_each(paginator, {}) do |n|
link_to_remote n,
{ :url => params.merge(:page => n ),
:loading => "Element.show('#{loading_indicator_id(params.merge(:action => 'pagination'))}');",
:update => scaffold_content_id(params) },
{ :href => url_for(params.merge(:page => n )) }
end
end
def column_sort_direction(column_name, params)
column_name && current_sort_direction(params) == "asc" ? "desc" : "asc"
end
def column_class(column_name, column_value, sort_column)
class_name = String.new
class_name += "empty " if column_empty?(column_value)
class_name += "sorted " if (!sort_column.nil? && column_name == sort_column)
class_name
end
def loading_indicator_tag(options)
image_filename = "indicator.gif"
"<img src=\"/images/#{image_filename}\" style=\"display: none;\" id=\"#{loading_indicator_id(options)}\" alt=\"loading indicator\" class=\"loading-indicator\" />"
end
# The following are a bunch of helper methods to produce the common scaffold view id's
def scaffold_content_id(options)
"#{options[:scaffold_id]}-content"
end
def scaffold_column_header_id(options)
"#{options[:scaffold_id]}-#{options[:column_name]}-column"
end
def scaffold_tbody_id(options)
"#{options[:scaffold_id]}-tbody"
end
def scaffold_messages_id(options)
"#{options[:scaffold_id]}-messages"
end
def empty_message_id(options)
"#{options[:scaffold_id]}-empty-message"
end
def element_row_id(options)
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-row"
end
def element_cell_id(options)
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-cell"
end
def element_form_id(options)
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-form"
end
def loading_indicator_id(options)
if options[:id].nil?
"#{options[:scaffold_id]}-#{options[:action]}-loading-indicator"
else
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-loading-indicator"
end
end
def element_messages_id(options)
"#{options[:scaffold_id]}-#{options[:action]}-#{options[:id]}-messages"
end
end
end
class ActiveRecord::Base
extend AjaxScaffold::Model::ClassMethods
@scaffold_columns = nil
def self.scaffold_columns
@scaffold_columns ||= build_scaffold_columns
end
@scaffold_columns_hash = nil
def self.scaffold_columns_hash
@scaffold_columns_hash ||= build_scaffold_columns_hash
end
end