fancygrid 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/CHANGELOG +9 -2
  2. data/Gemfile +6 -9
  3. data/Gemfile.lock +88 -103
  4. data/README.md +226 -0
  5. data/ROADMAP +0 -1
  6. data/Rakefile +2 -2
  7. data/VERSION +1 -1
  8. data/app/views/fancygrid/controls.html.haml +34 -0
  9. data/app/views/fancygrid/fancygrid.html.haml +18 -0
  10. data/app/views/fancygrid/search.html.haml +24 -0
  11. data/app/views/fancygrid/sort.html.haml +8 -0
  12. data/app/views/fancygrid/table.html.haml +25 -0
  13. data/config/locales/fancygrid.de.yml +17 -19
  14. data/config/locales/fancygrid.en.yml +14 -17
  15. data/fancygrid.gemspec +48 -88
  16. data/lib/assets/javascripts/fancygrid.js +425 -0
  17. data/lib/assets/javascripts/fancygrid.min.js +15 -0
  18. data/lib/assets/stylesheets/fancygrid.css +177 -0
  19. data/lib/fancygrid.rb +63 -44
  20. data/lib/fancygrid/column.rb +165 -0
  21. data/lib/fancygrid/controller/helper.rb +46 -0
  22. data/lib/fancygrid/grid.rb +171 -317
  23. data/lib/fancygrid/node.rb +85 -490
  24. data/lib/fancygrid/object_wrapper.rb +24 -0
  25. data/lib/fancygrid/orm/active_record.rb +39 -0
  26. data/lib/fancygrid/orm/sql_generator.rb +127 -0
  27. data/lib/fancygrid/view/helper.rb +44 -0
  28. data/lib/fancygrid/view_state.rb +161 -0
  29. data/spec/column_spec.rb +29 -0
  30. data/spec/dummy/app/controllers/application_controller.rb +48 -0
  31. data/spec/dummy/app/views/application/index.html.haml +11 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +1 -1
  33. data/spec/dummy/config/application.rb +1 -1
  34. data/spec/dummy/config/environments/development.rb +2 -2
  35. data/spec/dummy/config/environments/test.rb +2 -2
  36. data/spec/dummy/config/routes.rb +3 -2
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/schema.rb +26 -0
  39. data/spec/dummy/public/javascripts/jquery-1.4.2.js +6240 -0
  40. data/spec/dummy/public/javascripts/jquery-fancygrid.js +425 -0
  41. data/spec/dummy/public/javascripts/jquery-ui.js +41 -0
  42. data/spec/dummy/public/stylesheets/fancygrid.css +183 -0
  43. data/spec/node_spec.rb +79 -301
  44. data/spec/spec_helper.rb +0 -29
  45. data/spec/view_state_spec.rb +91 -0
  46. metadata +124 -137
  47. data/.bundle/config +0 -2
  48. data/README.rdoc +0 -299
  49. data/app/views/fancygrid/_cells.html.haml +0 -13
  50. data/app/views/fancygrid/base/controls.html.haml +0 -40
  51. data/app/views/fancygrid/base/list_frame.html.haml +0 -37
  52. data/app/views/fancygrid/base/search.html.haml +0 -33
  53. data/app/views/fancygrid/base/sort.html.haml +0 -20
  54. data/app/views/fancygrid/base/table_frame.html.haml +0 -45
  55. data/config/initializers/fancygrid.rb +0 -67
  56. data/lib/fancygrid/helper.rb +0 -129
  57. data/lib/fancygrid/query_generator.rb +0 -340
  58. data/lib/fancygrid/view.rb +0 -148
  59. data/lib/generators/install_generator.rb +0 -61
  60. data/lib/generators/views_generator.rb +0 -25
  61. data/lib/version.rb +0 -0
  62. data/public/images/fancygrid/add.png +0 -0
  63. data/public/images/fancygrid/clear.png +0 -0
  64. data/public/images/fancygrid/ddn.png +0 -0
  65. data/public/images/fancygrid/dn.png +0 -0
  66. data/public/images/fancygrid/dots.png +0 -0
  67. data/public/images/fancygrid/loading.gif +0 -0
  68. data/public/images/fancygrid/magnifier.png +0 -0
  69. data/public/images/fancygrid/next.png +0 -0
  70. data/public/images/fancygrid/order.png +0 -0
  71. data/public/images/fancygrid/prev.png +0 -0
  72. data/public/images/fancygrid/reload.png +0 -0
  73. data/public/images/fancygrid/remove.png +0 -0
  74. data/public/images/fancygrid/spacer.gif +0 -0
  75. data/public/images/fancygrid/submit.png +0 -0
  76. data/public/images/fancygrid/th_bg.png +0 -0
  77. data/public/images/fancygrid/up.png +0 -0
  78. data/public/images/fancygrid/uup.png +0 -0
  79. data/public/javascripts/fancygrid.js +0 -477
  80. data/public/javascripts/fancygrid.min.js +0 -17
  81. data/public/stylesheets/fancygrid.css +0 -289
  82. data/public/stylesheets/fancygrid.scss +0 -302
  83. data/spec/dummy/log/development.log +0 -0
  84. data/spec/dummy/log/production.log +0 -0
  85. data/spec/dummy/log/server.log +0 -0
  86. data/spec/dummy/log/test.log +0 -1026
  87. data/spec/dummy/public/javascripts/application.js +0 -2
  88. data/spec/dummy/public/javascripts/controls.js +0 -965
  89. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  90. data/spec/dummy/public/javascripts/effects.js +0 -1123
  91. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  92. data/spec/dummy/public/javascripts/rails.js +0 -175
  93. data/spec/grid_spec.rb +0 -15
  94. data/spec/integration/navigation_spec.rb +0 -9
  95. 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/query_generator"
7
- require "fancygrid/view"
4
+ require "fancygrid/column"
5
+ require "fancygrid/view_state"
6
+ require "fancygrid/object_wrapper"
8
7
 
9
- module Fancygrid
8
+ require "fancygrid/orm/sql_generator"
9
+ require "fancygrid/orm/active_record"
10
10
 
11
- mattr_accessor :table_template
12
- @@table_template = "fancygrid/base/table_frame"
11
+ require "fancygrid/controller/helper"
12
+ require "fancygrid/view/helper"
13
+
14
+ module Fancygrid
13
15
 
14
- mattr_accessor :list_template
15
- @@list_template = "fancygrid/base/list_frame"
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/base/controls"
23
+ @@controls_template = "fancygrid/controls"
19
24
 
20
25
  mattr_accessor :sort_template
21
- @@sort_template = "fancygrid/base/sort"
26
+ @@sort_template = "fancygrid/sort"
22
27
 
23
28
  mattr_accessor :search_template
24
- @@search_template = "fancygrid/base/search"
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 :use_grid_name_as_cells_template
36
- @@use_grid_name_as_cells_template = false
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 :default_per_page_selection
51
- @@default_per_page_selection = 20
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 :search_operators
54
- @@search_operators = Fancygrid::QueryGenerator::OPERATOR_NAMES
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