lolita 3.4.2 → 3.4.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +36 -36
  3. data/Gemfile +29 -29
  4. data/README.md +147 -147
  5. data/Rakefile +6 -6
  6. data/app/assets/javascripts/lolita/application.js +6 -6
  7. data/app/assets/javascripts/lolita/tab.js +100 -100
  8. data/app/assets/stylesheets/lolita/PIE-custom.htc +87 -87
  9. data/app/assets/stylesheets/lolita/PIE.htc +81 -81
  10. data/app/assets/stylesheets/lolita/application.css +6 -6
  11. data/app/assets/stylesheets/lolita/default.css.erb +169 -169
  12. data/app/assets/stylesheets/lolita/jquery-ui-1.8.16.lolita.css.erb +567 -567
  13. data/app/assets/stylesheets/lolita/style.css.erb +553 -553
  14. data/app/helpers/components/lolita/configuration/list_component.rb +10 -10
  15. data/app/helpers/components/lolita/configuration_component.rb +20 -20
  16. data/app/views/components/lolita/configuration/column/_first.html.haml +1 -1
  17. data/app/views/components/lolita/configuration/column/header/_first.html.haml +1 -1
  18. data/app/views/components/lolita/configuration/column/header/_sort.html.haml +6 -6
  19. data/app/views/components/lolita/configuration/columns/header/_display.html.haml +5 -5
  20. data/app/views/components/lolita/configuration/field/array/checkbox/_display.html.haml +7 -7
  21. data/app/views/components/lolita/configuration/field/string/text/_display.html.haml +7 -7
  22. data/app/views/components/lolita/configuration/search/_display.html.haml +2 -2
  23. data/app/views/components/lolita/configuration/tab/_display.html.haml +3 -3
  24. data/app/views/components/lolita/configuration/tabs/_form.html.haml +6 -6
  25. data/app/views/kaminari/lolita/_first_page.html.erb +11 -11
  26. data/app/views/kaminari/lolita/_gap.html.erb +8 -8
  27. data/app/views/kaminari/lolita/_last_page.html.erb +11 -11
  28. data/app/views/kaminari/lolita/_next_page.html.erb +11 -11
  29. data/app/views/kaminari/lolita/_page.html.erb +12 -12
  30. data/app/views/kaminari/lolita/_paginator.html.erb +23 -23
  31. data/app/views/kaminari/lolita/_prev_page.html.erb +11 -11
  32. data/app/views/lolita/info/index.html.erb +232 -232
  33. data/author +1 -1
  34. data/config/routes.rb +6 -6
  35. data/lib/generators/lolita/install_generator.rb +19 -19
  36. data/lib/generators/lolita/uninstall_generator.rb +70 -70
  37. data/lib/generators/templates/lolita.rb +13 -13
  38. data/lib/lolita.rb +140 -140
  39. data/lib/lolita/adapter/abstract_adapter.rb +15 -15
  40. data/lib/lolita/adapter/active_record.rb +227 -227
  41. data/lib/lolita/adapter/common_helper.rb +221 -221
  42. data/lib/lolita/adapter/field_helper.rb +18 -18
  43. data/lib/lolita/adapter/mongoid.rb +241 -241
  44. data/lib/lolita/components/base.rb +11 -11
  45. data/lib/lolita/configuration.rb +60 -60
  46. data/lib/lolita/configuration/column.rb +181 -181
  47. data/lib/lolita/configuration/field/big_decimal.rb +12 -12
  48. data/lib/lolita/configuration/field/boolean.rb +12 -12
  49. data/lib/lolita/configuration/field/date.rb +12 -12
  50. data/lib/lolita/configuration/field/hidden.rb +12 -12
  51. data/lib/lolita/configuration/field/integer.rb +11 -11
  52. data/lib/lolita/configuration/field/string.rb +16 -16
  53. data/lib/lolita/configuration/field/time.rb +13 -13
  54. data/lib/lolita/configuration/field_set.rb +25 -25
  55. data/lib/lolita/configuration/filter.rb +116 -116
  56. data/lib/lolita/configuration/list.rb +200 -200
  57. data/lib/lolita/configuration/search.rb +104 -104
  58. data/lib/lolita/controllers/component_helpers.rb +156 -156
  59. data/lib/lolita/controllers/internal_helpers.rb +71 -71
  60. data/lib/lolita/controllers/url_helpers.rb +7 -7
  61. data/lib/lolita/dbi/base.rb +56 -56
  62. data/lib/lolita/hooks/named_hook.rb +125 -125
  63. data/lib/lolita/lazy_loader.rb +54 -54
  64. data/lib/lolita/navigation/tree.rb +132 -132
  65. data/lib/lolita/rails/engine.rb +23 -23
  66. data/lib/lolita/rails/routes.rb +129 -129
  67. data/lib/lolita/ruby_ext/accessors.rb +26 -26
  68. data/lib/lolita/search/simple.rb +75 -75
  69. data/lib/lolita/support/formatter.rb +62 -62
  70. data/lib/lolita/support/formatter/rails.rb +56 -56
  71. data/lib/lolita/system_configuration/base.rb +178 -178
  72. data/lib/lolita/test/matchers.rb +77 -77
  73. data/lib/lolita/version.rb +30 -30
  74. data/lib/tasks/tinymce-assets.rake +6 -6
  75. data/lolita.gemspec +34 -34
  76. data/spec/adapter/common_helper_spec.rb +95 -95
  77. data/spec/adapter_helper.rb +42 -42
  78. data/spec/builder_spec.rb +120 -120
  79. data/spec/configuration/base_spec.rb +22 -22
  80. data/spec/configuration/field_spec.rb +118 -118
  81. data/spec/configuration/filter_spec.rb +131 -131
  82. data/spec/configuration/tab_spec.rb +187 -187
  83. data/spec/configuration/tabs_spec.rb +120 -120
  84. data/spec/generators/lolita/install_generator_spec.rb +54 -54
  85. data/spec/generators/lolita/uninstall_generator_spec.rb +48 -48
  86. data/spec/orm/mongoid.rb +12 -12
  87. data/spec/rails_app/app/controllers/application_controller.rb +3 -3
  88. data/spec/rails_app/app/helpers/application_helper.rb +3 -3
  89. data/spec/rails_app/app/mongoid/address.rb +7 -7
  90. data/spec/rails_app/app/mongoid/category.rb +18 -18
  91. data/spec/rails_app/app/mongoid/comment.rb +5 -5
  92. data/spec/rails_app/app/mongoid/post.rb +30 -30
  93. data/spec/rails_app/app/mongoid/preference.rb +5 -5
  94. data/spec/rails_app/app/mongoid/profile.rb +13 -13
  95. data/spec/rails_app/app/mongoid/tag.rb +3 -3
  96. data/spec/rails_app/app/views/components/lolita/configuration/list/_body_cell.html.erb +1 -1
  97. data/spec/rails_app/config/application.rb +33 -33
  98. data/spec/rails_app/config/boot.rb +7 -7
  99. data/spec/rails_app/config/environment.rb +5 -5
  100. data/spec/rails_app/config/environments/development.rb +23 -23
  101. data/spec/rails_app/config/environments/production.rb +37 -37
  102. data/spec/rails_app/config/environments/test.rb +37 -37
  103. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -7
  104. data/spec/rails_app/config/initializers/inflections.rb +2 -2
  105. data/spec/rails_app/config/initializers/secret_token.rb +1 -1
  106. data/spec/rails_app/config/routes.rb +2 -2
  107. data/spec/rails_app/lib/lolita/configuration/field/my_custom_collection.rb +13 -13
  108. data/spec/rails_app/public/javascripts/jquery-1.5.1.min.js +15 -15
  109. data/spec/rails_app/public/javascripts/lolita/main.js +6 -6
  110. data/spec/rails_app/public/javascripts/modernizr-1.7.min.js +1 -1
  111. data/spec/rails_app/public/javascripts/rails.js +137 -137
  112. data/spec/rails_app/public/javascripts/tinymce/langs/en.js +221 -221
  113. data/spec/rails_app/public/javascripts/tinymce/license.txt +504 -504
  114. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/about.htm +52 -52
  115. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/anchor.htm +26 -26
  116. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/charmap.htm +51 -51
  117. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/color_picker.htm +74 -74
  118. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/editor_template_src.js +1328 -1328
  119. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/image.htm +80 -80
  120. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/about.js +73 -73
  121. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/anchor.js +42 -42
  122. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/charmap.js +354 -354
  123. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/color_picker.js +329 -329
  124. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/image.js +247 -247
  125. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/link.js +153 -153
  126. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/js/source_editor.js +56 -56
  127. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/langs/en.js +68 -68
  128. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/langs/en_dlg.js +53 -53
  129. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/link.htm +57 -57
  130. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/shortcuts.htm +47 -47
  131. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/skins/cirkuit/content.css +66 -66
  132. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/skins/cirkuit/dialog.css +117 -117
  133. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/skins/cirkuit/ui.css +988 -988
  134. data/spec/rails_app/public/javascripts/tinymce/themes/advanced/source_editor.htm +25 -25
  135. data/spec/rails_app/public/javascripts/tinymce/tiny_mce_popup.js +4 -4
  136. data/spec/rails_app/public/stylesheets/lolita/default.css +169 -169
  137. data/spec/rails_app/public/stylesheets/lolita/style.css +214 -214
  138. data/spec/spec_helper.rb +51 -51
  139. data/vendor/assets/javascripts/application_vendor_lolita.js +4 -4
  140. data/vendor/assets/javascripts/jquery-numeric.js +279 -279
  141. data/vendor/assets/javascripts/modernizr_1_7_min.js +1 -1
  142. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/cirkuit/content.css +66 -66
  143. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/cirkuit/dialog.css +117 -117
  144. data/vendor/assets/javascripts/tinymce/themes/advanced/skins/cirkuit/ui.css +988 -988
  145. data/vendor/assets/stylesheets/jquery-ui-1.8.16.custom.css +567 -567
  146. metadata +4 -3
