fancygrid 1.1.0 → 2.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/CHANGELOG +9 -2
- data/Gemfile +6 -9
- data/Gemfile.lock +88 -103
- data/README.md +226 -0
- data/ROADMAP +0 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/app/views/fancygrid/controls.html.haml +34 -0
- data/app/views/fancygrid/fancygrid.html.haml +18 -0
- data/app/views/fancygrid/search.html.haml +24 -0
- data/app/views/fancygrid/sort.html.haml +8 -0
- data/app/views/fancygrid/table.html.haml +25 -0
- data/config/locales/fancygrid.de.yml +17 -19
- data/config/locales/fancygrid.en.yml +14 -17
- data/fancygrid.gemspec +48 -88
- data/lib/assets/javascripts/fancygrid.js +425 -0
- data/lib/assets/javascripts/fancygrid.min.js +15 -0
- data/lib/assets/stylesheets/fancygrid.css +177 -0
- data/lib/fancygrid.rb +63 -44
- data/lib/fancygrid/column.rb +165 -0
- data/lib/fancygrid/controller/helper.rb +46 -0
- data/lib/fancygrid/grid.rb +171 -317
- data/lib/fancygrid/node.rb +85 -490
- data/lib/fancygrid/object_wrapper.rb +24 -0
- data/lib/fancygrid/orm/active_record.rb +39 -0
- data/lib/fancygrid/orm/sql_generator.rb +127 -0
- data/lib/fancygrid/view/helper.rb +44 -0
- data/lib/fancygrid/view_state.rb +161 -0
- data/spec/column_spec.rb +29 -0
- data/spec/dummy/app/controllers/application_controller.rb +48 -0
- data/spec/dummy/app/views/application/index.html.haml +11 -0
- data/spec/dummy/app/views/layouts/application.html.erb +1 -1
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/environments/development.rb +2 -2
- data/spec/dummy/config/environments/test.rb +2 -2
- data/spec/dummy/config/routes.rb +3 -2
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +26 -0
- data/spec/dummy/public/javascripts/jquery-1.4.2.js +6240 -0
- data/spec/dummy/public/javascripts/jquery-fancygrid.js +425 -0
- data/spec/dummy/public/javascripts/jquery-ui.js +41 -0
- data/spec/dummy/public/stylesheets/fancygrid.css +183 -0
- data/spec/node_spec.rb +79 -301
- data/spec/spec_helper.rb +0 -29
- data/spec/view_state_spec.rb +91 -0
- metadata +124 -137
- data/.bundle/config +0 -2
- data/README.rdoc +0 -299
- data/app/views/fancygrid/_cells.html.haml +0 -13
- data/app/views/fancygrid/base/controls.html.haml +0 -40
- data/app/views/fancygrid/base/list_frame.html.haml +0 -37
- data/app/views/fancygrid/base/search.html.haml +0 -33
- data/app/views/fancygrid/base/sort.html.haml +0 -20
- data/app/views/fancygrid/base/table_frame.html.haml +0 -45
- data/config/initializers/fancygrid.rb +0 -67
- data/lib/fancygrid/helper.rb +0 -129
- data/lib/fancygrid/query_generator.rb +0 -340
- data/lib/fancygrid/view.rb +0 -148
- data/lib/generators/install_generator.rb +0 -61
- data/lib/generators/views_generator.rb +0 -25
- data/lib/version.rb +0 -0
- data/public/images/fancygrid/add.png +0 -0
- data/public/images/fancygrid/clear.png +0 -0
- data/public/images/fancygrid/ddn.png +0 -0
- data/public/images/fancygrid/dn.png +0 -0
- data/public/images/fancygrid/dots.png +0 -0
- data/public/images/fancygrid/loading.gif +0 -0
- data/public/images/fancygrid/magnifier.png +0 -0
- data/public/images/fancygrid/next.png +0 -0
- data/public/images/fancygrid/order.png +0 -0
- data/public/images/fancygrid/prev.png +0 -0
- data/public/images/fancygrid/reload.png +0 -0
- data/public/images/fancygrid/remove.png +0 -0
- data/public/images/fancygrid/spacer.gif +0 -0
- data/public/images/fancygrid/submit.png +0 -0
- data/public/images/fancygrid/th_bg.png +0 -0
- data/public/images/fancygrid/up.png +0 -0
- data/public/images/fancygrid/uup.png +0 -0
- data/public/javascripts/fancygrid.js +0 -477
- data/public/javascripts/fancygrid.min.js +0 -17
- data/public/stylesheets/fancygrid.css +0 -289
- data/public/stylesheets/fancygrid.scss +0 -302
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/log/test.log +0 -1026
- data/spec/dummy/public/javascripts/application.js +0 -2
- data/spec/dummy/public/javascripts/controls.js +0 -965
- data/spec/dummy/public/javascripts/dragdrop.js +0 -974
- data/spec/dummy/public/javascripts/effects.js +0 -1123
- data/spec/dummy/public/javascripts/prototype.js +0 -6001
- data/spec/dummy/public/javascripts/rails.js +0 -175
- data/spec/grid_spec.rb +0 -15
- data/spec/integration/navigation_spec.rb +0 -9
- data/spec/query_generator_spec.rb +0 -358
@@ -0,0 +1,15 @@
|
|
1
|
+
(function(d){var j=this.Fancygrid={},i=function(a,b){d(a).each(function(a,c){var h=d(c);h.is("select")||h.is("input")?h.val(b):h.text(b)})},g=function(a){a=d(a).first();return a.is("select")||a.is("input")?a.val():a.text()},f=function(a,b){var e={ajaxUrl:"/",ajaxType:"GET",name:"",searchFadeTime:25,searchFadeOpac:0.5,page:1,perPage:25},b=b||{};d.extend(e,b);this.name=b.name;this.container=a;this.settings=e;this.queries=0;this.query={pagination:{page:e.page,per_page:e.perPage},columns:[],conditions:[],
|
2
|
+
operator:"all",order:{}};this.components={container:a,search:a.find(".fg-search"),searchTemplate:a.find(".fg-search-template"),sortWindow:a.find(".fg-sort-window"),sortContent:a.find(".fg-sort-content"),controls:a.find(".fg-control-bar"),dataWrapper:a.find(".fg-datawrapper"),dataContainer:a.find(".fg-datacontainer"),currentPage:a.find(".fg-current-page"),totalPages:a.find(".fg-total-pages"),perPage:a.find(".fg-per-page"),buttons:{prevPage:a.find(".fg-button-prev"),nextPage:a.find(".fg-button-next"),
|
3
|
+
refresh:a.find(".fg-button-refresh"),clearSearch:a.find(".fg-button-clear"),toggleSearch:a.find(".fg-button-search"),toggleSort:a.find(".fg-button-sort"),addCriterion:a.find(".fg-button-add-criterion"),removeCriterion:a.find(".fg-button-remove-criterion")}};this.components.searchTemplate.hide();this.components.sortWindow.hide();this.components.sortContent.hide();e.searchVisible||this.components.search.hide();var c=this;this.components.search.find("input[type='text'], select").bind("change.fancygrid",
|
4
|
+
function(){c.buildConditions();c.refresh()}).bind("focus.fancygrid",function(){d(this).select()});this.components.currentPage.bind("change.fancygrid",function(){c.setPage(g(d(this)));c.refresh()}).bind("focus.fancygrid",function(){d(this).select()});this.components.buttons.prevPage.bind("click.fancygrid",function(a){a.preventDefault();c.flipPages(-1);c.refresh()});this.components.buttons.nextPage.bind("click.fancygrid",function(a){a.preventDefault();c.flipPages(1);c.refresh()});this.components.buttons.refresh.bind("click.fancygrid",
|
5
|
+
function(a){a.preventDefault();c.refresh()});this.components.buttons.clearSearch.bind("click.fancygrid",function(a){a.preventDefault();c.clearSearch();c.refresh()});this.components.perPage.bind("change.fancygrid",function(a){a.preventDefault();c.setPerPage(g(d(this)));c.refresh()});this.components.buttons.toggleSearch.bind("click.fancygrid",function(a){a.preventDefault();c.toggleSearch()});this.components.buttons.toggleSort.bind("click.fancygrid",function(a){a.preventDefault();c.toggleSort()});this.components.sortWindow.click(function(){c.toggleSort()});
|
6
|
+
this.components.buttons.removeCriterion.click(function(a){a.preventDefault();c.buildConditions();d(this).parents(".fg-search-criterion").detach()});this.components.buttons.addCriterion.click(function(a){a.preventDefault();c.addSearchCriterion()});a.find(".fg-orderable").click(function(a){a.preventDefault();c.toggleOrder(d(this))})};f.prototype.flipPages=function(a){return this.setPage(this.query.pagination.page+a)};f.prototype.setPage=function(a){a=Math.max(1,a);this.query.pagination.page=a;i(this.components.currentPage,
|
7
|
+
a);return a};f.prototype.setPages=function(a){a=Math.max(0,a);i(this.components.totalPages,a);return a};f.prototype.setPerPage=function(a){a=Math.max(1,a);this.query.pagination.per_page=a;i(this.components.perPage,a)};f.prototype.setOrder=function(a,b){this.query.order.identifier=a;this.query.order.direction=b;this.container.find(".fg-orderable").attr("fg-sort-order","");this.container.find(".fg-orderable[fg-identifier='"+a+"']").attr("fg-sort-order",b);return this.query.order};f.prototype.toggleOrder=
|
8
|
+
function(a){var b=a.attr("fg-identifier"),a=a.attr("fg-sort-order");this.setOrder(b,"asc"==a?"desc":"desc"==a?"":"asc");this.refresh()};f.prototype.toggleSort=function(){this.components.sortWindow.css({position:"absolute",top:0,left:0,width:"100%",height:"100%",opacity:0.5});this.components.sortContent.css({position:"absolute",top:0.25*window.innerHeight/2,left:(window.innerWidth-200)/2,width:200});var a=this;this.components.sortContent.find("input[type=submit]").click(function(){a.submitSort();return!1});
|
9
|
+
this.components.sortContent.find(".fg-sortable").sortable();this.components.sortContent.find(".fg-sortable").disableSelection();this.components.sortWindow.toggle();this.components.sortContent.toggle()};f.prototype.submitSort=function(){this.buildColumns();this.refresh(function(){window.location.reload()})};f.prototype.clearSearch=function(){this.container.find(".fg-search li.fg-search-criterion").detach();this.container.find(".fg-search-criterion *[name='value']").val("");this.query.conditions=[];
|
10
|
+
return this.query.conditions};f.prototype.buildColumns=function(){var a=this.components.sortContent.find(".fg-sort-item input"),b=this.query.columns=[];a.each(function(a,c){c=d(c);b.push({identifier:c.attr("name"),visible:c.is(":checked"),position:a})});return this.query.columns};f.prototype.buildConditions=function(){this.query.operator=this.container.find("#fg-search-conditions:checked").val()||"all";var a=this.query.conditions=[];this.components.search.find(".fg-search-criterion").each(function(){a.push({identifier:g(d(this).find("#identifier")),
|
11
|
+
operator:g(d(this).find("#operator")),value:g(d(this).find("#value"))})});return this.query};f.prototype.toggleSearch=function(){this.components.search.toggle();this.query.search_visible=this.components.search.is(":visible");return this.query.search_visible};f.prototype.addSearchCriterion=function(){if(!this.components.searchTemplate)return!1;var a=this,b=d(this.components.searchTemplate.html());this.components.search.find(".fg-search-criteria").append(b);b.find(".fg-button-remove-criterion").click(function(){b.remove();
|
12
|
+
a.buildConditions()});b.find("input[type='text']").bind("change.fancygrid",function(){a.buildConditions()}).bind("focus.fancygrid",function(){d(this).select()})};f.prototype.refresh=function(a){var b=this,e={fancygrid:{}};e.fancygrid[b.name]=b.query;b.queries+=1;b.container.fadeTo(b.settings.searchFadeTime,b.settings.searchFadeOpac);d.ajax({type:b.settings.ajaxType,url:b.settings.ajaxUrl,data:e,dataType:"html",success:function(a){b.queries-=1;0===b.queries&&(a=d(a).find("#fancygrid_"+b.settings.name),
|
13
|
+
b.container.find(".fg-row").detach(),b.container.find(".fg-datacontainer").append(a.find(".fg-row")),b.setPage(g(a.find(".fg-current-page"))),b.setPages(g(a.find(".fg-total-pages"))),b.container.fadeTo(b.settings.searchFadeTime,1),b.container.trigger("ajaxSuccess"))},error:function(){b.queries-=1;0===b.queries&&(b.container.find(".fg-row").detach(),b.container.fadeTo(b.settings.searchFadeTime,1),b.container.trigger("ajaxError"))},complete:a})};f.prototype.download=function(a){var b={fancygrid:{}};
|
14
|
+
b.fancygrid[this.name]=this.query;var e=this.settings.ajaxUrl;e.match(/\.html$/)&&(e=e.substring(0,e.length-5));e=[e,a].join(".");a=d.param(b);b=this.settings.ajaxType;if(e&&a){var a="string"===typeof a?a:d.param(a),c="";d.each(a.split("&"),function(){var a=this.split("=");c+='<input type="hidden" name="'+decodeURIComponent(a[0])+'" value="'+decodeURIComponent(a[1])+'" />'});d('<form action="'+e+'" method="'+(b||"post")+'">'+c+"</form>").appendTo("body").submit().remove()}};d.fn.fancygrid=function(a){j[a.name]=
|
15
|
+
new f(d(this),a);d(this).data("fancygrid",j[a.name])}})(jQuery);
|
@@ -0,0 +1,177 @@
|
|
1
|
+
|
2
|
+
.fg-control-bar{
|
3
|
+
list-style: none;
|
4
|
+
display: block;
|
5
|
+
text-align: center;
|
6
|
+
margin: 0px;
|
7
|
+
padding: 5px;
|
8
|
+
}
|
9
|
+
|
10
|
+
.fg-control-bar li{
|
11
|
+
display: inline;
|
12
|
+
}
|
13
|
+
|
14
|
+
tr.fg-search td .fg-search-criterion{
|
15
|
+
border: 1px solid #ccc;
|
16
|
+
padding: 3px;
|
17
|
+
}
|
18
|
+
tr.fg-search td .fg-search-criterion input,
|
19
|
+
tr.fg-search td .fg-search-criterion select{
|
20
|
+
border: 0px;
|
21
|
+
padding: 0px;
|
22
|
+
width: 100%;
|
23
|
+
outline: none;
|
24
|
+
-webkit-appearance:scrollbarbutton-down;
|
25
|
+
}
|
26
|
+
tr.fg-search td .fg-search-criterion select:focus;{
|
27
|
+
outline: none;
|
28
|
+
}
|
29
|
+
|
30
|
+
tr.fg-header th.fg-orderable{
|
31
|
+
background-position: 50% 0%;
|
32
|
+
background-repeat: no-repeat;
|
33
|
+
cursor: pointer;
|
34
|
+
}
|
35
|
+
tr.fg-header th.fg-orderable[fg-sort-order=asc]{
|
36
|
+
background-image: url(
|
37
|
+
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAECAYAAACzzX7wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACRJREFUeNpiYEACkZER/0GYARuASoAxhiJkSQxF2CSRFQEEGADl3xw9oxw7tQAAAABJRU5ErkJggg==
|
38
|
+
);
|
39
|
+
}
|
40
|
+
tr.fg-header th.fg-orderable:hover[fg-sort-order=asc]{
|
41
|
+
background-image: url(
|
42
|
+
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAECAMAAAB1GNVPAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF1NTUfX190dHRtLS0l5eXQEBAR0dH1dXVREREr6+v2dnZn5+fbGxseXl5RkZGzMzM////BUSGAAAAABF0Uk5T/////////////////////wAlrZliAAAAJklEQVR42mIQEBBgA2IGAQEORh4QzcrLycwtwMDHwsTPwMUOEGAAFi0BOZt2IEwAAAAASUVORK5CYII=
|
43
|
+
);
|
44
|
+
}
|
45
|
+
tr.fg-header th.fg-orderable[fg-sort-order=desc]{
|
46
|
+
background-image: url(
|
47
|
+
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAEAgMAAADOo5ZjAAAACVBMVEUAAAAAAABZWVjux8MkAAAAAXRSTlMAQObYZgAAABRJREFUeNpjmBrGoBrBwJnAwNQAAA+QAlRLCPc3AAAAAElFTkSuQmCC
|
48
|
+
);
|
49
|
+
}
|
50
|
+
tr.fg-header th.fg-orderable:hover[fg-sort-order=desc]{
|
51
|
+
background-image: url(
|
52
|
+
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAECAMAAAB1GNVPAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADBQTFRFfX19xMTEbW1ttLS0jo6OREREr6+vycnJj4+Pubm5jIyMlpaWsLCwoKCg1NTU////gVMa/AAAABB0Uk5T////////////////////AOAjXRkAAAAmSURBVHjaYmBl4GLhZeNh4Gfi5mTn42fg5+dg5OMH0fzMQAwQYAAQZgEsd9uAdAAAAABJRU5ErkJggg==
|
53
|
+
);
|
54
|
+
}
|
55
|
+
|
56
|
+
.fg-control-bar [class^="fg-button"],
|
57
|
+
.fg-search [class^="fg-button"]{
|
58
|
+
cursor: pointer;
|
59
|
+
display: inline-block;
|
60
|
+
width: 14px;
|
61
|
+
height: 14px;
|
62
|
+
vertical-align: text-top;
|
63
|
+
background-image: url(
|
64
|
+
data:image/png;base64,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
|
65
|
+
);
|
66
|
+
|
67
|
+
background-position: 14px 14px;
|
68
|
+
background-repeat: no-repeat;
|
69
|
+
*margin-right: .3em;
|
70
|
+
}
|
71
|
+
.fg-control-bar .fg-button-search,
|
72
|
+
.fg-search .fg-button-refresh{
|
73
|
+
background-position: -48px 0;
|
74
|
+
}
|
75
|
+
.fg-search .fg-button-add-criterion{
|
76
|
+
background-position: 0 -96px;
|
77
|
+
}
|
78
|
+
.fg-search .fg-button-remove-criterion{
|
79
|
+
background-position: -24px -96px;
|
80
|
+
}
|
81
|
+
|
82
|
+
.fg-control-bar .fg-button-prev{
|
83
|
+
background-position: -432px -72px;
|
84
|
+
}
|
85
|
+
.fg-control-bar .fg-button-next{
|
86
|
+
background-position: -456px -72px;
|
87
|
+
}
|
88
|
+
.fg-control-bar .fg-button-clear,
|
89
|
+
.fg-search .fg-button-clear{
|
90
|
+
background-position: -456px 0;
|
91
|
+
}
|
92
|
+
.fg-control-bar .fg-button-refresh{
|
93
|
+
background-position: -240px -24px;
|
94
|
+
}
|
95
|
+
.fg-control-bar .fg-button-sort{
|
96
|
+
background-position: -264px -24px;
|
97
|
+
}
|
98
|
+
|
99
|
+
.fg-container input,
|
100
|
+
.fg-container select{
|
101
|
+
padding: 3px 5px;
|
102
|
+
border: 1px solid #CCCCCC;
|
103
|
+
}
|
104
|
+
.fg-container input{
|
105
|
+
padding: 4px 5px;
|
106
|
+
}
|
107
|
+
.fg-control-bar input.fg-current-page{
|
108
|
+
width: 25px;
|
109
|
+
text-align: right;
|
110
|
+
}
|
111
|
+
|
112
|
+
.fg-control-bar .separator{
|
113
|
+
border-left: 1px solid #ccc;
|
114
|
+
margin: 0px 5px;
|
115
|
+
}
|
116
|
+
|
117
|
+
.fg-sort-window{
|
118
|
+
background-color: black;
|
119
|
+
}
|
120
|
+
|
121
|
+
.fg-sort-content{
|
122
|
+
background-color: white;
|
123
|
+
}
|
124
|
+
|
125
|
+
.fg-sort-content .fg-sortable{
|
126
|
+
list-style : none;
|
127
|
+
padding-left: 10px;
|
128
|
+
}
|
129
|
+
.fg-sort-content .fg-sort-item{
|
130
|
+
cursor : move;
|
131
|
+
}
|
132
|
+
.fg-sort-content input[type=submit]{
|
133
|
+
width: 100%;
|
134
|
+
}
|
135
|
+
|
136
|
+
/*
|
137
|
+
*
|
138
|
+
*/
|
139
|
+
.fg-container table{
|
140
|
+
width: 100%;
|
141
|
+
border-collapse: collapse;
|
142
|
+
border-spacing: 0;
|
143
|
+
border: 1px solid #ddd;
|
144
|
+
*border-collapse: collapsed;
|
145
|
+
}
|
146
|
+
|
147
|
+
.fg-container th, .fg-container td {
|
148
|
+
padding: 8px;
|
149
|
+
line-height: 18px;
|
150
|
+
text-align: left;
|
151
|
+
border-top: 1px solid #ddd;
|
152
|
+
}
|
153
|
+
|
154
|
+
.fg-container th + th,
|
155
|
+
.fg-container td + td,
|
156
|
+
.fg-container th + td,
|
157
|
+
.fg-container td + th {
|
158
|
+
border-left: 1px solid #ddd;
|
159
|
+
}
|
160
|
+
|
161
|
+
.fg-container tbody tr:nth-child(odd) td,
|
162
|
+
.fg-container tbody tr:nth-child(odd) th {
|
163
|
+
background-color: #f9f9f9;
|
164
|
+
}
|
165
|
+
|
166
|
+
.fg-search-controls,
|
167
|
+
.fg-search-criteria{
|
168
|
+
margin: 0px;
|
169
|
+
padding: 0px;
|
170
|
+
list-style: none;
|
171
|
+
}
|
172
|
+
.fg-search-criteria li{
|
173
|
+
margin-top: 5px;
|
174
|
+
}
|
175
|
+
ul.fg-search-controls li{
|
176
|
+
display: inline-block;
|
177
|
+
}
|
data/lib/fancygrid.rb
CHANGED
@@ -1,72 +1,91 @@
|
|
1
1
|
require "fancygrid"
|
2
|
-
require "version"
|
3
|
-
require "fancygrid/helper"
|
4
2
|
require "fancygrid/node"
|
5
3
|
require "fancygrid/grid"
|
6
|
-
require "fancygrid/
|
7
|
-
require "fancygrid/
|
4
|
+
require "fancygrid/column"
|
5
|
+
require "fancygrid/view_state"
|
6
|
+
require "fancygrid/object_wrapper"
|
8
7
|
|
9
|
-
|
8
|
+
require "fancygrid/orm/sql_generator"
|
9
|
+
require "fancygrid/orm/active_record"
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
require "fancygrid/controller/helper"
|
12
|
+
require "fancygrid/view/helper"
|
13
|
+
|
14
|
+
module Fancygrid
|
13
15
|
|
14
|
-
mattr_accessor :
|
15
|
-
@@
|
16
|
+
mattr_accessor :base_template
|
17
|
+
@@base_template = "fancygrid/fancygrid"
|
18
|
+
|
19
|
+
mattr_accessor :table_template
|
20
|
+
@@table_template = "fancygrid/table"
|
16
21
|
|
17
22
|
mattr_accessor :controls_template
|
18
|
-
@@controls_template = "fancygrid/
|
23
|
+
@@controls_template = "fancygrid/controls"
|
19
24
|
|
20
25
|
mattr_accessor :sort_template
|
21
|
-
@@sort_template = "fancygrid/
|
26
|
+
@@sort_template = "fancygrid/sort"
|
22
27
|
|
23
28
|
mattr_accessor :search_template
|
24
|
-
@@search_template = "fancygrid/
|
25
|
-
|
26
|
-
mattr_accessor :cells_template_directory
|
27
|
-
@@cells_template_directory = "fancygrid/"
|
28
|
-
|
29
|
-
mattr_accessor :cells_template
|
30
|
-
@@cells_template = "_cells"
|
29
|
+
@@search_template = "fancygrid/search"
|
31
30
|
|
32
31
|
mattr_accessor :i18n_scope
|
33
32
|
@@i18n_scope = "fancygrid"
|
33
|
+
|
34
|
+
mattr_accessor :components
|
35
|
+
@@components = [:top_bar, :bottom_bar, :search_bar, :table]
|
36
|
+
|
37
|
+
mattr_accessor :orm
|
38
|
+
@@orm = "fancygrid/orm/active_record"
|
39
|
+
|
40
|
+
mattr_accessor :hide_search
|
41
|
+
@@hide_search = true
|
34
42
|
|
35
|
-
mattr_accessor :
|
36
|
-
@@
|
37
|
-
|
38
|
-
mattr_accessor :search_visible
|
39
|
-
@@search_visible = false
|
40
|
-
|
41
|
-
mattr_accessor :default_search_type
|
42
|
-
@@default_search_type = :simple
|
43
|
-
|
44
|
-
mattr_accessor :default_grid_type
|
45
|
-
@@default_grid_type = :table
|
46
|
-
|
47
|
-
mattr_accessor :default_per_page_options
|
48
|
-
@@default_per_page_options = [5, 10, 15, 20, 25, 30, 40, 50]
|
43
|
+
mattr_accessor :search_operators
|
44
|
+
@@search_operators = Fancygrid::Orm::SqlGenerator::OPERATOR_NAMES
|
49
45
|
|
50
|
-
mattr_accessor :
|
51
|
-
@@
|
46
|
+
mattr_accessor :search_operator
|
47
|
+
@@search_operator = :like
|
48
|
+
|
49
|
+
mattr_accessor :per_page_values
|
50
|
+
@@per_page_values = [5, 10, 15, 20, 25, 30, 40, 50, 100]
|
52
51
|
|
53
|
-
mattr_accessor :
|
54
|
-
@@
|
52
|
+
mattr_accessor :per_page_value
|
53
|
+
@@per_page_value = 20
|
54
|
+
|
55
|
+
mattr_accessor :ajax_type
|
56
|
+
@@ajax_type = :get
|
57
|
+
|
58
|
+
mattr_accessor :persist_state
|
59
|
+
@@persist_state = false
|
55
60
|
|
56
61
|
def self.setup
|
57
62
|
yield self
|
58
63
|
end
|
59
64
|
|
65
|
+
def self.default_options
|
66
|
+
{
|
67
|
+
:base_template => self.base_template,
|
68
|
+
:table_template => self.table_template,
|
69
|
+
:controls_template => self.controls_template,
|
70
|
+
:sort_template => self.sort_template,
|
71
|
+
:search_template => self.search_template,
|
72
|
+
:i18n_scope => self.i18n_scope,
|
73
|
+
:components => self.components,
|
74
|
+
:orm => self.orm,
|
75
|
+
:hide_search => self.hide_search,
|
76
|
+
:search_operators => self.search_operators,
|
77
|
+
:search_operator => self.search_operator,
|
78
|
+
:per_page_values => self.per_page_values,
|
79
|
+
:per_page_value => self.per_page_value,
|
80
|
+
:ajax_type => self.ajax_type,
|
81
|
+
:persist_state => self.persist_state
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
60
85
|
class Engine < Rails::Engine#:nodoc:
|
61
|
-
|
62
|
-
generators do
|
63
|
-
require File.join(File.dirname(__FILE__), "generators", "install_generator")
|
64
|
-
require File.join(File.dirname(__FILE__), "generators", "views_generator")
|
65
|
-
end
|
66
|
-
|
67
86
|
initializer "fancygrid.initialize" do |app|
|
68
|
-
ActionController::Base.send :include, Fancygrid::Helper
|
69
|
-
ActionView::Base.send :include, Fancygrid::Helper
|
87
|
+
ActionController::Base.send :include, Fancygrid::Controller::Helper
|
88
|
+
ActionView::Base.send :include, Fancygrid::View::Helper
|
70
89
|
end
|
71
90
|
end
|
72
91
|
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Fancygrid
|
2
|
+
|
3
|
+
class Column < Fancygrid::Node
|
4
|
+
|
5
|
+
# The column position in table.
|
6
|
+
attr_accessor :position
|
7
|
+
|
8
|
+
# The column width.
|
9
|
+
attr_accessor :width
|
10
|
+
|
11
|
+
# If true, this column is not rendered.
|
12
|
+
attr_accessor :hidden
|
13
|
+
|
14
|
+
|
15
|
+
# If true, a search field is then rendered for this column.
|
16
|
+
attr_accessor :searchable
|
17
|
+
|
18
|
+
# The current search value for this column.
|
19
|
+
attr_accessor :search_value
|
20
|
+
|
21
|
+
# The current search operator for this column.
|
22
|
+
attr_accessor :search_operator
|
23
|
+
|
24
|
+
# The possible search options for this column.
|
25
|
+
attr_accessor :search_options
|
26
|
+
|
27
|
+
|
28
|
+
# If true, this column is treated as a database column.
|
29
|
+
# SQL queries may use the columns name for SELECT statements.
|
30
|
+
attr_accessor :selectable
|
31
|
+
|
32
|
+
# If true, the root node has a formatter method for this column.
|
33
|
+
attr_accessor :formatable
|
34
|
+
|
35
|
+
# Value resolver proc for this column.
|
36
|
+
attr_accessor :value_proc
|
37
|
+
|
38
|
+
|
39
|
+
def initialize(parent, name, options = {})
|
40
|
+
super(parent, name, options)
|
41
|
+
|
42
|
+
@position = options.fetch(:position, 0)
|
43
|
+
@width = options.fetch(:width, nil)
|
44
|
+
@hidden = options.fetch(:hidden, false)
|
45
|
+
self.visible = options.fetch(:visible, self.visible)
|
46
|
+
|
47
|
+
@searchable = options.fetch(:searchable, false)
|
48
|
+
@search_value = options.fetch(:search_value, nil)
|
49
|
+
@search_operator = options.fetch(:search_operator, nil)
|
50
|
+
@search_options = options.fetch(:search_options, nil)
|
51
|
+
|
52
|
+
@selectable = options.fetch(:selectable, false)
|
53
|
+
@value_proc = options.fetch(:value_proc, nil)
|
54
|
+
|
55
|
+
@human_name = options.fetch(:human_name, nil)
|
56
|
+
|
57
|
+
@formatable = self.root.respond_to?(self.formatter_method)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Gets a value indicating whether this column is visible
|
61
|
+
# and should be rendered or not.
|
62
|
+
#
|
63
|
+
def visible
|
64
|
+
!@hidden
|
65
|
+
end
|
66
|
+
|
67
|
+
# Sets a value indication whether this column is visible
|
68
|
+
# and should be rendered or not.
|
69
|
+
#
|
70
|
+
def visible=(value)
|
71
|
+
@hidden = !value
|
72
|
+
end
|
73
|
+
|
74
|
+
# Gets the current sort order for this column.
|
75
|
+
#
|
76
|
+
def sort_order
|
77
|
+
self.root.view_state.column_order(self)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Gets the method name that is send to the root node
|
81
|
+
# to format the value of a column cell
|
82
|
+
#
|
83
|
+
def formatter_method
|
84
|
+
@formatter_method or @formatter_method = "format_" + self.identifier.gsub(".", "_")
|
85
|
+
end
|
86
|
+
|
87
|
+
# Gets the column identifier.
|
88
|
+
# This is the #table_name and #name joined with a '.' (dot)
|
89
|
+
#
|
90
|
+
def identifier
|
91
|
+
@identifier or @identifier = [self.table_name, self.name].join('.')
|
92
|
+
end
|
93
|
+
|
94
|
+
# Gets a whitespace separated string that is used as css class
|
95
|
+
# for the table column. The string contains the #table_name
|
96
|
+
# and the #name of this column.
|
97
|
+
#
|
98
|
+
def tag_class
|
99
|
+
@tag_class or @tag_class = self.identifier.split(".").join(" ")
|
100
|
+
end
|
101
|
+
|
102
|
+
# Gets the internationalization lookup path for this column.
|
103
|
+
#
|
104
|
+
def i18n_path
|
105
|
+
@i18n_path or @i18n_path = [Fancygrid.i18n_scope, :tables, self.name_chain].join(".")
|
106
|
+
end
|
107
|
+
|
108
|
+
# Gets the default human name for this column
|
109
|
+
#
|
110
|
+
def default_human_name
|
111
|
+
result = self.name.to_s.humanize
|
112
|
+
if self.resource_class.respond_to? :human_attribute_name
|
113
|
+
self.resource_class.human_attribute_name(self.name, :default => result)
|
114
|
+
else
|
115
|
+
result
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Gets the internationalized, human readable name for this column.
|
120
|
+
#
|
121
|
+
def human_name
|
122
|
+
@human_name or @human_name = I18n.t(self.i18n_path, :default => default_human_name)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Fetches a value from given record.
|
126
|
+
#
|
127
|
+
def fetch_value record
|
128
|
+
if self.value_proc
|
129
|
+
return value_proc.call(record)
|
130
|
+
else
|
131
|
+
chain = self.name_chain.split(".")
|
132
|
+
chain.shift
|
133
|
+
|
134
|
+
value = record
|
135
|
+
while token = chain.shift
|
136
|
+
value = (value.respond_to?(token) ? value.send(token) : nil)
|
137
|
+
return nil if value.nil?
|
138
|
+
end
|
139
|
+
|
140
|
+
return value
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Fetches a value from given record and tries to apply
|
145
|
+
# the format method
|
146
|
+
#
|
147
|
+
def fetch_value_and_format record
|
148
|
+
value = fetch_value(record)
|
149
|
+
value = self.root.send(self.formatter_method, value) if self.formatable
|
150
|
+
return value
|
151
|
+
end
|
152
|
+
|
153
|
+
# Adds this column to the given collection
|
154
|
+
#
|
155
|
+
def collect_columns collection
|
156
|
+
collection << self
|
157
|
+
end
|
158
|
+
|
159
|
+
protected
|
160
|
+
def add_child(node)
|
161
|
+
raise "columns can not have child elements"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|