data_grid 0.0.1 → 0.0.2
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/.rspec +3 -0
- data/CHANGELOG +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +1 -0
- data/app/assets/images/data_grid/calendar_view_month.png +0 -0
- data/app/assets/images/data_grid/csv.gif +0 -0
- data/app/assets/images/data_grid/delete.png +0 -0
- data/app/assets/images/data_grid/edit.png +0 -0
- data/app/assets/images/data_grid/no.png +0 -0
- data/app/assets/images/data_grid/sort_down.gif +0 -0
- data/app/assets/images/data_grid/sort_up.gif +0 -0
- data/app/assets/images/data_grid/yes.png +0 -0
- data/app/assets/javascripts/data_grid/data_grid.js +24 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar-setup.js +200 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar-setup_stripped.js +21 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar.js +1819 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar_original.js +1845 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar_patched.js +1819 -0
- data/app/assets/javascripts/data_grid/grid_calendar/calendar_stripped.js +14 -0
- data/app/assets/javascripts/data_grid/grid_calendar/img.gif +0 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-af.js +39 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-al.js +101 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-bg.js +124 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-big5-utf8.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-big5.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-br.js +108 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ca.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-cs-utf8.js +65 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-cs-win.js +65 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-da.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-de.js +124 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-du.js +45 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-el.js +89 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-en.js +127 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-es.js +129 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-fi.js +98 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-fr.js +125 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-he-utf8.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-hr-utf8.js +49 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-hr.js +0 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-hu.js +124 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-it.js +124 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-jp.js +45 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ko-utf8.js +120 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ko.js +120 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-lt-utf8.js +114 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-lt.js +114 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-lv.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-nl.js +73 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-no.js +114 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-pl-utf8.js +93 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-pl.js +56 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-pt.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ro.js +66 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ru.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-ru_win_.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-si.js +94 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-sk.js +99 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-sp.js +110 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-sv.js +93 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-tr.js +58 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/calendar-zh.js +119 -0
- data/app/assets/javascripts/data_grid/grid_calendar/lang/cn_utf8.js +123 -0
- data/app/assets/javascripts/data_grid/grid_calendar/menuarrow.gif +0 -0
- data/app/assets/javascripts/data_grid/grid_calendar/menuarrow2.gif +0 -0
- data/app/assets/stylesheets/data_grid/data_grid.css +90 -0
- data/app/assets/stylesheets/data_grid/data_grid_3_0.css +90 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-blue.css +233 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-blue2.css +237 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-brown.css +226 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-green.css +230 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-system.css +252 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-tas.css +240 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-win2k-1.css +272 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-win2k-2.css +272 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-win2k-cold-1.css +266 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/calendar-win2k-cold-2.css +272 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/img.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/menuarrow.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/menuarrow2.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/active-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/dark-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/hover-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/menuarrow.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/normal-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/rowhover-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/status-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/theme.css +236 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/title-bg.gif +0 -0
- data/app/assets/stylesheets/data_grid/grid_calendar/skins/aqua/today-bg.gif +0 -0
- data/app/views/data_grid/_data_grid.html.erb +101 -0
- data/config/locales/en.yml +10 -0
- data/data_grid.gemspec +27 -0
- data/lib/data_grid/column.rb +38 -0
- data/lib/data_grid/controller.rb +30 -0
- data/lib/data_grid/cookies_state_saver.rb +42 -0
- data/lib/data_grid/csv_exporter.rb +79 -0
- data/lib/data_grid/data_grid_logic.rb +175 -0
- data/lib/data_grid/data_source_array.rb +267 -0
- data/lib/data_grid/data_source_orm.rb +207 -0
- data/lib/data_grid/engine.rb +19 -0
- data/lib/data_grid/summaries.rb +34 -0
- data/lib/data_grid/version.rb +3 -0
- data/lib/data_grid/view_helpers.rb +271 -0
- data/lib/data_grid.rb +43 -0
- data/lib/generators/data_grid/copy_view_generator.rb +16 -0
- data/lib/generators/data_grid/install_generator.rb +29 -0
- data/lib/generators/templates/data_grid.rb +29 -0
- data/lib/generators/templates/stylesheets/data_grid/data_grid_3_0.css +90 -0
- data/spec/orm_spec.rb +57 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/active_record.rb +17 -0
- metadata +118 -5
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/* Distributed as part of The Coolest DHTML Calendar
|
|
2
|
+
Author: Mihai Bazon, www.bazon.net/mishoo
|
|
3
|
+
Copyright Dynarch.com 2005, www.dynarch.com
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* The main calendar widget. DIV containing a table. */
|
|
7
|
+
|
|
8
|
+
div.calendar { position: relative; }
|
|
9
|
+
|
|
10
|
+
.calendar, .calendar table {
|
|
11
|
+
border: 1px solid #bdb2bf;
|
|
12
|
+
font-size: 11px;
|
|
13
|
+
color: #000;
|
|
14
|
+
cursor: default;
|
|
15
|
+
background: url("normal-bg.gif");
|
|
16
|
+
font-family: "trebuchet ms",verdana,tahoma,sans-serif;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.calendar {
|
|
20
|
+
border-color: #797979;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* Header part -- contains navigation buttons and day names. */
|
|
24
|
+
|
|
25
|
+
.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
|
|
26
|
+
text-align: center; /* They are the navigation buttons */
|
|
27
|
+
padding: 2px; /* Make the buttons seem like they're pressing */
|
|
28
|
+
background: url("title-bg.gif") repeat-x 0 100%; color: #000;
|
|
29
|
+
font-weight: bold;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.calendar .nav {
|
|
33
|
+
font-family: verdana,tahoma,sans-serif;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.calendar .nav div {
|
|
37
|
+
background: transparent url("menuarrow.gif") no-repeat 100% 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.calendar thead tr { background: url("title-bg.gif") repeat-x 0 100%; color: #000; }
|
|
41
|
+
|
|
42
|
+
.calendar thead .title { /* This holds the current "month, year" */
|
|
43
|
+
font-weight: bold; /* Pressing it will take you to the current date */
|
|
44
|
+
text-align: center;
|
|
45
|
+
padding: 2px;
|
|
46
|
+
background: url("title-bg.gif") repeat-x 0 100%; color: #000;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.calendar thead .headrow { /* Row <TR> containing navigation buttons */
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.calendar thead .name { /* Cells <TD> containing the day names */
|
|
53
|
+
border-bottom: 1px solid #797979;
|
|
54
|
+
padding: 2px;
|
|
55
|
+
text-align: center;
|
|
56
|
+
color: #000;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.calendar thead .weekend { /* How a weekend day name shows in header */
|
|
60
|
+
color: #c44;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.calendar thead .hilite { /* How do the buttons in header appear when hover */
|
|
64
|
+
background: url("hover-bg.gif");
|
|
65
|
+
border-bottom: 1px solid #797979;
|
|
66
|
+
padding: 2px 2px 1px 2px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.calendar thead .active { /* Active (pressed) buttons in header */
|
|
70
|
+
background: url("active-bg.gif"); color: #fff;
|
|
71
|
+
padding: 3px 1px 0px 3px;
|
|
72
|
+
border-bottom: 1px solid #797979;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.calendar thead .daynames { /* Row <TR> containing the day names */
|
|
76
|
+
background: url("dark-bg.gif");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* The body part -- contains all the days in month. */
|
|
80
|
+
|
|
81
|
+
.calendar tbody .day { /* Cells <TD> containing month days dates */
|
|
82
|
+
font-family: verdana,tahoma,sans-serif;
|
|
83
|
+
width: 2em;
|
|
84
|
+
color: #000;
|
|
85
|
+
text-align: right;
|
|
86
|
+
padding: 2px 4px 2px 2px;
|
|
87
|
+
}
|
|
88
|
+
.calendar tbody .day.othermonth {
|
|
89
|
+
font-size: 80%;
|
|
90
|
+
color: #999;
|
|
91
|
+
}
|
|
92
|
+
.calendar tbody .day.othermonth.oweekend {
|
|
93
|
+
color: #f99;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.calendar table .wn {
|
|
97
|
+
padding: 2px 3px 2px 2px;
|
|
98
|
+
border-right: 1px solid #797979;
|
|
99
|
+
background: url("dark-bg.gif");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.calendar tbody .rowhilite td,
|
|
103
|
+
.calendar tbody .rowhilite td.wn {
|
|
104
|
+
background: url("rowhover-bg.gif");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.calendar tbody td.today { font-weight: bold; /* background: url("today-bg.gif") no-repeat 70% 50%; */ }
|
|
108
|
+
|
|
109
|
+
.calendar tbody td.hilite { /* Hovered cells <TD> */
|
|
110
|
+
background: url("hover-bg.gif");
|
|
111
|
+
padding: 1px 3px 1px 1px;
|
|
112
|
+
border: 1px solid #bbb;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.calendar tbody td.active { /* Active (pressed) cells <TD> */
|
|
116
|
+
padding: 2px 2px 0px 2px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.calendar tbody td.weekend { /* Cells showing weekend days */
|
|
120
|
+
color: #c44;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.calendar tbody td.selected { /* Cell showing selected date */
|
|
124
|
+
font-weight: bold;
|
|
125
|
+
border: 1px solid #797979;
|
|
126
|
+
padding: 1px 3px 1px 1px;
|
|
127
|
+
background: url("active-bg.gif"); color: #fff;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.calendar tbody .disabled { color: #999; }
|
|
131
|
+
|
|
132
|
+
.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
|
|
133
|
+
visibility: hidden;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
|
|
137
|
+
display: none;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* The footer part -- status bar and "Close" button */
|
|
141
|
+
|
|
142
|
+
.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
|
|
143
|
+
text-align: center;
|
|
144
|
+
background: #565;
|
|
145
|
+
color: #fff;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
|
|
149
|
+
padding: 2px;
|
|
150
|
+
background: url("status-bg.gif") repeat-x 0 0; color: #000;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.calendar tfoot .hilite { /* Hover style for buttons in footer */
|
|
154
|
+
background: #afa;
|
|
155
|
+
border: 1px solid #084;
|
|
156
|
+
color: #000;
|
|
157
|
+
padding: 1px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
|
|
161
|
+
background: #7c7;
|
|
162
|
+
padding: 2px 0px 0px 2px;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Combo boxes (menus that display months/years for direct selection) */
|
|
166
|
+
|
|
167
|
+
.calendar .combo {
|
|
168
|
+
position: absolute;
|
|
169
|
+
display: none;
|
|
170
|
+
top: 0px;
|
|
171
|
+
left: 0px;
|
|
172
|
+
width: 4em;
|
|
173
|
+
cursor: default;
|
|
174
|
+
border-width: 0 1px 1px 1px;
|
|
175
|
+
border-style: solid;
|
|
176
|
+
border-color: #797979;
|
|
177
|
+
background: url("normal-bg.gif"); color: #000;
|
|
178
|
+
z-index: 100;
|
|
179
|
+
font-size: 90%;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.calendar .combo .label,
|
|
183
|
+
.calendar .combo .label-IEfix {
|
|
184
|
+
text-align: center;
|
|
185
|
+
padding: 1px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.calendar .combo .label-IEfix {
|
|
189
|
+
width: 4em;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.calendar .combo .hilite {
|
|
193
|
+
background: url("hover-bg.gif"); color: #000;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.calendar .combo .active {
|
|
197
|
+
background: url("active-bg.gif"); color: #fff;
|
|
198
|
+
font-weight: bold;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.calendar td.time {
|
|
202
|
+
border-top: 1px solid #797979;
|
|
203
|
+
padding: 1px 0px;
|
|
204
|
+
text-align: center;
|
|
205
|
+
background: url("dark-bg.gif");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.calendar td.time .hour,
|
|
209
|
+
.calendar td.time .minute,
|
|
210
|
+
.calendar td.time .ampm {
|
|
211
|
+
padding: 0px 5px 0px 6px;
|
|
212
|
+
font-weight: bold;
|
|
213
|
+
background: url("normal-bg.gif"); color: #000;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.calendar td.time .hour,
|
|
217
|
+
.calendar td.time .minute {
|
|
218
|
+
font-family: monospace;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.calendar td.time .ampm {
|
|
222
|
+
text-align: center;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.calendar td.time .colon {
|
|
226
|
+
padding: 0px 2px 0px 3px;
|
|
227
|
+
font-weight: bold;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.calendar td.time span.hilite {
|
|
231
|
+
background: url("hover-bg.gif"); color: #000;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.calendar td.time span.active {
|
|
235
|
+
background: url("active-bg.gif"); color: #fff;
|
|
236
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<div class="data_grid">
|
|
2
|
+
<table class="data_grid" width="99%" cellpadding="0" cellspacing="0">
|
|
3
|
+
<tbody>
|
|
4
|
+
<tr>
|
|
5
|
+
<% data_grid.columns.each do |col| %>
|
|
6
|
+
<th class="<%= col.filter_active? ? "filter" : '' %>">
|
|
7
|
+
<%= data_grid_header(data_grid, col) %>
|
|
8
|
+
</th>
|
|
9
|
+
<% end %>
|
|
10
|
+
</tr>
|
|
11
|
+
|
|
12
|
+
<% if data_grid.filters? %>
|
|
13
|
+
<tr class="filters">
|
|
14
|
+
<% data_grid.columns.each do |col| %>
|
|
15
|
+
<td class="<%= col.filter_active? ? "filter" : '' %>">
|
|
16
|
+
<%= data_grid_filter(data_grid, col) %>
|
|
17
|
+
</td>
|
|
18
|
+
<% end %>
|
|
19
|
+
</tr>
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
22
|
+
<% if data_grid.out_data.empty? %>
|
|
23
|
+
<tr>
|
|
24
|
+
<td colspan="<%= data_grid.columns.size %>" class="grid_no_data data_grid_row">
|
|
25
|
+
<br />
|
|
26
|
+
<%= t('data_grid.no_data') %>
|
|
27
|
+
<br />
|
|
28
|
+
<br />
|
|
29
|
+
</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<% else %>
|
|
32
|
+
<% data_grid.out_data.each_with_index do |row, row_index| %>
|
|
33
|
+
<tr>
|
|
34
|
+
<% data_grid.columns.each_with_index do |col, col_index| %>
|
|
35
|
+
<% cell = row[col_index].is_a?(Array) ? row[col_index][0] : row[col_index] %>
|
|
36
|
+
<td class="<%= (row_index.odd? ? "odd " : '') + (col.css_class).to_s + ' data_grid_row' %>" style="<%= col.style ? "#{(data_grid.row_styles[row_index].to_s if data_grid.row_styles).to_s + ';' + col.style}" : data_grid.row_styles ? "#{data_grid.row_styles[row_index]}" : '' %>">
|
|
37
|
+
<%= col.formatter ? send("data_grid_formatter_#{col.formatter}", cell) : cell %>
|
|
38
|
+
</td>
|
|
39
|
+
<% end %>
|
|
40
|
+
</tr>
|
|
41
|
+
<% unless data_grid.hidden_row.nil? %>
|
|
42
|
+
<tr>
|
|
43
|
+
<td colspan="<%= data_grid.columns.size %>">
|
|
44
|
+
<%= data_grid.out_hidden_rows[row_index] %>
|
|
45
|
+
</td>
|
|
46
|
+
</tr>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% end %>
|
|
49
|
+
<% end %>
|
|
50
|
+
|
|
51
|
+
<% if data_grid.summary? %>
|
|
52
|
+
<tr class="summary">
|
|
53
|
+
<% data_grid.columns.each_with_index do |col, col_index| %>
|
|
54
|
+
<td>
|
|
55
|
+
<%= col.summary_formatter ? send("data_grid_formatter_#{col.summary_formatter}", data_grid.summaries[col_index].to_s) : data_grid.summaries[col_index].to_s %>
|
|
56
|
+
</td>
|
|
57
|
+
<% end %>
|
|
58
|
+
</tr>
|
|
59
|
+
<% end %>
|
|
60
|
+
|
|
61
|
+
<% if data_grid.global_summary? %>
|
|
62
|
+
<tr class="summary">
|
|
63
|
+
<% data_grid.columns.each_with_index do |col, col_index| %>
|
|
64
|
+
<td>
|
|
65
|
+
<%= col.summary_formatter ? send("data_grid_formatter_#{col.summary_formatter}", data_grid.global_summaries[col_index].to_s) : data_grid.global_summaries[col_index].to_s %>
|
|
66
|
+
</td>
|
|
67
|
+
<% end %>
|
|
68
|
+
</tr>
|
|
69
|
+
<% end %>
|
|
70
|
+
|
|
71
|
+
<% if data_grid.footer? %>
|
|
72
|
+
<tfoot>
|
|
73
|
+
<tr>
|
|
74
|
+
<td colspan="<%= data_grid.columns.size + 1 %>">
|
|
75
|
+
<div class="data_grid_fl">
|
|
76
|
+
<%= t('data_grid.results') %>:
|
|
77
|
+
<%= data_grid.entries_from %>
|
|
78
|
+
-
|
|
79
|
+
<%= data_grid.entries_to %>
|
|
80
|
+
/
|
|
81
|
+
<%= data_grid.total %>
|
|
82
|
+
</div>
|
|
83
|
+
<% if data_grid.export_enabled %>
|
|
84
|
+
<div class="data_grid_fl data_grid_lmargin">
|
|
85
|
+
<%= data_grid_export_link(data_grid) %>
|
|
86
|
+
</div>
|
|
87
|
+
<% end %>
|
|
88
|
+
<div class="data_grid_fr">
|
|
89
|
+
<%= t('data_grid.per_page') %>:
|
|
90
|
+
<%= data_grid_per_page_selector(data_grid) %>
|
|
91
|
+
</div>
|
|
92
|
+
<div class="pagination data_grid_fr">
|
|
93
|
+
<%= data_grid_pager(data_grid) %>
|
|
94
|
+
</div>
|
|
95
|
+
</td>
|
|
96
|
+
</tr>
|
|
97
|
+
</tfoot>
|
|
98
|
+
<% end %>
|
|
99
|
+
</tbody>
|
|
100
|
+
</table>
|
|
101
|
+
</div>
|
data/data_grid.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'data_grid/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "data_grid"
|
|
8
|
+
gem.version = DataGrid::VERSION
|
|
9
|
+
gem.authors = ["Krzysztof Kempiński"]
|
|
10
|
+
gem.email = ["kkempin@gmail.com"]
|
|
11
|
+
gem.description = %q{This gem generates configurable grids for Rails applications}
|
|
12
|
+
gem.summary = %q{data grid tool for Rails applications}
|
|
13
|
+
gem.homepage = "https://github.com/kkempin/data_grid"
|
|
14
|
+
|
|
15
|
+
gem.required_rubygems_version = ">= 1.3.6"
|
|
16
|
+
gem.add_dependency "rails", ">= 3.0"
|
|
17
|
+
gem.add_dependency "fastercsv"
|
|
18
|
+
gem.add_development_dependency "bundler", ">= 1.0.0"
|
|
19
|
+
gem.add_development_dependency "rspec", "~> 2.6"
|
|
20
|
+
gem.add_development_dependency "rspec-rails"
|
|
21
|
+
gem.add_development_dependency "sqlite3"
|
|
22
|
+
|
|
23
|
+
gem.files = `git ls-files`.split($/)
|
|
24
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
25
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
26
|
+
gem.require_paths = ["lib"]
|
|
27
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Class Column used to define colums in DataGrid
|
|
2
|
+
|
|
3
|
+
module DataGrid
|
|
4
|
+
class Column
|
|
5
|
+
|
|
6
|
+
attr_accessor :field, :title, :sortable, :sort_by, :filter, :filter_data, :filter_value, :filter_by, :style, :summary, :summary_formatter, :formatter, :hide_in_export, :css_class, :global_summary, :auto_filter_hash
|
|
7
|
+
|
|
8
|
+
def initialize(column_field, attrs = {})
|
|
9
|
+
self.sortable = attrs[:sortable] || DataGrid.column_sortable
|
|
10
|
+
self.title = attrs[:title]
|
|
11
|
+
self.field = column_field
|
|
12
|
+
self.sort_by = attrs[:sort_by] || self.field
|
|
13
|
+
self.filter = attrs[:filter]
|
|
14
|
+
self.filter_data = []
|
|
15
|
+
self.style = attrs[:style]
|
|
16
|
+
self.summary = attrs[:summary]
|
|
17
|
+
self.global_summary = attrs[:global_summary]
|
|
18
|
+
self.summary_formatter = attrs[:summary_formatter] || DataGrid.column_summary_formatter
|
|
19
|
+
self.formatter = attrs[:formatter]
|
|
20
|
+
self.filter_by = attrs[:filter_by] || self.field
|
|
21
|
+
self.hide_in_export = attrs[:hide_in_export] || false
|
|
22
|
+
self.css_class = attrs[:css_class] || ''
|
|
23
|
+
self.auto_filter_hash = attrs[:auto_filter_hash]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sort_field
|
|
27
|
+
if self.field.class == Symbol
|
|
28
|
+
return self.sort_by ? self.sort_by : self.field
|
|
29
|
+
else
|
|
30
|
+
return self.sort_by
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def filter_active?
|
|
35
|
+
!self.filter_value.to_s.split(DataGrid.range_separator).first.blank?
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module DataGrid
|
|
2
|
+
module Controller
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
def prepare_grid(&block)
|
|
6
|
+
# Build logic object
|
|
7
|
+
data_grid = DataGrid::DataGridLogic.new(:params => params)
|
|
8
|
+
block.call(data_grid)
|
|
9
|
+
|
|
10
|
+
# Restore state
|
|
11
|
+
if data_grid.state_saver and DataGrid.state_saver_method
|
|
12
|
+
require "data_grid/#{DataGrid.state_saver_method}_state_saver"
|
|
13
|
+
self.restore_state(data_grid)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Get and save data from params
|
|
17
|
+
data_grid.get_params_from_request
|
|
18
|
+
self.save_state(data_grid) if data_grid.state_saver
|
|
19
|
+
|
|
20
|
+
# Export on demand
|
|
21
|
+
if data_grid.export_enabled and params["export_#{data_grid.name}"]
|
|
22
|
+
require "data_grid/#{params["export_#{data_grid.name}"]}_exporter"
|
|
23
|
+
self.export(data_grid, data_grid.export_filename)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
data_grid
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# State consists of actual per_page, page, sort, sort direction of DataGrid
|
|
2
|
+
|
|
3
|
+
module DataGrid
|
|
4
|
+
module Controller
|
|
5
|
+
|
|
6
|
+
STATE_KEYS = [:per_page, :page, :sort, :sort_direction]
|
|
7
|
+
|
|
8
|
+
# Save grid state in cookies
|
|
9
|
+
def save_state(data_grid)
|
|
10
|
+
cookies["data_grid_state_#{data_grid.name}"] ||= {}
|
|
11
|
+
|
|
12
|
+
state = {}
|
|
13
|
+
STATE_KEYS.each do |key|
|
|
14
|
+
state[key] = data_grid.send(key)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
data_grid.columns.each_with_index do |col, col_index|
|
|
18
|
+
state[:columns] ||= {}
|
|
19
|
+
state[:columns][col_index] = col.filter_value
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
cookies["data_grid_state_#{data_grid.name}"] = Marshal.dump(state)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Restore state from cookies
|
|
26
|
+
def restore_state(data_grid)
|
|
27
|
+
if cookies["data_grid_state_#{data_grid.name}"]
|
|
28
|
+
state = Marshal.load(cookies["data_grid_state_#{data_grid.name}"])
|
|
29
|
+
STATE_KEYS.each do |key|
|
|
30
|
+
data_grid.send("#{key}=", state[key])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if state[:columns]
|
|
34
|
+
state[:columns].each_pair do |k, v|
|
|
35
|
+
data_grid.columns[k.to_i].filter_value = v if data_grid.columns[k.to_i]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Module used to export data to CSV
|
|
2
|
+
|
|
3
|
+
class CsvContent
|
|
4
|
+
include ActionView::Helpers::TagHelper
|
|
5
|
+
include ActionView::Helpers::FormTagHelper
|
|
6
|
+
|
|
7
|
+
def image_tag name, options = nil
|
|
8
|
+
''
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def link_to name, options=nil, extra=nil
|
|
12
|
+
name
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def raw s=''
|
|
16
|
+
s.to_s.gsub('<br />', ', ')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module DataGrid
|
|
22
|
+
module Controller
|
|
23
|
+
# Do CSV export
|
|
24
|
+
def export(data_grid, filename = DataGrid.export_filename)
|
|
25
|
+
require 'csv'
|
|
26
|
+
|
|
27
|
+
if request.env['HTTP_USER_AGENT'] =~ /msie/i
|
|
28
|
+
headers['Pragma'] = 'public'
|
|
29
|
+
headers["Content-type"] = "text/plain; charset=utf-8; header=present"
|
|
30
|
+
headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
|
|
31
|
+
headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
|
|
32
|
+
headers['Expires'] = "0"
|
|
33
|
+
else
|
|
34
|
+
headers["Content-Type"] ||= 'text/csv; charset=utf-8; header=present'
|
|
35
|
+
headers["Content-Disposition"] = "attachment; filename=\"#{filename}\""
|
|
36
|
+
end
|
|
37
|
+
data_grid.view_context = CsvContent.new
|
|
38
|
+
data_grid.prepare_data
|
|
39
|
+
|
|
40
|
+
csv_string = CSV.generate(:col_sep => ';') do |csv|
|
|
41
|
+
hide_column_indexes = []
|
|
42
|
+
cols = []
|
|
43
|
+
data_grid.columns.each_with_index do |col, i|
|
|
44
|
+
if col.hide_in_export
|
|
45
|
+
hide_column_indexes << i
|
|
46
|
+
else
|
|
47
|
+
cols << col.title
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
csv << cols
|
|
51
|
+
data_grid.out_data.each_with_index do |row, row_index|
|
|
52
|
+
data_row = []
|
|
53
|
+
row.each_with_index do |row_col, i|
|
|
54
|
+
next if (!data_grid.hidden_row.nil? and i == row.size-1)
|
|
55
|
+
unless hide_column_indexes.include?(i)
|
|
56
|
+
data_row << ((row_col.class == ActiveSupport::SafeBuffer) ? row_col.to_s.gsub(/<\/?[^>]*>/, "") : (row_col.class == String) ? row_col.gsub(/<\/?[^>]*>/, "") : row_col)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
unless data_grid.hidden_row.nil?
|
|
60
|
+
data_row << data_grid.out_hidden_rows[row_index]
|
|
61
|
+
end
|
|
62
|
+
csv << data_row
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if data_grid.summary?
|
|
66
|
+
data_row = []
|
|
67
|
+
data_grid.columns.each_with_index {|col, i|
|
|
68
|
+
data_row << data_grid.summaries[i].to_s unless hide_column_indexes.include?(i)
|
|
69
|
+
}
|
|
70
|
+
csv << data_row
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
render :text => csv_string
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|