require 'magic_grid/logger' require 'magic_grid/collection' require 'magic_grid/column' require 'magic_grid/order' require 'active_support/core_ext' module MagicGrid class Definition attr_reader :columns, :options, :params def magic_collection @collection end def collection @collection.collection end DEFAULTS = { :class => [], :top_pager => false, :bottom_pager => true, :remote => false, :min_search_length => 3, :id => false, :searcher => false, :needs_searcher => false, :live_search => false, :listeners => {}, :collapse_empty_header => false, :collapse_empty_footer => false, :default_ajax_handler => true, :default_order => :asc, :search_button => false, :searcher_size => nil, :title => nil, } def self.runtime_defaults # run these lazily to catch any late I18n path changes DEFAULTS.merge(Collection::DEFAULTS).merge( :if_empty => I18n.t("magic_grid.no_results").capitalize, # "No results found." :searcher_label => I18n.t("magic_grid.search.label").capitalize + ': ', # "Search: " :searcher_tooltip => I18n.t("magic_grid.search.tooltip"), # "type.. + " :searcher_button => I18n.t("magic_grid.search.button").capitalize # "Search" ) end def self.normalize_columns_options(cols_or_opts, opts) case cols_or_opts when Hash options = runtime_defaults.merge(cols_or_opts.reject {|k| k == :cols}) columns = cols_or_opts.fetch(:cols, []) when Array options = runtime_defaults.merge opts columns = cols_or_opts else raise "I have no idea what that is, but it's not a columns list or options hash" end [options, columns] end def initialize(cols_or_opts, collection = nil, controller = nil, opts = {}) @options, @columns = *self.class.normalize_columns_options(cols_or_opts, opts) @params = controller && controller.params || {} @collection = Collection.create_or_reuse collection, options @columns = Column.columns_for_collection(magic_collection, columns, options[:searchable]) columns.each do |col| if col.sortable? if col.id == current_sort_col col.order = current_order else col.order = Order::Unordered end else col.order = Order::Unsortable end end apply_collection_params end def apply_collection_params magic_collection.apply_sort(columns[current_sort_col], current_order.to_sql) magic_collection.apply_filter filters magic_collection.apply_pagination(current_page) magic_collection.apply_search current_search magic_collection.per_page = options[:per_page] magic_collection.apply_filter_callback options[:listener_handler] magic_collection.enable_post_filter options[:collection_post_filter] magic_collection.add_post_filter_callback options[:post_filter] end def filters @filters ||= begin filter_keys = options[:listeners].values params.slice(*filter_keys).reject {|k,v| v.to_s.empty? } end end def current_sort_col @current_sort_col ||= begin given = param(:col, -1) if given >= 0 and given <= columns.count given else options[:default_col].to_i end end end def default_order @default_order ||= Order.from_param(options[:default_order]) end def current_order @current_order ||= Order.from_param(param(:order, default_order.to_param)) end def current_search param(:q, "") end def magic_id options[:id] || (Column.hash_string(columns) + magic_collection.hash_string) end def searchable? magic_collection.searchable? end def needs_searcher? options[:needs_searcher] or (searchable? and not options[:searcher]) end def searcher if needs_searcher? param_key(:searcher) else options[:searcher] end end def has_title? options[:title] || false end def title options[:title] end def param_key(key) "#{magic_id}_#{key}".to_sym end def param(key, default=nil) params.fetch(param_key(key), default) end def base_params params.merge :magic_grid_id => magic_id end def current_page [param(:page, 1).to_i, 1].max end end end