# Note: # For includes to work with namespaces other than the root namespace, the # full namespaced class_name has to be set in the model on the association # being included. For example: # # class Animals::Dog # has_many :friends, :class_name => 'Animals::Dog' # end # module Caboose class PageBarGenerator # # Parameters: # params: array of key/value pairs that must include the following: # base_url: url without querystring onto which the parameters are added. # itemCount: Total number of items. # # In addition, the following parameters are not required but may be # included in the array: # itemsPerPage: Number of items you want to show per page. Defaults to 10 if not present. # page: Current page number. Defaults to 0 if not present. # attr_accessor :params, :options, :custom_url_vars #def initialize(post_get, params = nil, options = nil, &custom_url_vars = nil) def initialize(post_get, params = nil, options = nil) params = {} if params.nil? options = {} if options.nil? # Note: a few keys are required: # base_url, page, itemCount, itemsPerPage @params = {} @options = { 'model' => '', 'sort' => '', 'desc' => 0, 'base_url' => '', 'page' => 1, 'item_count' => 0, 'items_per_page' => 10, 'abbreviations' => {}, 'skip' => [], # params to skip when printing the page bar 'includes' => nil # Hash of association includes # { # search_field_1 => [association_name, join_table, column_name], # search_field_2 => [association_name, join_table, column_name] # } } params.each { |key, val| @params[key] = val } options.each { |key, val| @options[key] = val } @params.each { |key, val| k = @options['abbreviations'].include?(key) ? @options['abbreviations'][key] : key @params[key] = post_get[key].nil? ? (post_get[k].nil? ? val : post_get[k]) : post_get[key] } @options.each { |key, val| @options[key] = post_get[key].nil? ? val : post_get[key] } #@custom_url_vars = custom_url_vars if !custom_url_vars.nil? fix_desc set_item_count end def set_item_count @options['item_count'] = model_with_includes.where(where).count end def model_with_includes m = @options['model'].constantize return m if @options['includes'].nil? associations = [] @options['includes'].each do |field, arr| next if @params[field].nil? || (@params[field].kind_of?(String) && @params[field].length == 0) associations << arr[0] end associations.uniq.each { |assoc| m = m.includes(assoc) } return m end def table_name_of_association(assoc) return @options['model'].constantize.reflect_on_association(assoc.to_sym).class_name.constantize.table_name end def fix_desc @options['desc'] = 0 and return if @options['desc'].nil? return if @options['desc'] == 1 return if @options['desc'] == 0 @options['desc'] = 1 and return if @options['desc'] == 'true' || @options['desc'].is_a?(TrueClass) @options['desc'] = 0 and return if @options['desc'] == 'false' || @options['desc'].is_a?(FalseClass) @options['desc'] = @options['desc'].to_i end def ok(val) return false if val.nil? return true if val.is_a? Array return true if val.is_a? Hash return true if val.is_a? Integer return true if val.is_a? Fixnum return true if val.is_a? Float return true if val.is_a? Bignum return true if val.is_a? TrueClass return true if val.is_a? FalseClass return false if val == "" return true end def items assoc = model_with_includes.where(where) if @options['items_per_page'] != -1 assoc = assoc.limit(limit).offset(offset) end return assoc.reorder(reorder).all end def all_items return model_with_includes.where(where).all end def item_values(attribute) arr = [] model_with_includes.where(where).all.each do |m| arr << m[attribute] end return arr.uniq end def generate # Check for necessary parameter values return false if !ok(@options['base_url']) # Error: base_url is required for the page bar generator to work. return false if !ok(@options['item_count']) # Error: itemCount is required for the page bar generator to work. # Set default parameter values if not present @options['items_per_page'] = 10 if @options["items_per_page"].nil? @options['page'] = 1 if @options["page"].nil? page = @options["page"].to_i # Max links to show (must be odd) total_links = 5 prev_page = page - 1 next_page = page + 1 total_pages = (@options['item_count'].to_f / @options['items_per_page'].to_f).ceil if (total_pages < total_links) start = 1 stop = total_pages else start = page - (total_links/2).floor start = 1 if start < 1 stop = start + total_links - 1 if (stop > total_pages) stop = total_pages start = stop - total_links start = 1 if start < 1 end end base_url = url_with_vars base_url << (Caboose.use_url_params ? "/" : (base_url.include?("?") ? "&" : "?")) keyval_delim = Caboose.use_url_params ? "/" : "=" var_delim = Caboose.use_url_params ? "/" : "&" str = '' str << "
Results: showing page #{page} of #{total_pages}
\n" if (total_pages > 1) str << "