module SimpleSearch module ViewHelper # Example: # # <%= order_by :name %> # <%= order_by :name, 'Company Name' %> # <%= order_by :name, 'Company Name', :class=>'bold' %> def order_link(order_to, name=nil, html_options={}) raise Exception, "must be used in a view" unless (request.fullpath && request.parameters) # check if order_by is in an url array matches = request.fullpath.match Regexp.new("[\&\?]([a-z_]+)\\[order_by\\]=") # &array[order_by] order_arr_key = (matches && matches.length == 2) ? matches[1] : nil # get order_by value order_by_value = order_arr_key ? request.parameters[order_arr_key][:order_by] : request.parameters[:order_by] if order_by_value order_by_col, current_order = order_by_value.split(" ") else order_by_col, current_order = order_to.to_s, "" end order_to = order_to.to_s.strip order_by_col.strip! order_by_value.strip! unless order_by_value.nil? # determine next order next_order = order_to==order_by_col ? {'asc'=>'desc', 'desc'=>'asc'}[current_order] : 'asc' # build new url params params = request.parameters.clone new_url_params = if order_arr_key old_arr = params[order_arr_key] new_arr = old_arr.merge(:order_by => "#{order_to} #{next_order}") params.merge(order_arr_key => new_arr) else params.merge(:order_by => "#{order_to} #{next_order}" ) end # build link text name ||= order_to.gsub(/_/," ").strip.titleize order_indicator = order_to==order_by_col ? {'asc'=>'▲', 'desc'=>'▼'}[current_order] : "" link_text = "#{name} #{order_indicator}".strip link_to raw(link_text), new_url_params, html_options end # # Returns page related properties in hash # def page_properties(arel) total_rows = arel.limit(1000000).offset(0).count # check if page is in an url array matches = request.fullpath.match Regexp.new("\&([a-z_]+)\\[page|page_by\\]=") # &array[page] page_arr_key = (matches && matches.length == 2) ? matches[1] : nil # get current page value page = page_arr_key ? request.parameters[page_arr_key][:page] : request.parameters[:page] page ||= 1 page = page.to_i page_by = page_arr_key ? request.parameters[page_arr_key][:page_by] : request.parameters[:page_by] page_by ||= 30 page_by = page_by.to_i last_page = total_rows / page_by.to_i last_page += 1 if total_rows % page_by.to_i != 0 { :total_rows => total_rows, :last_page => last_page, :current_page => (page || 1).to_i, :rows_per_page => (page_by || 30).to_i, :page_arr_key => page_arr_key } end # # Returns a url params in hash for the page number given # def page_params(page_num, page_by, page_arr_key=nil) params = if page_arr_key old_arr = request.parameters[page_arr_key].with_indifferent_access request.parameters.merge(page_arr_key => old_arr.merge(:page => page_num, :page_by => page_by ) ) else request.parameters.merge(:page => page_num, :page_by => page_by ) end params.with_indifferent_access end # # Returns page url params in hash with the page number as key # def page_url_params(arel, options={}) page_props = options[:page_props] || page_properties(arel) num_pages = options[:num_pages] || 5 num_bf_af = (num_pages-1)/2 current_page = page_props[:current_page] last_page = page_props[:last_page] page_numbers = [1, last_page] page_numbers << ([current_page-num_bf_af,1].max..[current_page+num_bf_af,last_page].min).to_a page_numbers << last_page page_numbers = page_numbers.flatten.uniq.sort page_url_params = {} for num in page_numbers page_url_params[num] = page_params(num, page_props[:rows_per_page], page_props[:page_arr_key]) end page_url_params end def page_urls(arel, http_options={}) page_urls = [] prev_page = 0 page_props = page_properties(arel) page_url_params(arel, :page_props => page_props ).each { |page, url_params| if page.to_i > (prev_page+1) # page number jumped up, need to have some indicator page_urls << "..." end new_options = page_props[:current_page] == page ? http_options.merge({:class => 'current'}) : http_options page_urls << link_to(page, url_params, new_options) prev_page = page } page_urls end end end