presenting 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -20
- data/README +10 -10
- data/Rakefile +22 -22
- data/app/assets/javascripts/search.js +13 -13
- data/app/assets/stylesheets/details-color.css +7 -7
- data/app/assets/stylesheets/details.css +10 -10
- data/app/assets/stylesheets/form.css +1 -1
- data/app/assets/stylesheets/grid-color.css +71 -71
- data/app/assets/stylesheets/grid.css +64 -64
- data/app/assets/stylesheets/search-color.css +16 -16
- data/app/assets/stylesheets/search.css +45 -45
- data/app/controllers/presentation/assets_controller.rb +42 -42
- data/app/views/presentations/_details.erb +11 -11
- data/app/views/presentations/_field_search.erb +14 -14
- data/app/views/presentations/_form.erb +20 -20
- data/app/views/presentations/_grid.erb +70 -70
- data/app/views/presentations/_search.erb +7 -7
- data/lib/presentation/base.rb +31 -31
- data/lib/presentation/details.rb +21 -21
- data/lib/presentation/field_search.rb +67 -67
- data/lib/presentation/form.rb +149 -149
- data/lib/presentation/grid.rb +162 -160
- data/lib/presentation/search.rb +9 -9
- data/lib/presenting/attribute.rb +51 -51
- data/lib/presenting/configurable.rb +10 -10
- data/lib/presenting/defaults.rb +10 -10
- data/lib/presenting/field_set.rb +26 -26
- data/lib/presenting/form_helpers.rb +51 -51
- data/lib/presenting/helpers.rb +114 -114
- data/lib/presenting/sanitize.rb +19 -19
- data/lib/presenting/search.rb +185 -185
- data/lib/presenting/sorting.rb +87 -87
- data/test/attribute_test.rb +61 -61
- data/test/configurable_test.rb +20 -20
- data/test/details_test.rb +68 -68
- data/test/field_search_test.rb +102 -102
- data/test/field_set_test.rb +46 -46
- data/test/grid_test.rb +246 -239
- data/test/helpers_test.rb +72 -72
- data/test/presenting_test.rb +15 -15
- data/test/r3/Gemfile +7 -7
- data/test/r3/Gemfile.lock +86 -82
- data/test/r3/config/application.rb +12 -12
- data/test/r3/config/boot.rb +6 -6
- data/test/r3/config/database.yml +22 -22
- data/test/r3/config/environment.rb +5 -5
- data/test/r3/config/environments/test.rb +35 -35
- data/test/r3/db/test.sqlite3 +0 -0
- data/test/r3/log/test.log +336 -0
- data/test/r3/public/javascripts/presenting/grid.js +0 -0
- data/test/r3/public/javascripts/presenting/search.js +13 -13
- data/test/r3/public/stylesheets/presenting/details-color.css +7 -7
- data/test/r3/public/stylesheets/presenting/details.css +10 -10
- data/test/r3/public/stylesheets/presenting/form.css +1 -1
- data/test/r3/public/stylesheets/presenting/grid-color.css +71 -71
- data/test/r3/public/stylesheets/presenting/grid.css +64 -64
- data/test/r3/public/stylesheets/presenting/search-color.css +16 -16
- data/test/r3/public/stylesheets/presenting/search.css +45 -45
- data/test/sanitize_test.rb +15 -15
- data/test/search_conditions_test.rb +137 -137
- data/test/search_test.rb +30 -30
- data/test/sorting_test.rb +63 -63
- metadata +74 -74
@@ -1,11 +1,11 @@
|
|
1
|
-
<div class="presentation-details">
|
2
|
-
<% if @details.title %>
|
3
|
-
<h3><%= @details.title %></h3>
|
4
|
-
<% end %>
|
5
|
-
<dl>
|
6
|
-
<% @details.fields.each do |field| %>
|
7
|
-
<dt><%= field.name %></dt>
|
8
|
-
<dd><%= present(field.value_from(@details.presentable), :raw => !field.sanitize?) %></dd>
|
9
|
-
<% end %>
|
10
|
-
</dl>
|
11
|
-
</div>
|
1
|
+
<div class="presentation-details">
|
2
|
+
<% if @details.title %>
|
3
|
+
<h3><%= @details.title %></h3>
|
4
|
+
<% end %>
|
5
|
+
<dl>
|
6
|
+
<% @details.fields.each do |field| %>
|
7
|
+
<dt><%= field.name %></dt>
|
8
|
+
<dd><%= present(field.value_from(@details.presentable), :raw => !field.sanitize?) %></dd>
|
9
|
+
<% end %>
|
10
|
+
</dl>
|
11
|
+
</div>
|
@@ -1,14 +1,14 @@
|
|
1
|
-
<div class="presentation-search">
|
2
|
-
<%= form_tag @search.url, :method => :get, :class => ("compact" if @search.compact) do %>
|
3
|
-
<% @search.fields.each do |field| %>
|
4
|
-
<fieldset>
|
5
|
-
<label><%= field.name %></label>
|
6
|
-
<%= present(field, "#{field.type}_search", :name => "search[#{field.param}][value]") %>
|
7
|
-
</fieldset>
|
8
|
-
<% end %>
|
9
|
-
<fieldset class="submit">
|
10
|
-
<input type="submit" value="Search" class="submit" />
|
11
|
-
<%= link_to 'reset', @search.url %>
|
12
|
-
</fieldset>
|
13
|
-
<% end %>
|
14
|
-
</div>
|
1
|
+
<div class="presentation-search">
|
2
|
+
<%= form_tag @search.url, :method => :get, :class => ("compact" if @search.compact) do %>
|
3
|
+
<% @search.fields.each do |field| %>
|
4
|
+
<fieldset>
|
5
|
+
<label><%= field.name %></label>
|
6
|
+
<%= present(field, "#{field.type}_search", :name => "search[#{field.param}][value]") %>
|
7
|
+
</fieldset>
|
8
|
+
<% end %>
|
9
|
+
<fieldset class="submit">
|
10
|
+
<input type="submit" value="Search" class="submit" />
|
11
|
+
<%= link_to 'reset', @search.url %>
|
12
|
+
</fieldset>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
@@ -1,20 +1,20 @@
|
|
1
|
-
<%= form_for @form.presentable, :url => @form.url, :method => @form.method, :html => @form.html do |f| %>
|
2
|
-
<% @form.groups.each do |group| %>
|
3
|
-
<fieldset>
|
4
|
-
<% unless group.name.blank? %>
|
5
|
-
<legend><%= group.name %></legend>
|
6
|
-
<% end %>
|
7
|
-
<% group.fields.each do |field| %>
|
8
|
-
<% if field.type.to_sym == :hidden %>
|
9
|
-
<%= f.present(field) %>
|
10
|
-
<% else %>
|
11
|
-
<div class="field">
|
12
|
-
<%= f.label field.name, field.label %>
|
13
|
-
<%= f.present(field) %>
|
14
|
-
</div>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
17
|
-
</fieldset>
|
18
|
-
<% end %>
|
19
|
-
<%= f.submit @form.button %>
|
20
|
-
<% end %>
|
1
|
+
<%= form_for @form.presentable, :url => @form.url, :method => @form.method, :html => @form.html do |f| %>
|
2
|
+
<% @form.groups.each do |group| %>
|
3
|
+
<fieldset>
|
4
|
+
<% unless group.name.blank? %>
|
5
|
+
<legend><%= group.name %></legend>
|
6
|
+
<% end %>
|
7
|
+
<% group.fields.each do |field| %>
|
8
|
+
<% if field.type.to_sym == :hidden %>
|
9
|
+
<%= f.present(field) %>
|
10
|
+
<% else %>
|
11
|
+
<div class="field">
|
12
|
+
<%= f.label field.name, field.label %>
|
13
|
+
<%= f.present(field) %>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
</fieldset>
|
18
|
+
<% end %>
|
19
|
+
<%= f.submit @form.button %>
|
20
|
+
<% end %>
|
@@ -1,70 +1,70 @@
|
|
1
|
-
<div id="<%= @grid.id %>" class="presentation-grid">
|
2
|
-
<table>
|
3
|
-
<% unless @grid.title.blank? and @grid.links.empty? %>
|
4
|
-
<caption>
|
5
|
-
<% unless @grid.links.empty? %>
|
6
|
-
<ul class="actions">
|
7
|
-
<% @grid.links.each do |link| %>
|
8
|
-
<li><%= link %></li>
|
9
|
-
<% end %>
|
10
|
-
</ul>
|
11
|
-
<% end %>
|
12
|
-
|
13
|
-
<%= @grid.title %>
|
14
|
-
</caption>
|
15
|
-
<% end %>
|
16
|
-
<thead>
|
17
|
-
<tr>
|
18
|
-
<% @grid.fields.each do |field| %>
|
19
|
-
<th class="<%= field.id %>">
|
20
|
-
<% if field.sortable? %>
|
21
|
-
<%= link_to field.name, field.sorted_url(request), :class => "sortable" %>
|
22
|
-
<% else %>
|
23
|
-
<%= field.name %>
|
24
|
-
<% end %>
|
25
|
-
</th>
|
26
|
-
<% end %>
|
27
|
-
<% unless @grid.record_links.empty? %>
|
28
|
-
<th></th>
|
29
|
-
<% end %>
|
30
|
-
</tr>
|
31
|
-
</thead>
|
32
|
-
<tbody>
|
33
|
-
<% if @grid.presentable.blank? %>
|
34
|
-
<tr>
|
35
|
-
<td colspan="<%= @grid.colspan %>">
|
36
|
-
No records found.
|
37
|
-
</td>
|
38
|
-
</tr>
|
39
|
-
<% else %>
|
40
|
-
<% @grid.presentable.each do |record| %>
|
41
|
-
<tr class="<%= cycle('odd', 'even') %>">
|
42
|
-
<% @grid.fields.each do |field| %>
|
43
|
-
<td class="<%= [field.id, ('sorted' if field.is_sorted?(request))].compact.join(' ') %>">
|
44
|
-
<%= present(field.value_from(record), :raw => !field.sanitize?) %>
|
45
|
-
</td>
|
46
|
-
<% end %>
|
47
|
-
<% unless @grid.record_links.empty? %>
|
48
|
-
<td>
|
49
|
-
<ul class="actions">
|
50
|
-
<% @grid.record_links.each do |link| %>
|
51
|
-
<li><%= link.call(record) %></li>
|
52
|
-
<% end %>
|
53
|
-
</ul>
|
54
|
-
</td>
|
55
|
-
<% end %>
|
56
|
-
</tr>
|
57
|
-
<% end %>
|
58
|
-
<% end %>
|
59
|
-
</tbody>
|
60
|
-
<% if @grid.paginate? %>
|
61
|
-
<tfoot>
|
62
|
-
<tr>
|
63
|
-
<td colspan="<%= @grid.colspan %>">
|
64
|
-
<%= will_paginate @grid.presentable %>
|
65
|
-
</td>
|
66
|
-
</tr>
|
67
|
-
</tfoot>
|
68
|
-
<% end %>
|
69
|
-
</table>
|
70
|
-
</div>
|
1
|
+
<div id="<%= @grid.id %>" class="presentation-grid">
|
2
|
+
<table>
|
3
|
+
<% unless @grid.title.blank? and @grid.links.empty? %>
|
4
|
+
<caption>
|
5
|
+
<% unless @grid.links.empty? %>
|
6
|
+
<ul class="actions">
|
7
|
+
<% @grid.links.each do |link| %>
|
8
|
+
<li><%= link %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<%= @grid.title %>
|
14
|
+
</caption>
|
15
|
+
<% end %>
|
16
|
+
<thead>
|
17
|
+
<tr>
|
18
|
+
<% @grid.fields.each do |field| %>
|
19
|
+
<th class="<%= field.id %>">
|
20
|
+
<% if field.sortable? %>
|
21
|
+
<%= link_to field.name, field.sorted_url(request), :class => "sortable" %>
|
22
|
+
<% else %>
|
23
|
+
<%= field.name %>
|
24
|
+
<% end %>
|
25
|
+
</th>
|
26
|
+
<% end %>
|
27
|
+
<% unless @grid.record_links.empty? %>
|
28
|
+
<th></th>
|
29
|
+
<% end %>
|
30
|
+
</tr>
|
31
|
+
</thead>
|
32
|
+
<tbody>
|
33
|
+
<% if @grid.presentable.blank? %>
|
34
|
+
<tr>
|
35
|
+
<td colspan="<%= @grid.colspan %>">
|
36
|
+
No records found.
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
<% else %>
|
40
|
+
<% @grid.presentable.each do |record| %>
|
41
|
+
<tr class="<%= cycle('odd', 'even') %>">
|
42
|
+
<% @grid.fields.each do |field| %>
|
43
|
+
<td class="<%= [field.id, ('sorted' if field.is_sorted?(request))].compact.join(' ') %>">
|
44
|
+
<%= present(field.value_from(record), :raw => !field.sanitize?) %>
|
45
|
+
</td>
|
46
|
+
<% end %>
|
47
|
+
<% unless @grid.record_links.empty? %>
|
48
|
+
<td>
|
49
|
+
<ul class="actions">
|
50
|
+
<% @grid.record_links.each do |link| %>
|
51
|
+
<li><%= link.call(record) %></li>
|
52
|
+
<% end %>
|
53
|
+
</ul>
|
54
|
+
</td>
|
55
|
+
<% end %>
|
56
|
+
</tr>
|
57
|
+
<% end %>
|
58
|
+
<% end %>
|
59
|
+
</tbody>
|
60
|
+
<% if @grid.paginate? %>
|
61
|
+
<tfoot>
|
62
|
+
<tr>
|
63
|
+
<td colspan="<%= @grid.colspan %>">
|
64
|
+
<%= will_paginate @grid.presentable %>
|
65
|
+
</td>
|
66
|
+
</tr>
|
67
|
+
</tfoot>
|
68
|
+
<% end %>
|
69
|
+
</table>
|
70
|
+
</div>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
<div class="presentation-search">
|
2
|
-
<%= form_tag @search.url, :method => :get do %>
|
3
|
-
<%= text_field_tag 'search', params[:search] %>
|
4
|
-
<input type="submit" value="Search" class="submit" />
|
5
|
-
<%= link_to 'reset', @search.url %>
|
6
|
-
<% end %>
|
7
|
-
</div>
|
1
|
+
<div class="presentation-search">
|
2
|
+
<%= form_tag @search.url, :method => :get do %>
|
3
|
+
<%= text_field_tag 'search', params[:search] %>
|
4
|
+
<input type="submit" value="Search" class="submit" />
|
5
|
+
<%= link_to 'reset', @search.url %>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
data/lib/presentation/base.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
module Presentation
|
2
|
-
class Base
|
3
|
-
include Presenting::Configurable
|
4
|
-
|
5
|
-
def render
|
6
|
-
view.render :partial => "presentations/#{self.class.to_s.split('::').last.underscore}"
|
7
|
-
end
|
8
|
-
|
9
|
-
attr_accessor :presentable
|
10
|
-
|
11
|
-
attr_accessor :controller
|
12
|
-
delegate :request, :form_authenticity_token, :url_for, :params, :to => 'controller'
|
13
|
-
|
14
|
-
protected
|
15
|
-
|
16
|
-
# what the presentation is called in its templates
|
17
|
-
def iname
|
18
|
-
:presentation
|
19
|
-
end
|
20
|
-
|
21
|
-
# a reference to the view
|
22
|
-
def view #:nodoc:
|
23
|
-
@view ||= Presenting::View.new(ActionController::Base.view_paths, assigns_for_view, self)
|
24
|
-
end
|
25
|
-
|
26
|
-
def assigns_for_view
|
27
|
-
{iname => self, :_request => request}
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
1
|
+
module Presentation
|
2
|
+
class Base
|
3
|
+
include Presenting::Configurable
|
4
|
+
|
5
|
+
def render
|
6
|
+
view.render :partial => "presentations/#{self.class.to_s.split('::').last.underscore}"
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :presentable
|
10
|
+
|
11
|
+
attr_accessor :controller
|
12
|
+
delegate :request, :form_authenticity_token, :url_for, :params, :to => 'controller'
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
# what the presentation is called in its templates
|
17
|
+
def iname
|
18
|
+
:presentation
|
19
|
+
end
|
20
|
+
|
21
|
+
# a reference to the view
|
22
|
+
def view #:nodoc:
|
23
|
+
@view ||= Presenting::View.new(ActionController::Base.view_paths, assigns_for_view, self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def assigns_for_view
|
27
|
+
{iname => self, :_request => request}
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/presentation/details.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
require 'presentation/grid'
|
2
|
-
|
3
|
-
module Presentation
|
4
|
-
# TODO: abstract what's common between Record and Grid into a shared module or reusable objects or something
|
5
|
-
class Details < Grid
|
6
|
-
def iname; :details end
|
7
|
-
|
8
|
-
# The display title for this presentation. Will default based on the id.
|
9
|
-
attr_accessor :title
|
10
|
-
|
11
|
-
def fields=(args)
|
12
|
-
args.each do |field|
|
13
|
-
self.fields << field
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def fields
|
18
|
-
@fields ||= Presenting::FieldSet.new(Presenting::Attribute, :name, :value)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
1
|
+
require 'presentation/grid'
|
2
|
+
|
3
|
+
module Presentation
|
4
|
+
# TODO: abstract what's common between Record and Grid into a shared module or reusable objects or something
|
5
|
+
class Details < Grid
|
6
|
+
def iname; :details end
|
7
|
+
|
8
|
+
# The display title for this presentation. Will default based on the id.
|
9
|
+
attr_accessor :title
|
10
|
+
|
11
|
+
def fields=(args)
|
12
|
+
args.each do |field|
|
13
|
+
self.fields << field
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def fields
|
18
|
+
@fields ||= Presenting::FieldSet.new(Presenting::Attribute, :name, :value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,67 +1,67 @@
|
|
1
|
-
require 'presentation/search'
|
2
|
-
|
3
|
-
module Presentation
|
4
|
-
class FieldSearch < Search
|
5
|
-
# This method supports the configuration-on-initialization paradigm. It makes:
|
6
|
-
# present = Presentation::FieldSearch.new(:fields => [
|
7
|
-
# {:a => {:type => :list, :options => %w(foo bar baz)}},
|
8
|
-
# :b,
|
9
|
-
# {:c => :boolean}
|
10
|
-
# ])
|
11
|
-
#
|
12
|
-
# equivalent to:
|
13
|
-
#
|
14
|
-
# present = Presentation::FieldSearch.new
|
15
|
-
# present.fields << {:a => {:type => :list, :options => %w(foo bar baz)}}
|
16
|
-
# present.fields << :b
|
17
|
-
# present.fields << {:c => :boolean}
|
18
|
-
def fields=(args)
|
19
|
-
args.each do |field|
|
20
|
-
self.fields << field
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def fields
|
25
|
-
@fields ||= Presenting::FieldSet.new(Field, :param, :type)
|
26
|
-
end
|
27
|
-
|
28
|
-
def compact
|
29
|
-
@compact != false
|
30
|
-
end
|
31
|
-
attr_writer :compact
|
32
|
-
|
33
|
-
class Field
|
34
|
-
include Presenting::Configurable
|
35
|
-
|
36
|
-
# the display name of the field.
|
37
|
-
attr_reader :name
|
38
|
-
def name=(val)
|
39
|
-
@name = val.is_a?(Symbol) ? val.to_s.titleize : val
|
40
|
-
end
|
41
|
-
|
42
|
-
# the parameter name of the field. note that this is not necessarily the name of a database column or record attribute.
|
43
|
-
# it simply needs to be recognized as a "field" by the controller logic.
|
44
|
-
attr_reader :param
|
45
|
-
def param=(val)
|
46
|
-
self.name ||= val
|
47
|
-
@param = val.to_s.underscore.downcase.gsub(' ', '_')
|
48
|
-
end
|
49
|
-
|
50
|
-
# the type of search interface for this field. supported options:
|
51
|
-
# * :text (default)
|
52
|
-
# * :checkbox
|
53
|
-
# * :time [planned]
|
54
|
-
# * :list [planned]
|
55
|
-
def type
|
56
|
-
@type ||= :text
|
57
|
-
end
|
58
|
-
attr_writer :type
|
59
|
-
|
60
|
-
# extra options for the field.
|
61
|
-
def options
|
62
|
-
@options ||= {}
|
63
|
-
end
|
64
|
-
attr_writer :options
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
1
|
+
require 'presentation/search'
|
2
|
+
|
3
|
+
module Presentation
|
4
|
+
class FieldSearch < Search
|
5
|
+
# This method supports the configuration-on-initialization paradigm. It makes:
|
6
|
+
# present = Presentation::FieldSearch.new(:fields => [
|
7
|
+
# {:a => {:type => :list, :options => %w(foo bar baz)}},
|
8
|
+
# :b,
|
9
|
+
# {:c => :boolean}
|
10
|
+
# ])
|
11
|
+
#
|
12
|
+
# equivalent to:
|
13
|
+
#
|
14
|
+
# present = Presentation::FieldSearch.new
|
15
|
+
# present.fields << {:a => {:type => :list, :options => %w(foo bar baz)}}
|
16
|
+
# present.fields << :b
|
17
|
+
# present.fields << {:c => :boolean}
|
18
|
+
def fields=(args)
|
19
|
+
args.each do |field|
|
20
|
+
self.fields << field
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def fields
|
25
|
+
@fields ||= Presenting::FieldSet.new(Field, :param, :type)
|
26
|
+
end
|
27
|
+
|
28
|
+
def compact
|
29
|
+
@compact != false
|
30
|
+
end
|
31
|
+
attr_writer :compact
|
32
|
+
|
33
|
+
class Field
|
34
|
+
include Presenting::Configurable
|
35
|
+
|
36
|
+
# the display name of the field.
|
37
|
+
attr_reader :name
|
38
|
+
def name=(val)
|
39
|
+
@name = val.is_a?(Symbol) ? val.to_s.titleize : val
|
40
|
+
end
|
41
|
+
|
42
|
+
# the parameter name of the field. note that this is not necessarily the name of a database column or record attribute.
|
43
|
+
# it simply needs to be recognized as a "field" by the controller logic.
|
44
|
+
attr_reader :param
|
45
|
+
def param=(val)
|
46
|
+
self.name ||= val
|
47
|
+
@param = val.to_s.underscore.downcase.gsub(' ', '_')
|
48
|
+
end
|
49
|
+
|
50
|
+
# the type of search interface for this field. supported options:
|
51
|
+
# * :text (default)
|
52
|
+
# * :checkbox
|
53
|
+
# * :time [planned]
|
54
|
+
# * :list [planned]
|
55
|
+
def type
|
56
|
+
@type ||= :text
|
57
|
+
end
|
58
|
+
attr_writer :type
|
59
|
+
|
60
|
+
# extra options for the field.
|
61
|
+
def options
|
62
|
+
@options ||= {}
|
63
|
+
end
|
64
|
+
attr_writer :options
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|