@@ -1,12 +1,12 @@
1
- module Lolita
2
- module Components
3
-
4
- class Base
5
- attr_reader :parent
6
- def initialize(parent)
7
- @parent = parent
8
- end
9
- end
10
-
11
- end
1
+ module Lolita
2
+ module Components
3
+
4
+ class Base
5
+ attr_reader :parent
6
+ def initialize(parent)
7
+ @parent = parent
8
+ end
9
+ end
10
+
11
+ end
12
12
  end
@@ -1,61 +1,61 @@
1
- module Lolita
2
- # All classes that want to use lolita for configuration should include this module.
3
- module Configuration
4
- # When Lolita::Configuration is included, it add hook for class <em>:after_lolita_loaded</em> and define class methods
5
- # <em>lolita</em> and <em>lolita=</em> and instance method <em>lolita</em> that refers to class method with same name.
6
- def self.included(base)
7
- base.class_eval do
8
- include Lolita::Hooks
9
- add_hook :after_lolita_loaded
10
-
11
- extend ClassMethods
12
- def lolita
13
- self.class.lolita
14
- end
15
- end
16
- end
17
-
18
- module ClassMethods
19
- # This is main method for configuration, it initialize new Lolita::Configuration::Core object, that have other methost to
20
- # define different parts of configuration.
21
- def lolita(&block)
22
- Lolita::LazyLoader.lazy_load(self,:@lolita,Lolita::Configuration::Core,self,&block)
23
- end
24
-
25
- def lolita=(value)
26
- if value.is_a?(Lolita::Configuration::Core) || value.nil?
27
- @lolita = value
28
- else
29
- raise ArgumentError.new("Only Lolita::Configuration::Core is acceptable.")
30
- end
31
- end
32
- end
33
- end
34
- end
35
-
36
- require 'lolita/configuration/base'
37
- require 'lolita/configuration/core'
38
- require 'lolita/configuration/list'
39
- require 'lolita/configuration/nested_list'
40
- require 'lolita/configuration/tabs'
41
- require 'lolita/configuration/tab'
42
- require 'lolita/configuration/columns'
43
- require 'lolita/configuration/column'
44
- require 'lolita/configuration/fields'
45
- require 'lolita/configuration/field'
46
- require 'lolita/configuration/field_set'
47
- require 'lolita/configuration/nested_form'
48
- require 'lolita/configuration/search'
49
- require 'lolita/configuration/filter'
50
- require 'lolita/configuration/action'
51
-
52
- require 'lolita/configuration/factory/field'
53
- require 'lolita/configuration/factory/tab'
54
-
55
- # Configuration for fields and tabs
56
- ["field","tab"].each do |type|
57
- Dir["#{File.dirname(__FILE__)}/configuration/#{type}/**/*.*"].each do |path|
58
- base_name=File.basename(path,".rb")
59
- require "lolita/configuration/#{type}/#{base_name}"
60
- end
1
+ module Lolita
2
+ # All classes that want to use lolita for configuration should include this module.
3
+ module Configuration
4
+ # When Lolita::Configuration is included, it add hook for class <em>:after_lolita_loaded</em> and define class methods
5
+ # <em>lolita</em> and <em>lolita=</em> and instance method <em>lolita</em> that refers to class method with same name.
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include Lolita::Hooks
9
+ add_hook :after_lolita_loaded
10
+
11
+ extend ClassMethods
12
+ def lolita
13
+ self.class.lolita
14
+ end
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ # This is main method for configuration, it initialize new Lolita::Configuration::Core object, that have other methost to
20
+ # define different parts of configuration.
21
+ def lolita(&block)
22
+ Lolita::LazyLoader.lazy_load(self,:@lolita,Lolita::Configuration::Core,self,&block)
23
+ end
24
+
25
+ def lolita=(value)
26
+ if value.is_a?(Lolita::Configuration::Core) || value.nil?
27
+ @lolita = value
28
+ else
29
+ raise ArgumentError.new("Only Lolita::Configuration::Core is acceptable.")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ require 'lolita/configuration/base'
37
+ require 'lolita/configuration/core'
38
+ require 'lolita/configuration/list'
39
+ require 'lolita/configuration/nested_list'
40
+ require 'lolita/configuration/tabs'
41
+ require 'lolita/configuration/tab'
42
+ require 'lolita/configuration/columns'
43
+ require 'lolita/configuration/column'
44
+ require 'lolita/configuration/fields'
45
+ require 'lolita/configuration/field'
46
+ require 'lolita/configuration/field_set'
47
+ require 'lolita/configuration/nested_form'
48
+ require 'lolita/configuration/search'
49
+ require 'lolita/configuration/filter'
50
+ require 'lolita/configuration/action'
51
+
52
+ require 'lolita/configuration/factory/field'
53
+ require 'lolita/configuration/factory/tab'
54
+
55
+ # Configuration for fields and tabs
56
+ ["field","tab"].each do |type|
57
+ Dir["#{File.dirname(__FILE__)}/configuration/#{type}/**/*.*"].each do |path|
58
+ base_name=File.basename(path,".rb")
59
+ require "lolita/configuration/#{type}/#{base_name}"
60
+ end
61
61
  end
