usefull_filter 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ 0.0.1 (11 July 2012)
2
+ - Starting projeect
3
+ - test
4
+ -test2
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ #You can add lacal gems with
2
+ # gem "my_gem", :path => "/home/www/gems/my_gem"
3
+ #you must remove the path in production or if you change server and replace with:
4
+ # git "git@10.2.252.240:my_gem.git"
5
+
6
+ source "http://rubygems.org"
7
+
8
+ gem "rails", "~>3.0.14"
9
+ gem "meta_search"
10
+
11
+ group :development, :test do
12
+ gem "ruby-debug"
13
+ gem "capybara", ">= 0.4.0"
14
+ gem "sqlite3"
15
+ gem "single_test"
16
+ end
17
+
18
+ gemspec
19
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = UsefullFilter
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ require "bundler/gem_tasks"
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+
10
+ require 'rake'
11
+ require 'rake/testtask'
12
+ require 'rdoc/task'
13
+
14
+
15
+
16
+ Rake::TestTask.new(:test) do |t|
17
+ t.libs << 'lib'
18
+ t.libs << 'test'
19
+ t.pattern = 'test/**/*_test.rb'
20
+ t.verbose = false
21
+ end
22
+
23
+ task :default => :test
24
+
25
+ Rake::RDocTask.new(:rdoc) do |rdoc|
26
+ rdoc.rdoc_dir = 'rdoc'
27
+ rdoc.title = 'usefull_filter'
28
+ rdoc.options << '--line-numbers' << '--inline-source'
29
+ rdoc.rdoc_files.include('README.rdoc')
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ end
32
+
@@ -0,0 +1,72 @@
1
+ #require "usefull_filter/filter_form_builder"
2
+ #L'helper si occupa di wrappare la classe MetaSearch permettendo l'utilizzo di Filtri selezionabili dall'utente
3
+ #
4
+ #[documents_controller]
5
+ # Vedi TableHelper
6
+ #
7
+ #[index.html.erb]
8
+ # <%=filter_for_new @search, :url => magazzino_documents_path do |f| %>
9
+ # <%= f.text_field :data, :size => 10, :filters => ["equals", "less_than_or_equal_to", "greater_than_or_equal_to"] %>
10
+ # <%= f.text_field :DoCNr, :filters_type => :number %>
11
+ # <%= f.text_field :TbDoC, :filters_only => ["equals"] %>
12
+ # <%= f.text_field :BollaXENrDoC, filters_except => ["equals", "does_not_equal"] %>
13
+ # <%= f.text_field :DoCSit %>
14
+ # <%= f.submit %>
15
+ # <% end %>
16
+ module UsefullFilterHelper
17
+ #Contatta l'url passato ripassando i filtri attivi in @search
18
+ def filter_button_tag(name, url, method = :get)
19
+ if @search.kind_of?(MetaSearch::Builder)
20
+ form_tag(url, :method => method) do
21
+ @search.search_attributes.each do |k,v|
22
+ if v.kind_of?(Array)
23
+ v.each{|vv| concat hidden_field_tag("search[#{k}][]", vv)}
24
+ else
25
+ concat hidden_field_tag("search[#{k}]", v)
26
+ end
27
+ end
28
+ concat submit_tag(name)
29
+ end
30
+ end
31
+ end
32
+
33
+ def filter_for_new(obj, *args, &proc)
34
+ filter_for(obj, *args, &proc)
35
+ end
36
+
37
+ #Cerca una serie di filtri utilizzando MetaSearch di cui fa il wrapper
38
+ #obj è una istanza metashearch
39
+ def filter_for(obj, *args, &proc)
40
+ unless obj.blank?
41
+ options = args.extract_options!
42
+
43
+ options[:html] ||= {}
44
+ options[:html][:select] ||= {}
45
+ options[:html][:input] ||= {}
46
+ options[:html][:method] ||= :get
47
+ options[:html][:class] ||= "usefull_filter_container"
48
+ options[:html_1] = options.delete(:html)
49
+ options.merge!(:builder => UsefullFilter::FilterFormBuilder)
50
+
51
+ remove_filter_label = I18n.t("remove_filter", :scope => "meta_search.buttons")
52
+ filter_title = I18n.t("filter_title", :scope => "meta_search.buttons")
53
+
54
+ #Estraggo le options che mi interessano, perchè una volta passate al builder
55
+ #per qulache arcano motivo vengono alterate....
56
+ classe = options[:html_1].delete(:class)
57
+ url = options[:url]
58
+ #UserSession.log("FilterHelper#filter_for_new: options=#{options.inspect}")
59
+ content_tag(:div,
60
+ content_tag(:h3, filter_title) +
61
+ content_tag(:ul,
62
+ form_for(obj, *(args << options), &proc) +
63
+ form_tag(url_for(url), :method => :get) do
64
+ obj.search_attributes.each_key {|k| concat hidden_field_tag("search[#{k}]") }
65
+ concat submit_tag(remove_filter_label, :class => "usefull_filter_push-2")
66
+ end ),
67
+ :class => classe)
68
+ end
69
+ end
70
+
71
+ end
72
+
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+ module UsefullFilter
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Install generator for UsefullFilter gem"
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+ #def copy_config
8
+ # directory "config"
9
+ #end
10
+
11
+ #def copy_public
12
+ # directory "public"
13
+ #end
14
+
15
+ end
16
+ end
17
+
@@ -0,0 +1,7 @@
1
+ module UsefullFilter
2
+ end
3
+
4
+ require "meta_search"
5
+ require "usefull_filter/engine"
6
+ require "usefull_filter/exceptions"
7
+ #require "usefull_filter/filter_builder"
@@ -0,0 +1,20 @@
1
+ module UsefullFilter
2
+ class Engine < Rails::Engine
3
+
4
+ config.autoload_paths += Dir["#{config.root}/lib/**/"]
5
+
6
+ initializer 'usefull_filter.helper' do |app|
7
+ ActiveSupport.on_load(:action_controller) do
8
+ include UsefullFilterHelper
9
+ end
10
+ ActiveSupport.on_load(:action_view) do
11
+ include UsefullFilterHelper
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ #Add ere require to specific file or gem used
20
+
@@ -0,0 +1,17 @@
1
+ #Localize messages in it.CustomError.MyError
2
+ module UsefullFilter
3
+ class CustomError < StandardError
4
+ def initialize(*args)
5
+ @options = args.extract_options!
6
+ super
7
+ end
8
+
9
+ def message
10
+ @options.merge!({:default => "Error : #{@options.inspect}"})
11
+ I18n.t("#{self.class.name.gsub(/::/,'.')}", @options )
12
+ end
13
+ end
14
+
15
+ #class MyError < CustomError; end
16
+ end
17
+
@@ -0,0 +1,183 @@
1
+ module UsefullFilter
2
+ class FilterFormBuilder < ActionView::Helpers::FormBuilder
3
+
4
+ DEFAULT_TYPES=["equals", "does_not_equal", "in", "not_in"]
5
+ STRING_TYPES=["contains", "does_not_contain", "starts_with", "does_not_start_with", "ends_with", "does_not_end_with"]
6
+ NUMBER_TYPES=["greater_than", "greater_than_or_equal_to", "less_than", "less_than_or_equal_to"]
7
+ BOOLEAN_TYPES=["is_true", "is_false"]
8
+ OTHER_TYPES=["is_present", "is_blank"]
9
+
10
+ #Ridefinisco il metodo per wrapparlo all'interno di una lista
11
+ #Accetta i seguenti parametri:
12
+ #* :default_filter => "equals"
13
+ #* :filters => ["equals", ....]
14
+ #
15
+ #Il nome sarà del tipo
16
+ #* :ART
17
+ #* "document.activity.id" (come per la tabelle)
18
+ def text_field(object_name, *args)
19
+ opt = define_args(args, object_name)
20
+ name = object_name.to_s.gsub(/\./, "_")
21
+ opt.merge!(@options[:html_1][:input])
22
+ #UserSession.log("FilterHelper#text_field:opt=#{opt.inspect}")
23
+ @template.content_tag(:li) do
24
+ @template.concat filter_list(name, opt[:default_filter], opt)
25
+ @template.concat " "
26
+ @template.concat super(default(name, opt[:default_filter]), opt)
27
+ ##UserSession.log("FilterHelper#text_field:object_name=#{object_name.inspect}")
28
+ #@template.concat attribute_type(object_name) == :Date ? @template.link_to(@template.image_tag('calendar16.png'), '#', :onclick => "show_calendar('search_data_prevista_equals')") : ''
29
+ end
30
+ end
31
+
32
+ #Utilizza come filtro una combo, con i valori passati nell'array
33
+ def select(object_name, array, *args)
34
+ opt = define_args(args, object_name)
35
+ name = object_name.to_s.gsub(/\./, "_")
36
+ opt.merge!(@options[:html_1][:input])
37
+ @template.content_tag(:li) do
38
+ @template.concat filter_list(name, opt[:default_filter], opt)
39
+ @template.concat " "
40
+ #@template.concat select("search", default(name, opt[:default_filter]), array.collect {|p| [p,p]}, opt)
41
+ @template.concat super(default(name, opt[:default_filter]), array, opt)
42
+ ##UserSession.log("FilterHelper#text_field:object_name=#{object_name.inspect}")
43
+ end
44
+ end
45
+
46
+ #Utilizza come filtro un elenco di valori rappresentati da una check_box
47
+ #che vengono gestiti come OR
48
+ #def checks(object_name, array, *args, &block)
49
+ # super.to_s.html_safe
50
+ #end
51
+
52
+
53
+ #Genera una doppia text_box per gestire i filtri tra due
54
+ def between_field(object_name, *args)
55
+ opt = define_args(args, object_name)
56
+ name = object_name.to_s.gsub(/\./, "_")
57
+ @template.content_tag(:li,
58
+ multiparameter_field(name.to_s + "_between",
59
+ {:field_type => :text_field}, {:field_type => :text_field}, :size => 5))
60
+ end
61
+
62
+ def submit
63
+ applay_filter_label = I18n.t(:applay_filter, :scope => "meta_search.buttons")
64
+ super(applay_filter_label, :class => "usefull_filter_push-1")
65
+ end
66
+
67
+ private
68
+
69
+ #Aggiusta il vettore dei parametri passati
70
+ #* :default_filter => "equals" filtro di default che deve essere presente in tutti i metodi
71
+ #* :filters_only => ["equals", .. ] elenco di filtri da utilizzare, rimpiazza anche i dafault
72
+ #* :filters_except => ["equals", .. ] elenco di filtri da escludere
73
+ #* :filters => [..] elenco dei filtri richiesti, sovrascrive i default
74
+ #* :filters_type => :string | :number | :boolean | :other da aggiungere a quelli gia presenti
75
+ def define_args(args, object_name)
76
+ opt = args.extract_options!
77
+ #Il filtro di default e _equals che deve essere presente su tutti i campi
78
+ opt[:filters] ||= DEFAULT_TYPES + type(object_name)
79
+ opt[:default_filter] ||= opt[:filters].include?("equals") ? "equals" : opt[:filters].first
80
+ opt[:filters_only] ||= []
81
+ opt[:filters_except] ||= []
82
+ case opt[:filters_type]
83
+ when :string
84
+ opt[:filters] |= STRING_TYPES
85
+ when :number
86
+ opt[:filters] |= NUMBER_TYPES
87
+ when :boolean
88
+ opt[:filters] |= BOOLEAN_TYPES
89
+ when :other
90
+ opt[:filters] |= OTHER_TYPES
91
+ end
92
+
93
+ opt[:filters] -= opt[:filters_except]
94
+ opt[:filters] = opt[:filters_only] unless opt[:filters_only] .blank?
95
+ opt
96
+ end
97
+
98
+ #Costruisce l'elenco dei filtri da utilizzare
99
+ #seleziona come selected il parametro trovato in params[] per garantire coerenza dopo il reload
100
+ def options_list(object_name, args, default_filter="equals")
101
+ filters = args[:filters].dup
102
+ filters.map! {|o|
103
+ "<option value = '" + object_name.to_s + "_" + o + "'" +
104
+ (default(object_name,default_filter) == object_name.to_s + "_" + o ? " selected = 'selected'" : "") +
105
+ " >" +
106
+ I18n.t(o, :scope =>"meta_search.predicates", :attribute => human(object_name)) +
107
+ "</option>"}
108
+ filters.join("").html_safe
109
+ end
110
+
111
+ #Crea una lista dei filtri disponibili per il campo
112
+ def filter_list(object_name, default_filter, args)
113
+ list = options_list(object_name, args,default_filter)
114
+ ##UserSession.log("FilterHelper#filter_list:options=#{@options.inspect}")
115
+ #UserSession.log("FilterFormBuilder#filter_list list=#{list}")
116
+ #@template.select_tag(object_name, list.html_safe, :onchange => "document.getElementById('search_' + #{object_name.to_s}).name = 'search[' + this + ']'")
117
+ @options[:html_1][:select][:onchange] = "$(#{'search_' + default(object_name,default_filter)}).name = 'search[' + this.value + ']'; $(#{'search_' + default(object_name, default_filter)}).id = 'search_' + this.value "
118
+ @options[:html_1][:select][:id] = object_name.to_s
119
+ @options[:html_1][:select][:class] = "select_dati"
120
+ ##UserSession.log("FilterHelper#filter_list:options(before select_tag)=#{@options.inspect}")
121
+ @template.select_tag("", list, @options[:html_1][:select])
122
+ end
123
+
124
+ #Restituisce l'elenco dei filtri associati al tipo di dati del DB
125
+ def type(object_name)
126
+ #case @object.base.columns_hash[object_name.to_s].type
127
+ case attribute_type(object_name)
128
+ when :String then
129
+ STRING_TYPES
130
+ when :Bignum, :Fixnum, :Float, :Date, :Time, :Datetime then
131
+ NUMBER_TYPES
132
+ when :TrueClass, :FalseClass then
133
+ BOOLEAN_TYPES
134
+ when nil
135
+ []
136
+ else
137
+ OTHER_TYPES
138
+ end
139
+ end
140
+
141
+ #Restituisce il tipo dellìattributo
142
+ #gestendo i multilivello document.activity.data_prevista => :Date
143
+ #==Nota:
144
+ #* non testata con le relazioni polimorfiche...
145
+ #* con metodi definit all'utente, restiuisce nil
146
+ def attribute_type(attribute_name)
147
+ #UserSession.log("FilterFormBuilder#attribute_type attribute_name=#{attribute_name}, base=#{@object.base.name}")
148
+ #Aggiungo self. daventi in quanto i campi tipo ART vengono confusi per costanti se non specifico il contesto. SIGH!
149
+
150
+ attributes = attribute_name.to_s.split(".")
151
+ base = @object.base
152
+ method = attributes.pop
153
+ #UserSession.log("FilterFormBuilder#attribute_type(1) method=#{method}, base=#{base.name}, attributes=#{attributes.inspect}")
154
+ if attributes.length > 0
155
+ attributes.each do |association|
156
+ reflection = base.reflect_on_association(association.to_sym)
157
+ base = reflection.blank? ? nil : reflection.klass
158
+ end
159
+ end
160
+ ##UserSession.log("FilterFormBuilder#attribute_type(2) method=#{method}")
161
+ base.columns_hash[method.to_s].klass.name.to_sym unless base.blank? || base.columns_hash[method.to_s].blank?
162
+ end
163
+
164
+ #Restituisce il nome del campo preso da ActiveRecord
165
+ def human(object_name)
166
+ ##UserSession.log("FilterFormBuilder#human classe=#{@object.class.name}")
167
+ @object.base.human_attribute_name(object_name.to_s)
168
+ end
169
+
170
+ #Restituisce il valore di default prelevato da params[]
171
+ #altrimenti restituisce nome_equals
172
+ def default(nome, filter="equals")
173
+ out = ""
174
+ @object.search_attributes.each_key do |k|
175
+ out = k unless k.match(/^#{nome.to_s}/).nil?
176
+ end
177
+ out = out.blank? ? nome.to_s + "_" + filter : out
178
+ out
179
+ end
180
+
181
+ end
182
+
183
+ end
@@ -0,0 +1,4 @@
1
+ module UsefullFilter
2
+ VERSION = "0.0.4"
3
+ end
4
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: usefull_filter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
11
+ platform: ruby
12
+ authors:
13
+ - Andrea Bignozzi
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-07-13 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ hash: 27
27
+ segments:
28
+ - 3
29
+ - 0
30
+ - 14
31
+ version: 3.0.14
32
+ type: :runtime
33
+ requirement: *id001
34
+ prerelease: false
35
+ name: rails
36
+ - !ruby/object:Gem::Dependency
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ requirement: *id002
48
+ prerelease: false
49
+ name: meta_search
50
+ description: Wraps meta_search with usefull helpers
51
+ email:
52
+ - skylord73@gmail.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - app/helpers/usefull_filter_helper.rb
61
+ - lib/usefull_filter/engine.rb
62
+ - lib/usefull_filter/filter_form_builder.rb
63
+ - lib/usefull_filter/exceptions.rb
64
+ - lib/usefull_filter/version.rb
65
+ - lib/generators/usefull_filter/install/install_generator.rb
66
+ - lib/usefull_filter.rb
67
+ - MIT-LICENSE
68
+ - Rakefile
69
+ - Gemfile
70
+ - README.rdoc
71
+ - CHANGELOG.md
72
+ homepage:
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Wraps meta_search with usefull helpers
105
+ test_files: []
106
+