is_positionable 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/is_positionable.gemspec +56 -0
- data/lib/is_positionable/base.rb +11 -0
- data/lib/is_positionable/errors/no_method_error/acts_as_list.rb +24 -0
- data/lib/is_positionable/interface.rb +117 -0
- data/lib/is_positionable.rb +231 -0
- metadata +76 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Michael van Rooijen | Meskyanichi
|
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,18 @@
|
|
1
|
+
= ip
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but
|
13
|
+
bump version in a commit by itself I can ignore when I pull)
|
14
|
+
* Send me a pull request. Bonus points for topic branches.
|
15
|
+
|
16
|
+
== Copyright
|
17
|
+
|
18
|
+
Copyright (c) 2009 meskyanichi. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "is_positionable"
|
8
|
+
gem.summary = %Q{Handles positioning (ordering) your ActiveRecord Objects.}
|
9
|
+
gem.description = %Q{
|
10
|
+
Handles positioning (ordering) your ActiveRecord Objects.
|
11
|
+
Makes use of the "Acts As List" plugin for the optimized background handling of the positioning.
|
12
|
+
"Is Positionable" is a front-end that dynamically generates buttons for moving ActiveRecord Objects
|
13
|
+
"up", "down", to the "top" and to the "bottom". Setting it up takes just 1 word: "is_positionable".
|
14
|
+
}
|
15
|
+
gem.email = "meskyan@gmail.com"
|
16
|
+
gem.homepage = "http://github.com/meskyanichi/is_positionable"
|
17
|
+
gem.authors = ["meskyanichi"]
|
18
|
+
gem.add_dependency "acts_as_list"
|
19
|
+
# gem.files.include 'lib/**/*'
|
20
|
+
end
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test) do |test|
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.pattern = 'test/**/*_test.rb'
|
29
|
+
test.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rcov/rcovtask'
|
34
|
+
Rcov::RcovTask.new do |test|
|
35
|
+
test.libs << 'test'
|
36
|
+
test.pattern = 'test/**/*_test.rb'
|
37
|
+
test.verbose = true
|
38
|
+
end
|
39
|
+
rescue LoadError
|
40
|
+
task :rcov do
|
41
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
task :test => :check_dependencies
|
46
|
+
|
47
|
+
task :default => :test
|
48
|
+
|
49
|
+
require 'rake/rdoctask'
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
51
|
+
if File.exist?('VERSION')
|
52
|
+
version = File.read('VERSION')
|
53
|
+
else
|
54
|
+
version = ""
|
55
|
+
end
|
56
|
+
|
57
|
+
rdoc.rdoc_dir = 'rdoc'
|
58
|
+
rdoc.title = "ip #{version}"
|
59
|
+
rdoc.rdoc_files.include('README*')
|
60
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
61
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "is_positionable")
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{is_positionable}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["meskyanichi"]
|
12
|
+
s.date = %q{2009-10-05}
|
13
|
+
s.description = %q{
|
14
|
+
Handles positioning (ordering) your ActiveRecord Objects.
|
15
|
+
Makes use of the "Acts As List" plugin for the optimized background handling of the positioning.
|
16
|
+
"Is Positionable" is a front-end that dynamically generates buttons for moving ActiveRecord Objects
|
17
|
+
"up", "down", to the "top" and to the "bottom". Setting it up takes just 1 word: "is_positionable".
|
18
|
+
}
|
19
|
+
s.email = %q{meskyan@gmail.com}
|
20
|
+
s.extra_rdoc_files = [
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc"
|
23
|
+
]
|
24
|
+
s.files = [
|
25
|
+
".document",
|
26
|
+
".gitignore",
|
27
|
+
"LICENSE",
|
28
|
+
"README.rdoc",
|
29
|
+
"Rakefile",
|
30
|
+
"VERSION",
|
31
|
+
"init.rb",
|
32
|
+
"is_positionable.gemspec",
|
33
|
+
"lib/is_positionable.rb",
|
34
|
+
"lib/is_positionable/base.rb",
|
35
|
+
"lib/is_positionable/errors/no_method_error/acts_as_list.rb",
|
36
|
+
"lib/is_positionable/interface.rb"
|
37
|
+
]
|
38
|
+
s.homepage = %q{http://github.com/meskyanichi/is_positionable}
|
39
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
40
|
+
s.require_paths = ["lib"]
|
41
|
+
s.rubygems_version = %q{1.3.5}
|
42
|
+
s.summary = %q{Handles positioning (ordering) your ActiveRecord Objects.}
|
43
|
+
|
44
|
+
if s.respond_to? :specification_version then
|
45
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<acts_as_list>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<acts_as_list>, [">= 0"])
|
52
|
+
end
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<acts_as_list>, [">= 0"])
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module IsPositionable
|
2
|
+
module Errors
|
3
|
+
module NoMethodError
|
4
|
+
class ActsAsList
|
5
|
+
def initialize
|
6
|
+
raise <<-MSG
|
7
|
+
The Acts As List Gem / Plugin has not been installed!
|
8
|
+
|
9
|
+
To install the gem:
|
10
|
+
sudo gem install acts_as_list
|
11
|
+
|
12
|
+
To install the plugin:
|
13
|
+
./script/plugin install git://github.com/rails/acts_as_list.git
|
14
|
+
|
15
|
+
|
16
|
+
Although this is not "required", I do recommend you (if using the GEM version)
|
17
|
+
to add the following line inside of your config/environment.rb file:
|
18
|
+
config.gem "acts_as_list"
|
19
|
+
MSG
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module IsPositionable
|
2
|
+
class Interface < IsPositionable::Base
|
3
|
+
|
4
|
+
def initialize(options, controller_name)
|
5
|
+
super({
|
6
|
+
:column => :position,
|
7
|
+
:controller => options[:controller] || controller_name,
|
8
|
+
:model => options[:controller] || controller_name,
|
9
|
+
:action => :positionable,
|
10
|
+
:scope => nil,
|
11
|
+
:redirect_to => :back,
|
12
|
+
:param => :move,
|
13
|
+
:set_default_scope => true
|
14
|
+
}.update(options))
|
15
|
+
end
|
16
|
+
|
17
|
+
def build
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# Finds a single record by id
|
22
|
+
# It will determine whether to use a plain find
|
23
|
+
# or whether to use a find through an association
|
24
|
+
def find(id)
|
25
|
+
if scope.nil?
|
26
|
+
model.find(id)
|
27
|
+
else
|
28
|
+
scope.send(model_association_name).find(id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Finds the last id of a list of records
|
33
|
+
# It will determine whether to use a plain find
|
34
|
+
# or whether to use a find through an association
|
35
|
+
def find_last_id
|
36
|
+
if scope.nil?
|
37
|
+
model.all.last.id
|
38
|
+
else
|
39
|
+
scope.send(model_association_name).last.id
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the value of the :redirect_to attribute
|
44
|
+
def redirect
|
45
|
+
options[:redirect_to]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the value of the :scope attribute
|
49
|
+
def scope
|
50
|
+
options[:scope]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the model Class which can be invoked using class methods
|
54
|
+
def model
|
55
|
+
Kernel.const_get(options[:model].singularize.camelize)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the controller Class which can be invoked using class methods
|
59
|
+
def controller
|
60
|
+
Kernel.const_get("#{controller_name.camelize.pluralize}Controller")
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the action name of the :action attribute
|
64
|
+
def action_name
|
65
|
+
options[:action]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the model name of the :model attribute
|
69
|
+
# The value will be singularize'd and camelize'd to
|
70
|
+
# return the exact name as it is written inside a Ruby file
|
71
|
+
def model_name
|
72
|
+
options[:model].singularize.camelize
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the model name in the form of an association
|
76
|
+
# This is the model name, pluralize'd and underscore'd
|
77
|
+
def model_association_name
|
78
|
+
options[:model].pluralize.underscore
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the controller name of the :controller attribute
|
82
|
+
def controller_name
|
83
|
+
options[:controller]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the param of the :param attribute
|
87
|
+
def param
|
88
|
+
options[:param]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns the column of the :column attribute
|
92
|
+
def column
|
93
|
+
options[:column]
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns a boolean
|
97
|
+
# Determines whether the :set_default_scope attribute was set
|
98
|
+
def set_default_scope?
|
99
|
+
true if options[:set_default_scope].eql?(true)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Require additional gems
|
103
|
+
# When the "ignore_error" argument is set to "true" (default)
|
104
|
+
# an error will not be raised if the gem cannot be found
|
105
|
+
def require_gem(gem, ignore_error = true)
|
106
|
+
if ignore_error.eql?(true)
|
107
|
+
begin
|
108
|
+
require "#{gem}"
|
109
|
+
rescue MissingSourceFile
|
110
|
+
end
|
111
|
+
else
|
112
|
+
require "#{gem}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'is_positionable/base'
|
2
|
+
require 'is_positionable/interface'
|
3
|
+
require 'is_positionable/errors/no_method_error/acts_as_list'
|
4
|
+
|
5
|
+
module IsPositionable
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
# Is Positionable
|
14
|
+
def is_positionable(options = {})
|
15
|
+
|
16
|
+
# Initialize the interface builer class
|
17
|
+
# Passes in the options hash and the controller_name and builds the methods for it
|
18
|
+
# Interface will convert ugly multi-dot-syntax to a single object.method wrapper
|
19
|
+
interface = IsPositionable::Interface.new(options, controller_name).build
|
20
|
+
|
21
|
+
# ControllerAction
|
22
|
+
|
23
|
+
# Requires the acts_as_list gem
|
24
|
+
# Ignores "MissingSourceFile" error so that a "nice" error message can be
|
25
|
+
# displayed in the browser.
|
26
|
+
interface.require_gem('acts_as_list')
|
27
|
+
|
28
|
+
# Initializes Acts As List on the model
|
29
|
+
# Will set up the column, the same that is used by Is Positionable
|
30
|
+
# The Acts As List Gem will be provided with the same scope as the Is Positionable Gem uses
|
31
|
+
# The default_scope will be set to always sort the items by the specified column (default = :position)
|
32
|
+
interface.model.class_eval do
|
33
|
+
|
34
|
+
# Initializes the Acts As List gem
|
35
|
+
# Sets the :column to the specified column attribute, default => :position
|
36
|
+
# Sets the :scope attribute to the specified attribute, default => '1 = 1' (like Acts As List)
|
37
|
+
# Will display a helpful error when the Acts As List Gem has either not been installed or loaded
|
38
|
+
begin
|
39
|
+
acts_as_list :column => interface.column,
|
40
|
+
:scope => interface.scope || '1 = 1'
|
41
|
+
rescue NoMethodError
|
42
|
+
raise IsPositionable::Errors::NoMethodError::ActsAsList.new
|
43
|
+
end
|
44
|
+
|
45
|
+
# Sets the default scope to order by the specified column
|
46
|
+
default_scope :order => interface.column if interface.set_default_scope?
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
# Defines the action which will be used to move objects around
|
51
|
+
define_method(interface.action_name) do
|
52
|
+
|
53
|
+
# Finds the object that will be re-positioned
|
54
|
+
object = interface.find(params[:id])
|
55
|
+
|
56
|
+
# Move Object Up 1 Position
|
57
|
+
if params[interface.param].eql?('higher')
|
58
|
+
object.move_higher
|
59
|
+
end
|
60
|
+
|
61
|
+
# Move Object Down 1 Position
|
62
|
+
if params[interface.param].eql?('lower')
|
63
|
+
object.move_lower
|
64
|
+
end
|
65
|
+
|
66
|
+
# Move Object To Top Of List
|
67
|
+
if params[interface.param].eql?('to_top')
|
68
|
+
object.move_to_top
|
69
|
+
end
|
70
|
+
|
71
|
+
# Move Object To Bottom Of List
|
72
|
+
if params[interface.param].eql?('to_bottom')
|
73
|
+
object.move_to_bottom
|
74
|
+
end
|
75
|
+
|
76
|
+
# Redirects if this is a simple HTML POST request
|
77
|
+
# Will do nothing if this is an AJAX request
|
78
|
+
respond_to do |format|
|
79
|
+
format.html do
|
80
|
+
|
81
|
+
# If the redirect path has not been set, it will default to :back.
|
82
|
+
# If the default is set, but there is no "Referer", it will by default redirect
|
83
|
+
# the user to the index action of the current controller.
|
84
|
+
# If the :redirect_to attribute was manually set, this will be used.
|
85
|
+
# If the :redirect_to attribute was set to :back, it will not change the default attribute
|
86
|
+
if interface.redirect.eql?(:back)
|
87
|
+
if request.headers["Referer"]
|
88
|
+
redirect_to(interface.redirect)
|
89
|
+
else
|
90
|
+
redirect_to(:action => :index)
|
91
|
+
end
|
92
|
+
else
|
93
|
+
redirect_to(interface.redirect)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# If the positioning action was triggered by a AJAX call
|
98
|
+
# then do nothing. Only optionally render the RJS file if present.
|
99
|
+
format.js do
|
100
|
+
# => Nothing
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end # => define_method(interface.action_name)
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
# HelperMethods
|
108
|
+
|
109
|
+
# Include the ActionView::Helpers inside of ActionController::Base
|
110
|
+
# This will enable html button parsing
|
111
|
+
ActionController::Base.send(:include, ActionView::Helpers)
|
112
|
+
|
113
|
+
# Injects the "UP" button for the view helpers into the controller
|
114
|
+
# This will be available to all views within the specified controller
|
115
|
+
define_method "up_button_for_#{interface.controller_name}" do |object, *options|
|
116
|
+
|
117
|
+
# Set default options and overwrite the existing ones with
|
118
|
+
# possible user input
|
119
|
+
options = {
|
120
|
+
:name => "up",
|
121
|
+
:attribute => :id,
|
122
|
+
:url => {
|
123
|
+
:controller => interface.controller_name,
|
124
|
+
:action => interface.action_name,
|
125
|
+
:id => object,
|
126
|
+
interface.param => "higher" },
|
127
|
+
:html => {
|
128
|
+
:id => "up_button_for_#{interface.controller_name.singularize}_#{object.id}",
|
129
|
+
:class => "up_button_for_#{interface.controller_name}" }
|
130
|
+
}.update(options.empty? ? {} : options.first)
|
131
|
+
|
132
|
+
button_to(options[:name], options[:url], options[:html]) unless object.first?
|
133
|
+
end
|
134
|
+
|
135
|
+
# Injects the "DOWN" button for the view helpers into the controller
|
136
|
+
# This will be available to all views within the specified controller
|
137
|
+
define_method "down_button_for_#{interface.controller_name}" do |object, *options|
|
138
|
+
|
139
|
+
# Set default options and overwrite the existing ones with
|
140
|
+
# possible user input
|
141
|
+
options = {
|
142
|
+
:name => "down",
|
143
|
+
:attribute => :id,
|
144
|
+
:url => {
|
145
|
+
:controller => interface.controller_name,
|
146
|
+
:action => interface.action_name,
|
147
|
+
:id => object,
|
148
|
+
interface.param => "lower" },
|
149
|
+
:html => {
|
150
|
+
:id => "down_button_for_#{interface.controller_name.singularize}_#{object.id}",
|
151
|
+
:class => "down_button_for_#{interface.controller_name}" }
|
152
|
+
}.update(options.empty? ? {} : options.first)
|
153
|
+
|
154
|
+
# Ensures that the last id will only be found once
|
155
|
+
# and not for each object that comes through the loop
|
156
|
+
unless defined?(@ip_last)
|
157
|
+
@ip_last = interface.find_last_id
|
158
|
+
end
|
159
|
+
|
160
|
+
# Ensures that the last "Down" button will not be displayed
|
161
|
+
# since you can't go lower than the lowest position
|
162
|
+
unless @ip_last.eql?(object.id)
|
163
|
+
button_to(options[:name], options[:url], options[:html])
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Injects the "TOP" button for the view helpers into the controller
|
168
|
+
# This will be available to all views within the specified controller
|
169
|
+
define_method "top_button_for_#{interface.controller_name}" do |object, *options|
|
170
|
+
|
171
|
+
# Set default options and overwrite the existing ones with
|
172
|
+
# possible user input
|
173
|
+
options = {
|
174
|
+
:name => "top",
|
175
|
+
:attribute => :id,
|
176
|
+
:url => {
|
177
|
+
:controller => interface.controller_name,
|
178
|
+
:action => interface.action_name,
|
179
|
+
:id => object,
|
180
|
+
interface.param => "to_top" },
|
181
|
+
:html => {
|
182
|
+
:id => "top_button_for_#{interface.controller_name.singularize}_#{object.id}",
|
183
|
+
:class => "top_button_for_#{interface.controller_name}" }
|
184
|
+
}.update(options.empty? ? {} : options.first)
|
185
|
+
|
186
|
+
button_to(options[:name], options[:url], options[:html]) unless object.first?
|
187
|
+
end
|
188
|
+
|
189
|
+
# Injects the "BOTTOM" button for the view helpers into the controller
|
190
|
+
# This will be available to all views within the specified controller
|
191
|
+
define_method "bottom_button_for_#{interface.controller_name}" do |object, *options|
|
192
|
+
|
193
|
+
# Set default options and overwrite the existing ones with
|
194
|
+
# possible user input
|
195
|
+
options = {
|
196
|
+
:name => "bottom",
|
197
|
+
:attribute => :id,
|
198
|
+
:url => {
|
199
|
+
:controller => interface.controller_name,
|
200
|
+
:action => interface.action_name,
|
201
|
+
:id => object,
|
202
|
+
interface.param => "to_bottom" },
|
203
|
+
:html => {
|
204
|
+
:id => "bottom_button_for_#{interface.controller_name.singularize}_#{object.id}",
|
205
|
+
:class => "bottom_button_for_#{interface.controller_name}" }
|
206
|
+
}.update(options.empty? ? {} : options.first)
|
207
|
+
|
208
|
+
# Ensures that the last id will only be found once
|
209
|
+
# and not for each object that comes through the loop
|
210
|
+
unless defined?(@ip_last)
|
211
|
+
@ip_last = interface.find_last_id
|
212
|
+
end
|
213
|
+
|
214
|
+
# Ensures that the last "Down" button will not be displayed
|
215
|
+
# since you can't go lower than the lowest position
|
216
|
+
unless @ip_last.eql?(object.id)
|
217
|
+
button_to(options[:name], options[:url], options[:html])
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# Makes the buttons available to the views that belong to the
|
222
|
+
# controller that Is Positional was invoked from
|
223
|
+
helper_method "up_button_for_#{interface.controller_name}",
|
224
|
+
"down_button_for_#{interface.controller_name}",
|
225
|
+
"top_button_for_#{interface.controller_name}",
|
226
|
+
"bottom_button_for_#{interface.controller_name}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
ActionController::Base.send(:include, IsPositionable)
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: is_positionable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- meskyanichi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-05 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: acts_as_list
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: "\n Handles positioning (ordering) your ActiveRecord Objects.\n Makes use of the \"Acts As List\" plugin for the optimized background handling of the positioning.\n \"Is Positionable\" is a front-end that dynamically generates buttons for moving ActiveRecord Objects\n \"up\", \"down\", to the \"top\" and to the \"bottom\". Setting it up takes just 1 word: \"is_positionable\".\n "
|
26
|
+
email: meskyan@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- init.rb
|
42
|
+
- is_positionable.gemspec
|
43
|
+
- lib/is_positionable.rb
|
44
|
+
- lib/is_positionable/base.rb
|
45
|
+
- lib/is_positionable/errors/no_method_error/acts_as_list.rb
|
46
|
+
- lib/is_positionable/interface.rb
|
47
|
+
has_rdoc: true
|
48
|
+
homepage: http://github.com/meskyanichi/is_positionable
|
49
|
+
licenses: []
|
50
|
+
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --charset=UTF-8
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.5
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Handles positioning (ordering) your ActiveRecord Objects.
|
75
|
+
test_files: []
|
76
|
+
|