@@ -1,181 +1,181 @@
1
- module Lolita
2
- module Configuration
3
- # column in a list
4
- #
5
- # === Examples
6
- # lolita do
7
- # list do
8
- # column :title, sortable: true
9
- # column :full_name, sortable: 'first_name'
10
- # column :is_public do
11
- # formatter do |value, record, view|
12
- # value ? 'Yes' : 'No'
13
- # end
14
- # end
15
- #
16
- # column do
17
- # title "ID"
18
- # name :id
19
- # formatter do|value, record, view|
20
- # view.link_to(value, view.url_for(action: 'edit', id: value))
21
- # end
22
- # end
23
- #
24
- # column :updated_at, title: 'Date', formatter: '%d.%m.%Y., %H:%M'
25
- # end
26
- # end
27
- class Column < Lolita::Configuration::Base
28
- MAX_TEXT_SIZE = 20
29
- attr_reader :list_association_name
30
- lolita_accessor :name, :title, :type, :options, :sortable, :association
31
-
32
- def initialize(dbi, *args, &block)
33
- set_and_validate_dbi(dbi)
34
- set_attributes(*args)
35
- instance_eval(&block) if block_given?
36
- validate
37
- normalize_attributes
38
- detect_association
39
- end
40
-
41
- def list(*args, &block)
42
- if args && args.any? || block_given?
43
- detect_association
44
- list_association = args[0] && @dbi.associations[args[0].to_s.to_sym] || association
45
- list_dbi = list_association && Lolita::DBI::Base.create(list_association.klass)
46
- fail Lolita::UnknownDBPError.new("DBI is not specified for list in column #{self}") unless list_dbi
47
- @list_association_name = list_association.name
48
- Lolita::LazyLoader.lazy_load(self, :@list, Lolita::Configuration::NestedList, list_dbi, self, association_name: list_association.name, &block)
49
- else
50
- @list
51
- end
52
- end
53
-
54
- # Return value of column from given record. When record matches foreign key patter, then foreign key is used.
55
- # In other cases it just ask for attribute with same name as column.
56
- def value(record)
57
- if association
58
- if association.macro == :one && dbi.klass.respond_to?(:human_attribute_name)
59
- dbi.klass.human_attribute_name(association.name)
60
- # dbi.record(record.send(association.name)).title
61
- elsif dbi.klass.respond_to?(:human_attribute_name)
62
- "#{dbi.klass.human_attribute_name(association.name)} (#{record.send(association.name).count})"
63
- else
64
- "#{association.name} (#{record.send(association.name).count})"
65
- end
66
- else
67
- record.send(name)
68
- end
69
- end
70
-
71
- def formatted_value(record, view)
72
- formatter.with(value(record), record, view)
73
- end
74
-
75
- # Set/Get title. Getter return title what was set or ask for human_attribute_name to model.
76
- def title(new_title = nil)
77
- if new_title
78
- @title = new_title
79
- end
80
- Lolita::Utils.dynamic_string(@title, default: @name && @dbi.klass.human_attribute_name(@name))
81
- end
82
-
83
- def sortable?
84
- @sortable
85
- end
86
-
87
- # Find if any of received sort options matches this column.
88
- def current_sort_state(params)
89
- @sortable && sort_pairs(params).find { |pair| pair[0] == sort_by_name } || []
90
- end
91
-
92
- # Return string with sort options for column if column is sortable.
93
- def sort_params(params)
94
- if @sortable
95
- pairs = sort_pairs(params)
96
- found_pair = false
97
- pairs.each_with_index{|pair, index|
98
- if pair[0] == sort_by_name
99
- pairs[index][1] = pair[1] == 'asc' ? 'desc' : 'asc'
100
- found_pair = true
101
- end
102
- }
103
- unless found_pair
104
- pairs << [sort_by_name, 'asc']
105
- end
106
- (pairs.map { |pair| pair.join(',') }).join('|')
107
- else
108
- ''
109
- end
110
- end
111
-
112
- # returns value to sort by
113
- # in default it will be column name, but you can specify it
114
- # in field configuration
115
- #
116
- # === Examples
117
- # list do
118
- # field :name, sortable: 'some_table.first_name'
119
- # end
120
- def sort_by_name
121
- @sortable.is_a?(TrueClass) ? name.to_s : @sortable.to_s
122
- end
123
-
124
- # Create array of sort information from params.
125
- def sort_pairs(params)
126
- (params[:s] || '').split('|').map { |pair| pair.split(',') }
127
- end
128
-
129
- # Define format, for details see Lolita::Support::Formatter and Lolita::Support::Formater::Rails
130
- def formatter(value = nil, &block)
131
- if block_given?
132
- @formatter = Lolita::Support::Formatter.new(value, &block)
133
- elsif value || !@formatter
134
- if value.kind_of?(Lolita::Support::Formatter)
135
- @formatter = value
136
- else
137
- @formatter = Lolita::Support::Formatter::Rails.new(value)
138
- end
139
- end
140
- @formatter
141
- end
142
-
143
- def formatter=(value)
144
- if value.kind_of?(Lolita::Support::Formatter)
145
- @formatter = value
146
- else
147
- @formatter = Lolita::Support::Formatter::Rails.new(value)
148
- end
149
- end
150
-
151
- def set_attributes(*args)
152
- options = args ? args.extract_options! : {}
153
- if args[0].respond_to?(:field)
154
- [:name, :type].each do |attr|
155
- send(:"#{attr}=", args[0].send(attr))
156
- end
157
- elsif args[0]
158
- self.name = args[0]
159
- end
160
- options.each do |attr_name, value|
161
- send(:"#{attr_name}=", value)
162
- end
163
- end
164
-
165
- private
166
-
167
- def detect_association
168
- @association ||= dbi.associations[name]
169
- end
170
-
171
- def normalize_attributes
172
- @name = @name.to_sym
173
- end
174
-
175
- def validate
176
- fail Lolita::UnknownDBIError.new("DBI is not specified for column #{self}") unless dbi
177
- fail ArgumentError.new('Column must have name.') unless name
178
- end
179
- end
180
- end
181
- end
1
+ module Lolita
2
+ module Configuration
3
+ # column in a list
4
+ #
5
+ # === Examples
6
+ # lolita do
7
+ # list do
8
+ # column :title, sortable: true
9
+ # column :full_name, sortable: 'first_name'
10
+ # column :is_public do
11
+ # formatter do |value, record, view|
12
+ # value ? 'Yes' : 'No'
13
+ # end
14
+ # end
15
+ #
16
+ # column do
17
+ # title "ID"
18
+ # name :id
19
+ # formatter do|value, record, view|
20
+ # view.link_to(value, view.url_for(action: 'edit', id: value))
21
+ # end
22
+ # end
23
+ #
24
+ # column :updated_at, title: 'Date', formatter: '%d.%m.%Y., %H:%M'
25
+ # end
26
+ # end
27
+ class Column < Lolita::Configuration::Base
28
+ MAX_TEXT_SIZE = 20
29
+ attr_reader :list_association_name
30
+ lolita_accessor :name, :title, :type, :options, :sortable, :association
31
+
32
+ def initialize(dbi, *args, &block)
33
+ set_and_validate_dbi(dbi)
34
+ set_attributes(*args)
35
+ instance_eval(&block) if block_given?
36
+ validate
37
+ normalize_attributes
38
+ detect_association
39
+ end
40
+
41
+ def list(*args, &block)
42
+ if args && args.any? || block_given?
43
+ detect_association
44
+ list_association = args[0] && @dbi.associations[args[0].to_s.to_sym] || association
45
+ list_dbi = list_association && Lolita::DBI::Base.create(list_association.klass)
46
+ fail Lolita::UnknownDBPError.new("DBI is not specified for list in column #{self}") unless list_dbi
47
+ @list_association_name = list_association.name
48
+ Lolita::LazyLoader.lazy_load(self, :@list, Lolita::Configuration::NestedList, list_dbi, self, association_name: list_association.name, &block)
49
+ else
50
+ @list
51
+ end
52
+ end
53
+
54
+ # Return value of column from given record. When record matches foreign key patter, then foreign key is used.
55
+ # In other cases it just ask for attribute with same name as column.
56
+ def value(record)
57
+ if association
58
+ if association.macro == :one && dbi.klass.respond_to?(:human_attribute_name)
59
+ dbi.klass.human_attribute_name(association.name)
60
+ # dbi.record(record.send(association.name)).title
61
+ elsif dbi.klass.respond_to?(:human_attribute_name)
62
+ "#{dbi.klass.human_attribute_name(association.name)} (#{record.send(association.name).count})"
63
+ else
64
+ "#{association.name} (#{record.send(association.name).count})"
65
+ end
66
+ else
67
+ record.send(name)
68
+ end
69
+ end
70
+
71
+ def formatted_value(record, view)
72
+ formatter.with(value(record), record, view)
73
+ end
74
+
75
+ # Set/Get title. Getter return title what was set or ask for human_attribute_name to model.
76
+ def title(new_title = nil)
77
+ if new_title
78
+ @title = new_title
79
+ end
80
+ Lolita::Utils.dynamic_string(@title, default: @name && @dbi.klass.human_attribute_name(@name))
81
+ end
82
+
83
+ def sortable?
84
+ @sortable
85
+ end
86
+
87
+ # Find if any of received sort options matches this column.
88
+ def current_sort_state(params)
89
+ @sortable && sort_pairs(params).find { |pair| pair[0] == sort_by_name } || []
90
+ end
91
+
92
+ # Return string with sort options for column if column is sortable.
93
+ def sort_params(params)
94
+ if @sortable
95
+ pairs = sort_pairs(params)
96
+ found_pair = false
97
+ pairs.each_with_index{|pair, index|
98
+ if pair[0] == sort_by_name
99
+ pairs[index][1] = pair[1] == 'asc' ? 'desc' : 'asc'
100
+ found_pair = true
101
+ end
102
+ }
103
+ unless found_pair
104
+ pairs << [sort_by_name, 'asc']
105
+ end
106
+ (pairs.map { |pair| pair.join(',') }).join('|')
107
+ else
108
+ ''
109
+ end
110
+ end
111
+
112
+ # returns value to sort by
113
+ # in default it will be column name, but you can specify it
114
+ # in field configuration
115
+ #
116
+ # === Examples
117
+ # list do
118
+ # field :name, sortable: 'some_table.first_name'
119
+ # end
120
+ def sort_by_name
121
+ @sortable.is_a?(TrueClass) ? name.to_s : @sortable.to_s
122
+ end
123
+
124
+ # Create array of sort information from params.
125
+ def sort_pairs(params)
126
+ (params[:s] || '').split('|').map { |pair| pair.split(',') }
127
+ end
128
+
129
+ # Define format, for details see Lolita::Support::Formatter and Lolita::Support::Formater::Rails
130
+ def formatter(value = nil, &block)
131
+ if block_given?
132
+ @formatter = Lolita::Support::Formatter.new(value, &block)
133
+ elsif value || !@formatter
134
+ if value.kind_of?(Lolita::Support::Formatter)
135
+ @formatter = value
136
+ else
137
+ @formatter = Lolita::Support::Formatter::Rails.new(value)
138
+ end
139
+ end
140
+ @formatter
141
+ end
142
+
143
+ def formatter=(value)
144
+ if value.kind_of?(Lolita::Support::Formatter)
145
+ @formatter = value
146
+ else
147
+ @formatter = Lolita::Support::Formatter::Rails.new(value)
148
+ end
149
+ end
150
+
151
+ def set_attributes(*args)
152
+ options = args ? args.extract_options! : {}
153
+ if args[0].respond_to?(:field)
154
+ [:name, :type].each do |attr|
155
+ send(:"#{attr}=", args[0].send(attr))
156
+ end
157
+ elsif args[0]
158
+ self.name = args[0]
159
+ end
160
+ options.each do |attr_name, value|
161
+ send(:"#{attr_name}=", value)
162
+ end
163
+ end
164
+
165
+ private
166
+
167
+ def detect_association
168
+ @association ||= dbi.associations[name]
169
+ end
170
+
171
+ def normalize_attributes
172
+ @name = @name.to_sym
173
+ end
174
+
175
+ def validate
176
+ fail Lolita::UnknownDBIError.new("DBI is not specified for column #{self}") unless dbi
177
+ fail ArgumentError.new('Column must have name.') unless name
178
+ end
179
+ end
180
+ end
181
+ end