column_sort 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/CHANGELOG +3 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +33 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +51 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/column_sort.rb +2 -0
- data/lib/column_sort/column_sort_helper.rb +58 -0
- data/lib/column_sort/column_sort_in_model.rb +67 -0
- data/lib/column_sort/engine.rb +6 -0
- data/lib/column_sort/railtie.rb +21 -0
- data/spec/column_sort_spec.rb +7 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +202 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +12 -0
- metadata +162 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.8.0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "bundler", "~> 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.8.4"
|
13
|
+
gem "rcov", ">= 0"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.3)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.8.4)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rdoc
|
11
|
+
json (1.7.3)
|
12
|
+
rake (0.9.2.2)
|
13
|
+
rcov (0.9.11)
|
14
|
+
rdoc (3.12)
|
15
|
+
json (~> 1.4)
|
16
|
+
rspec (2.8.0)
|
17
|
+
rspec-core (~> 2.8.0)
|
18
|
+
rspec-expectations (~> 2.8.0)
|
19
|
+
rspec-mocks (~> 2.8.0)
|
20
|
+
rspec-core (2.8.0)
|
21
|
+
rspec-expectations (2.8.0)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
rspec-mocks (2.8.0)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
bundler (~> 1.0.0)
|
30
|
+
jeweler (~> 1.8.4)
|
31
|
+
rcov
|
32
|
+
rdoc (~> 3.12)
|
33
|
+
rspec (~> 2.8.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Jeremiah Hemphill
|
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,51 @@
|
|
1
|
+
= column_sort
|
2
|
+
|
3
|
+
Sort columns for index pages on admins.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Add to your Gemfile
|
8
|
+
|
9
|
+
gem "column_sort"
|
10
|
+
|
11
|
+
Mark sortable fields in the model
|
12
|
+
|
13
|
+
class Person < ActiveRecord::Base
|
14
|
+
|
15
|
+
scope :column_sort_first_name_asc, lambda { order("people.first_name ASC") }
|
16
|
+
scope :column_sort_first_name_desc, lambda { order("people.first_name DESC") }
|
17
|
+
...
|
18
|
+
sortable_fields [:first_name, :last_name, :date_of_birth]
|
19
|
+
|
20
|
+
* IMPORTANT NOTE: the sortable fields call must go after all of the sorting scopes due to ruby mixin load order
|
21
|
+
* Complex sorts can always be added with the syntax scope :column_sort_<fieldname>_asc
|
22
|
+
|
23
|
+
Add the sorting scope to the query in the controller and set a default sort (optional)
|
24
|
+
|
25
|
+
class PeopleController < ApplicationController
|
26
|
+
def index
|
27
|
+
default_column_sort(:last_name)
|
28
|
+
@people = Person.active.column_sort(params[:column_sort])
|
29
|
+
end
|
30
|
+
|
31
|
+
Use the helper on the view to link to sorted links to the page
|
32
|
+
|
33
|
+
%table
|
34
|
+
%th
|
35
|
+
First Name
|
36
|
+
= column_sort :first_name
|
37
|
+
|
38
|
+
== Contributing to column_sort
|
39
|
+
|
40
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
41
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
42
|
+
* Fork the project.
|
43
|
+
* Start a feature/bugfix branch.
|
44
|
+
* Commit and push until you are happy with your contribution.
|
45
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
46
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
47
|
+
|
48
|
+
== Copyright
|
49
|
+
|
50
|
+
Copyright (c) 2012 Jeremiah Hemphill. See LICENSE.txt for
|
51
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "column_sort"
|
18
|
+
gem.homepage = "http://github.com/jeremiahishere/column_sort"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = "Column sorting for index pages"
|
21
|
+
gem.description = "Column sorting for index pages"
|
22
|
+
gem.email = "jeremiah@cloudspace.com"
|
23
|
+
gem.authors = ["Jeremiah Hemphill"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rdoc/task'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "column_sort #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/column_sort.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module ColumnSort
|
2
|
+
module ColumnSortHelper
|
3
|
+
|
4
|
+
# Sets the default column sort for the view
|
5
|
+
# Updates the params directly
|
6
|
+
#
|
7
|
+
# @param [String or Symbol] column The name of the sort column
|
8
|
+
# @param [String or Symbol] column The direction of the sort
|
9
|
+
def set_default_column_sort(column, direction)
|
10
|
+
if params.present?
|
11
|
+
if params[:column_sort].nil?
|
12
|
+
params[:column_sort] = {
|
13
|
+
:column => column,
|
14
|
+
:direction => direction
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generates a link that sorts the page based on the current params
|
21
|
+
#
|
22
|
+
# @param [Symbol] column_symbol The name of the sort column
|
23
|
+
# @param [String] column_name Display name for the sort column, defaults to the titlezed sort column
|
24
|
+
#
|
25
|
+
# @return [String] Link back to the current page with the new sorting parameters
|
26
|
+
def column_sort_link(column_symbol, column_name = nil)
|
27
|
+
# default column name to column symbol titleized
|
28
|
+
column_name = column_symbol.to_s.titleize if column_name.nil?
|
29
|
+
|
30
|
+
# set default link attributes
|
31
|
+
# note that we default to ascending search
|
32
|
+
link_attributes = {:column_sort => { :column => column_symbol, :direction => "asc" }}
|
33
|
+
|
34
|
+
# start building the link text
|
35
|
+
link_text = column_name
|
36
|
+
if params[:column_sort].present?
|
37
|
+
if params[:column_sort][:column].to_s == column_symbol.to_s
|
38
|
+
# if sorting on the current column, add an arrow for the current direction and make the link sort in the opposite direction
|
39
|
+
if params[:column_sort][:direction].to_s == "desc"
|
40
|
+
link_text += '▼' # ▼
|
41
|
+
link_attributes[:column_sort][:direction] = "asc"
|
42
|
+
else
|
43
|
+
link_text += '▲' # ▲
|
44
|
+
link_attributes[:column_sort][:direction] = "desc"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
# if not sorting on the current column, add a diamond and use the default sort direction
|
48
|
+
link_text += ' ♦' # ♦
|
49
|
+
end
|
50
|
+
else
|
51
|
+
# if no sort is specified, add a diamond and use the default sort direction
|
52
|
+
link_text += ' ♦' # ♦
|
53
|
+
end
|
54
|
+
# return html string for an a tag with the correct request parameters
|
55
|
+
link_to link_text.html_safe, link_attributes
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ColumnSort
|
2
|
+
module ColumnSortInModel
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
# Set the different types of sorts the front end can call
|
11
|
+
#
|
12
|
+
# This method is used to ensure that whatever sort is called from the column_sort scope will not
|
13
|
+
# trigger a missing method exception. This will throw exceptions for the missing scopes when the
|
14
|
+
# application. Additionally, sorts that are not included in this list will not be executed when
|
15
|
+
# column_sort is called. Taking strings from a params hash and directly converting them to method
|
16
|
+
# names without any security is a little scary.
|
17
|
+
#
|
18
|
+
# This method is optional. If it is not called, column_sort will blindly attempt to call any scope
|
19
|
+
# given to it.
|
20
|
+
#
|
21
|
+
# @param [Array] An array of column names
|
22
|
+
def sortable_columns(columns)
|
23
|
+
columns = [columns] unless columns.is_a? Array
|
24
|
+
mattr_accessor :sortable_column_list
|
25
|
+
self.sortable_column_list = columns
|
26
|
+
|
27
|
+
columns.each do |column|
|
28
|
+
if !self.respond_to?("column_sort_#{column}_asc") || !self.respond_to?("column_sort_#{column}_desc")
|
29
|
+
throw "Missing sort scope for #{column}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Calls a sorting scope based on the given parameters
|
35
|
+
#
|
36
|
+
# If the column and direction parameters are set, attempt to find a matching scope and call it.
|
37
|
+
# Otherwise, returns a chainable object that does not affect the outcome of the query.
|
38
|
+
#
|
39
|
+
# See the sortable_columns method for more information on how this works.
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# @params [Hash] params A hash with two optional keys, column and direction
|
43
|
+
def column_sort(params)
|
44
|
+
# if parameters are present, attempt to run a scope, otherwise add an empty where
|
45
|
+
if params.present? && params[:column].present? && params[:direction].present?
|
46
|
+
# if sortable_column_list is empty, just run the scope
|
47
|
+
# otherwise, check if the parameters match the values in sortable_column_list
|
48
|
+
if sortable_column_list.nil?
|
49
|
+
scope_name = "column_sort_#{params[:column]}_#{params[:direction]}".downcase
|
50
|
+
send(scope_name)
|
51
|
+
else
|
52
|
+
# if sortable_column_list is not empty, check to make sure the column is a member of the list
|
53
|
+
# before continuing
|
54
|
+
if !sortable_column_list.include?(params[:column].to_sym) || params[:direction].nil?
|
55
|
+
where({})
|
56
|
+
else
|
57
|
+
scope_name = "column_sort_#{params[:column]}_#{params[:direction]}".downcase
|
58
|
+
send(scope_name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
else
|
62
|
+
where({})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
# no config for now
|
4
|
+
# require 'column_sort/config'
|
5
|
+
|
6
|
+
module ColumnSort
|
7
|
+
class Railtie < ::Rails::Railtie
|
8
|
+
initializer 'column_sort' do |app|
|
9
|
+
require "column_sort/column_sort_in_model"
|
10
|
+
ActiveRecord::Base.send :include, ColumnSort::ColumnSortInModel
|
11
|
+
|
12
|
+
# note that the helpers are required in both views and controllers
|
13
|
+
# There is a way in rails to make helpers available in controllers but I am
|
14
|
+
# not sure how to use it here. A potentially better way to do this is to convert
|
15
|
+
# the gem to an engine and put it in app/helpers/column_sort/
|
16
|
+
require "column_sort/column_sort_helper"
|
17
|
+
ActionView::Base.send :include, ColumnSort::ColumnSortHelper
|
18
|
+
ActionController::Base.send :include, ColumnSort::ColumnSortHelper
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require File.expand_path('../config/application', __FILE__)
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
2
|
+
|
3
|
+
require "active_model/railtie"
|
4
|
+
require "active_record/railtie"
|
5
|
+
require "action_controller/railtie"
|
6
|
+
require "action_view/railtie"
|
7
|
+
require "action_mailer/railtie"
|
8
|
+
|
9
|
+
Bundler.require
|
10
|
+
require "column_sort"
|
11
|
+
|
12
|
+
module Dummy
|
13
|
+
class Application < Rails::Application
|
14
|
+
# Settings in config/environments/* take precedence over those specified here.
|
15
|
+
# Application configuration should go into files in config/initializers
|
16
|
+
# -- all .rb files in that directory are automatically loaded.
|
17
|
+
|
18
|
+
# Custom directories with classes and modules you want to be autoloadable.
|
19
|
+
# config.autoload_paths += %W(#{config.root}/extras)
|
20
|
+
|
21
|
+
# Only load the plugins named here, in the order given (default is alphabetical).
|
22
|
+
# :all can be used as a placeholder for all plugins not explicitly named.
|
23
|
+
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
24
|
+
|
25
|
+
# Activate observers that should always be running.
|
26
|
+
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
27
|
+
|
28
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
29
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
30
|
+
# config.time_zone = 'Central Time (US & Canada)'
|
31
|
+
|
32
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
33
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
34
|
+
# config.i18n.default_locale = :de
|
35
|
+
|
36
|
+
# JavaScript files you want as :defaults (application.js is always included).
|
37
|
+
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
|
38
|
+
|
39
|
+
# Configure the default encoding used in templates for Ruby 1.9.
|
40
|
+
config.encoding = "utf-8"
|
41
|
+
|
42
|
+
# Configure sensitive parameters which will be filtered from the log file.
|
43
|
+
config.filter_parameters += [:password]
|
44
|
+
end
|
45
|
+
end
|