sortable_nested_set 0.2.3 → 0.3.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/README.rdoc +30 -18
- data/VERSION +1 -1
- data/app/controllers/sortable_nested_set_controller.rb +35 -0
- data/app/helpers/sortable_nested_set_helper.rb +3 -6
- data/app/views/sortable_nested_set/_category.html.erb +4 -10
- data/app/views/sortable_nested_set/_item.html.erb +2 -6
- data/app/views/sortable_nested_set/_tree.html.erb +6 -8
- data/config/routes.rb +3 -0
- data/lib/{sortable_nested_set/acts_as_sortable_nested_set.rb → acts_as_sortable_nested_set.rb} +17 -8
- data/lib/sortable_nested_set.rb +12 -4
- data/public/javascripts/sortable_nested_set.js +40 -40
- data/public/stylesheets/sortable_nested_set.css +7 -7
- data/sortable_nested_set.gemspec +5 -8
- data/test/helper.rb +0 -1
- metadata +7 -10
- data/app/views/sortable_nested_set/sns_destroy_category.js.erb +0 -1
- data/app/views/sortable_nested_set/sns_destroy_item.js.erb +0 -1
- data/lib/sortable_nested_set/engine.rb +0 -7
- data/lib/sortable_nested_set/handles_sortable_nested_set.rb +0 -74
- data/lib/sortable_nested_set/routes.rb +0 -27
data/README.rdoc
CHANGED
@@ -1,32 +1,44 @@
|
|
1
|
-
|
1
|
+
= Sortable Nested Set
|
2
2
|
|
3
|
-
|
4
|
-
gem 'sortable_nested_set'
|
3
|
+
== Requirements
|
5
4
|
|
6
|
-
|
7
|
-
acts_as_sortable_nested_set_of :items
|
8
|
-
where :items is the pluralized Item model (e.g. "File").
|
5
|
+
jQuery is required.
|
9
6
|
|
10
|
-
|
11
|
-
handles_sortable_nested_set
|
12
|
-
to include menu actions.
|
7
|
+
== Usage
|
13
8
|
|
14
|
-
|
15
|
-
sortable_nested_set_for :categories
|
16
|
-
for each pluralized "Category" model.
|
9
|
+
Add the gem to your Gemfile.
|
17
10
|
|
18
|
-
|
19
|
-
|
11
|
+
gem 'sortable_nested_set'
|
12
|
+
|
13
|
+
In each "Category" (e.g. "Directory") migration:
|
20
14
|
lft:integer
|
21
15
|
rgt:integer
|
16
|
+
depth:integer [optional]
|
22
17
|
|
23
|
-
In
|
24
|
-
|
18
|
+
In the routing configuration file:
|
19
|
+
nest the "Category" and "Item" resources
|
20
|
+
|
21
|
+
In each "Category" model:
|
22
|
+
acts_as_sortable_nested_set_of :items
|
23
|
+
where :items is the pluralized, underscored "Item" model (e.g. "ImageFile"=>:image_files).
|
24
|
+
|
25
|
+
In the "Category" and "Item" controllers:
|
26
|
+
[new] use param[:category_id]
|
27
|
+
[destroy] respond_to format.js (and provide associated view)
|
28
|
+
|
29
|
+
In the "Category" and "Items" models:
|
30
|
+
provide #to_s.
|
25
31
|
|
26
32
|
In the <head> section of the layout(s) where the trees will be displayed:
|
27
33
|
yield(:head)
|
34
|
+
after jQuery is loaded.
|
35
|
+
|
36
|
+
== Support for acts_as_list
|
37
|
+
|
38
|
+
When an "Item" model acts_as_list, SortableNestedSet will use its position for sorting.
|
39
|
+
|
40
|
+
== Helpers
|
28
41
|
|
29
|
-
Helpers:
|
30
42
|
sns_options
|
31
43
|
sns_lineage
|
32
|
-
|
44
|
+
sns_tree
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class SortableNestedSetController < ActionController::Base
|
2
|
+
def sns_sort
|
3
|
+
category_class = params[:category_class].classify.constantize
|
4
|
+
|
5
|
+
matches = params[:moved].match(/(\w+)_(\d+)$/)
|
6
|
+
moved_type = matches[1]
|
7
|
+
moved_id = matches[2].to_i
|
8
|
+
moved_parent = nil
|
9
|
+
tree = {} # category_id => [children of move_type]
|
10
|
+
|
11
|
+
for node in params[:tree].scan(/(\w+)\[(\d+)\]=(\w+)/)
|
12
|
+
type = node[0]
|
13
|
+
next unless type == moved_type
|
14
|
+
|
15
|
+
id = node[1].to_i
|
16
|
+
parent = (node[2] == 'root') ? nil : node[2].to_i
|
17
|
+
|
18
|
+
moved_parent = parent if id == moved_id
|
19
|
+
|
20
|
+
tree[parent] ||= []
|
21
|
+
tree[parent] << id
|
22
|
+
end
|
23
|
+
|
24
|
+
if moved_type == category_class.sns_items_type.to_s.singularize
|
25
|
+
item = category_class.sns_items_type.to_s.classify.constantize.find(moved_id)
|
26
|
+
item.remove_from_list if item.respond_to?(:remove_from_list) # acts_as_list support
|
27
|
+
item.update_attribute(category_class.name.foreign_key, moved_parent)
|
28
|
+
item.insert_at(tree[moved_parent].index(moved_id)) if item.respond_to?(:insert_at) # acts_as_list support
|
29
|
+
else
|
30
|
+
moved_type.classify.constantize.find(moved_id).move(moved_parent, tree[moved_parent])
|
31
|
+
end
|
32
|
+
|
33
|
+
render :nothing => true
|
34
|
+
end
|
35
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module SortableNestedSetHelper
|
2
|
-
def
|
2
|
+
def sns_tree(class_or_category)
|
3
3
|
if class_or_category.is_a?(Class)
|
4
4
|
@category_class = class_or_category
|
5
5
|
@categories = @category_class.includes(@category_class.sns_items_type)
|
@@ -8,8 +8,7 @@ module SortableNestedSetHelper
|
|
8
8
|
@categories = class_or_category.self_and_descendants.includes(@category_class.sns_items_type)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
render 'sortable_nested_set/tree', :categories => @categories.arrange, :sns_sort_path => sns_sort_path
|
11
|
+
render 'sortable_nested_set/tree', :category_class => @category_class, :categories => @categories.arrange
|
13
12
|
end
|
14
13
|
|
15
14
|
def sns_lineage(category, options={})
|
@@ -27,8 +26,6 @@ module SortableNestedSetHelper
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def sns_options(category_class, mover=nil)
|
30
|
-
sorted_nested_set_options(category_class, lambda(&:left_column_name), mover)
|
31
|
-
'.' * level + category.name
|
32
|
-
end
|
29
|
+
sorted_nested_set_options(category_class, lambda(&:left_column_name), mover) { |cat, lvl| "#{'.'*lvl}#{cat}" }
|
33
30
|
end
|
34
31
|
end
|
@@ -1,20 +1,14 @@
|
|
1
|
-
<% cpath = category.class.name.underscore + '_path' %>
|
2
|
-
|
3
1
|
<div>
|
4
2
|
<span class="toggle open"></span>
|
5
3
|
<span class="handle"><%= category %></span>
|
6
4
|
<%= link_to image_tag('mega_menu.png'), category, :class => :mega_menu %>
|
7
5
|
<div class="mega_menu_links">
|
8
6
|
<%= link_to_unless_current 'show', category %> |
|
9
|
-
<%= link_to 'edit',
|
10
|
-
<%= link_to 'remove',
|
11
|
-
send("sns_destroy_category_#{cpath}", category),
|
12
|
-
:confirm => 'Are you sure?',
|
13
|
-
:method => :delete,
|
14
|
-
:remote => !current_page?(send(cpath, category)) %> |
|
7
|
+
<%= link_to 'edit', polymorphic_path(category, :action => :edit) %> |
|
8
|
+
<%= link_to 'remove', category, :confirm => 'Are you sure?', :method => :delete, :remote => !current_page?(category) %> |
|
15
9
|
<%= link_to "add #{category.class.sns_subcategories_type.to_s.singularize}",
|
16
|
-
|
10
|
+
polymorphic_path([category, category.class], :action => :new) %> |
|
17
11
|
<%= link_to "add #{category.class.sns_items_type.to_s.singularize}",
|
18
|
-
|
12
|
+
polymorphic_path([category, category.class.sns_items_class], :action => :new) %>
|
19
13
|
</div>
|
20
14
|
</div>
|
@@ -4,12 +4,8 @@
|
|
4
4
|
<%= link_to image_tag('mega_menu.png'), item, :class => :mega_menu %>
|
5
5
|
<div class="mega_menu_links">
|
6
6
|
<%= link_to 'show', item %> |
|
7
|
-
<%= link_to 'edit',
|
8
|
-
<%= link_to 'remove',
|
9
|
-
send("sns_destroy_item_#{item.class.name.underscore}_path", item),
|
10
|
-
:confirm => 'Are you sure?',
|
11
|
-
:method => :delete,
|
12
|
-
:remote => true %>
|
7
|
+
<%= link_to 'edit', polymorphic_path(item, :action => :edit) %> |
|
8
|
+
<%= link_to 'remove', item, :confirm => 'Are you sure?', :method => :delete, :remote => true %>
|
13
9
|
</div>
|
14
10
|
</div>
|
15
11
|
</li>
|
@@ -5,14 +5,12 @@
|
|
5
5
|
'sortable_nested_set' %>
|
6
6
|
<% end %>
|
7
7
|
|
8
|
-
<%= render_tree categories, :id => :sns_categories,
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
</ul>
|
15
|
-
|
8
|
+
<%= render_tree categories, :id => :sns_categories,
|
9
|
+
:class => :sortable,
|
10
|
+
'data-url' => sns_sort_path(:category_class => @category_class) do |category, child| %>
|
11
|
+
<li id="<%= category.class.name.underscore %>_<%= category.id %>" class="sns_category">
|
12
|
+
<%= render :partial => 'sortable_nested_set/category', :object => category %>
|
13
|
+
<ul><%= render :partial => 'sortable_nested_set/item', :collection => category.sns_items %></ul>
|
16
14
|
<%= child %>
|
17
15
|
</li>
|
18
16
|
<% end %>
|
data/config/routes.rb
ADDED
data/lib/{sortable_nested_set/acts_as_sortable_nested_set.rb → acts_as_sortable_nested_set.rb}
RENAMED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'nested_set'
|
2
|
-
include CollectiveIdea::Acts::NestedSet
|
3
2
|
|
4
3
|
module SortableNestedSet
|
5
4
|
def self.included(base)
|
@@ -11,10 +10,12 @@ module SortableNestedSet
|
|
11
10
|
def acts_as_sortable_nested_set_of(items_type)
|
12
11
|
@subcategories_type = "sub#{name.tableize}".to_sym
|
13
12
|
@items_type = items_type
|
13
|
+
@foreign_key = self.class.method_defined?(:parent) ? :parent_id : name.foreign_key
|
14
14
|
|
15
15
|
instance_eval do
|
16
16
|
def sns_subcategories_type ; @subcategories_type end
|
17
17
|
def sns_items_type ; @items_type end
|
18
|
+
def sns_items_class ; @items_type.to_s.singularize.classify.constantize end
|
18
19
|
end
|
19
20
|
|
20
21
|
class_eval do
|
@@ -22,16 +23,22 @@ module SortableNestedSet
|
|
22
23
|
define_method(:sns_items) { send(self.class.sns_items_type) }
|
23
24
|
end
|
24
25
|
|
25
|
-
acts_as_nested_set :parent_column =>
|
26
|
+
acts_as_nested_set :parent_column => @foreign_key
|
26
27
|
|
27
|
-
|
28
|
+
has_many @subcategories_type, :class_name => name, :foreign_key => @foreign_key, :dependent => :destroy
|
29
|
+
has_many @items_type,
|
30
|
+
:order => (sns_items_class.position_column if sns_items_class.method_defined?(:position_column)),
|
31
|
+
:dependent => :destroy
|
28
32
|
|
29
|
-
|
30
|
-
has_many @items_type, :order => :position, :dependent => :destroy
|
33
|
+
after_initialize :default_depth_to_zero
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
34
37
|
module InstanceMethods
|
38
|
+
def indented_name(indentation_character='.')
|
39
|
+
indentation_character * depth + name
|
40
|
+
end
|
41
|
+
|
35
42
|
def move(parent, children)
|
36
43
|
if children.size == 1
|
37
44
|
move_to_child_of(parent)
|
@@ -39,7 +46,7 @@ module SortableNestedSet
|
|
39
46
|
prev_sibling = nil
|
40
47
|
|
41
48
|
for i in 0...children.size
|
42
|
-
if children[i] == id
|
49
|
+
if children[i] == self.id
|
43
50
|
prev_sibling ? move_to_right_of(prev_sibling) : move_to_left_of(children[i+1])
|
44
51
|
break
|
45
52
|
end
|
@@ -49,8 +56,10 @@ module SortableNestedSet
|
|
49
56
|
end
|
50
57
|
end
|
51
58
|
|
52
|
-
|
53
|
-
|
59
|
+
private
|
60
|
+
|
61
|
+
def default_depth_to_zero
|
62
|
+
self.depth ||= 0 if has_attribute?(:depth)
|
54
63
|
end
|
55
64
|
end
|
56
65
|
end
|
data/lib/sortable_nested_set.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require '
|
1
|
+
module SortableNestedSet
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
initializer 'nested_fields.add_middleware' do |app|
|
4
|
+
require 'acts_as_sortable_nested_set'
|
5
|
+
app.middleware.use ActionDispatch::Static, "#{root}/public"
|
6
|
+
end
|
7
|
+
|
8
|
+
config.to_prepare do
|
9
|
+
ApplicationController.helper(SortableNestedSetHelper)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,38 +1,44 @@
|
|
1
|
-
$(
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
$(this).
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
1
|
+
$('#sns_categories span.toggle').live('click', function() {
|
2
|
+
$(this).toggleClass('open');
|
3
|
+
$(this).toggleClass('closed');
|
4
|
+
$(this).closest('li').find('> ul').toggle();
|
5
|
+
});
|
6
|
+
|
7
|
+
function linkHover() {
|
8
|
+
$(this).next().addClass('link_hover');
|
9
|
+
}
|
10
|
+
|
11
|
+
function linkUnhover() {
|
12
|
+
if (!$(this).next().hasClass('pop_up_hover'))
|
13
|
+
$(this).next().removeClass('link_hover');
|
14
|
+
}
|
15
|
+
|
16
|
+
function popUpHover() {
|
17
|
+
$(this).removeClass('link_hover');
|
18
|
+
$(this).addClass('pop_up_hover');
|
19
|
+
}
|
20
|
+
|
21
|
+
function popUpUnhover() {
|
22
|
+
$(this).removeClass('pop_up_hover');
|
23
|
+
}
|
24
|
+
|
25
|
+
var linkConfig = {
|
26
|
+
interval: 200,
|
27
|
+
out: linkUnhover,
|
28
|
+
over: linkHover,
|
29
|
+
sensitivity: 4,
|
30
|
+
timeout: 250
|
31
|
+
};
|
32
|
+
|
33
|
+
var popUpConfig = {
|
34
|
+
interval: 0,
|
35
|
+
out: popUpUnhover,
|
36
|
+
over: popUpHover,
|
37
|
+
sensitivity: 4,
|
38
|
+
timeout: 250
|
39
|
+
};
|
35
40
|
|
41
|
+
$(document).ready(function() {
|
36
42
|
$('.mega_menu').hoverIntent(linkConfig);
|
37
43
|
$('.mega_menu_links').hoverIntent(popUpConfig);
|
38
44
|
|
@@ -54,10 +60,4 @@ $(document).ready(function() {
|
|
54
60
|
});
|
55
61
|
}
|
56
62
|
});
|
57
|
-
|
58
|
-
$('#sns_categories .toggle').click(function() {
|
59
|
-
$(this).toggleClass('open');
|
60
|
-
$(this).toggleClass('closed');
|
61
|
-
$(this).closest('li').find('> ul').toggle();
|
62
|
-
});
|
63
63
|
});
|
@@ -1,3 +1,8 @@
|
|
1
|
+
.toggle {
|
2
|
+
cursor: pointer;
|
3
|
+
padding-right: 1em;
|
4
|
+
}
|
5
|
+
|
1
6
|
.mega_menu_links {
|
2
7
|
background: #ffc;
|
3
8
|
border: 1px solid #eea;
|
@@ -12,8 +17,8 @@
|
|
12
17
|
}
|
13
18
|
|
14
19
|
.pop_up_hover {
|
15
|
-
display: block;
|
16
20
|
border: 1px solid #cca;
|
21
|
+
display: block;
|
17
22
|
}
|
18
23
|
|
19
24
|
#sns_categories, #sns_categories ul {
|
@@ -23,7 +28,7 @@
|
|
23
28
|
}
|
24
29
|
|
25
30
|
#sns_categories {
|
26
|
-
margin: 0;
|
31
|
+
margin: 0 0 10px 0;
|
27
32
|
}
|
28
33
|
|
29
34
|
#sns_categories li {
|
@@ -47,11 +52,6 @@
|
|
47
52
|
color: #8a1f11;
|
48
53
|
}
|
49
54
|
|
50
|
-
.toggle {
|
51
|
-
cursor: pointer;
|
52
|
-
padding-right: 1em;
|
53
|
-
}
|
54
|
-
|
55
55
|
#sns_categories span.open {
|
56
56
|
background: url(/images/folder_open.png) no-repeat center;
|
57
57
|
}
|
data/sortable_nested_set.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sortable_nested_set}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jason Murad"]
|
12
|
-
s.date = %q{2011-01-
|
12
|
+
s.date = %q{2011-01-25}
|
13
13
|
s.description = %q{reusable menu for navigation and modification or hierarchical categories}
|
14
14
|
s.email = %q{jason@thriess.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -22,17 +22,14 @@ Gem::Specification.new do |s|
|
|
22
22
|
"README.rdoc",
|
23
23
|
"Rakefile",
|
24
24
|
"VERSION",
|
25
|
+
"app/controllers/sortable_nested_set_controller.rb",
|
25
26
|
"app/helpers/sortable_nested_set_helper.rb",
|
26
27
|
"app/views/sortable_nested_set/_category.html.erb",
|
27
28
|
"app/views/sortable_nested_set/_item.html.erb",
|
28
29
|
"app/views/sortable_nested_set/_tree.html.erb",
|
29
|
-
"
|
30
|
-
"
|
30
|
+
"config/routes.rb",
|
31
|
+
"lib/acts_as_sortable_nested_set.rb",
|
31
32
|
"lib/sortable_nested_set.rb",
|
32
|
-
"lib/sortable_nested_set/acts_as_sortable_nested_set.rb",
|
33
|
-
"lib/sortable_nested_set/engine.rb",
|
34
|
-
"lib/sortable_nested_set/handles_sortable_nested_set.rb",
|
35
|
-
"lib/sortable_nested_set/routes.rb",
|
36
33
|
"public/images/folder_closed.png",
|
37
34
|
"public/images/folder_open.png",
|
38
35
|
"public/images/mega_menu.png",
|
data/test/helper.rb
CHANGED
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 2
|
8
7
|
- 3
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jason Murad
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-25 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -101,17 +101,14 @@ files:
|
|
101
101
|
- README.rdoc
|
102
102
|
- Rakefile
|
103
103
|
- VERSION
|
104
|
+
- app/controllers/sortable_nested_set_controller.rb
|
104
105
|
- app/helpers/sortable_nested_set_helper.rb
|
105
106
|
- app/views/sortable_nested_set/_category.html.erb
|
106
107
|
- app/views/sortable_nested_set/_item.html.erb
|
107
108
|
- app/views/sortable_nested_set/_tree.html.erb
|
108
|
-
-
|
109
|
-
-
|
109
|
+
- config/routes.rb
|
110
|
+
- lib/acts_as_sortable_nested_set.rb
|
110
111
|
- lib/sortable_nested_set.rb
|
111
|
-
- lib/sortable_nested_set/acts_as_sortable_nested_set.rb
|
112
|
-
- lib/sortable_nested_set/engine.rb
|
113
|
-
- lib/sortable_nested_set/handles_sortable_nested_set.rb
|
114
|
-
- lib/sortable_nested_set/routes.rb
|
115
112
|
- public/images/folder_closed.png
|
116
113
|
- public/images/folder_open.png
|
117
114
|
- public/images/mega_menu.png
|
@@ -136,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
133
|
requirements:
|
137
134
|
- - ">="
|
138
135
|
- !ruby/object:Gem::Version
|
139
|
-
hash:
|
136
|
+
hash: 3123587155221195723
|
140
137
|
segments:
|
141
138
|
- 0
|
142
139
|
version: "0"
|
@@ -1 +0,0 @@
|
|
1
|
-
$('#category_<%= @category.id %>').remove();
|
@@ -1 +0,0 @@
|
|
1
|
-
$('#item_<%= @item.id %>').remove();
|
@@ -1,74 +0,0 @@
|
|
1
|
-
module SortableNestedSet
|
2
|
-
def self.included(base)
|
3
|
-
base.extend ClassMethods
|
4
|
-
end
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def handles_sortable_nested_set
|
8
|
-
class_eval do
|
9
|
-
define_method(:sns_category_id_field) { "#{controller_name.singularize}_id" }
|
10
|
-
define_method(:sns_category_class) { controller_name.classify.constantize }
|
11
|
-
define_method(:sns_items_type) { sns_category_class.sns_items_type }
|
12
|
-
define_method(:sns_item_class) { sns_items_type.to_s.classify.constantize }
|
13
|
-
end
|
14
|
-
|
15
|
-
include InstanceMethods
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
module InstanceMethods
|
20
|
-
def sns_add_subcategory
|
21
|
-
redirect_to :action => :new, sns_category_id_field => params[:id]
|
22
|
-
end
|
23
|
-
|
24
|
-
def sns_add_item
|
25
|
-
redirect_to :controller => sns_items_type, :action => :new, sns_category_id_field => params[:id]
|
26
|
-
end
|
27
|
-
|
28
|
-
def sns_sort
|
29
|
-
matches = params[:moved].match(/(\w+)_(\d+)$/)
|
30
|
-
moved_type = matches[1]
|
31
|
-
moved_id = matches[2].to_i
|
32
|
-
moved_parent = nil
|
33
|
-
tree = {} # category_id => [children of move_type]
|
34
|
-
|
35
|
-
for node in params[:tree].scan(/(\w+)\[(\d+)\]=(\w+)/)
|
36
|
-
type = node[0]
|
37
|
-
next unless type == moved_type
|
38
|
-
|
39
|
-
id = node[1].to_i
|
40
|
-
parent = (node[2] == 'root') ? nil : node[2].to_i
|
41
|
-
|
42
|
-
moved_parent = parent if id == moved_id
|
43
|
-
|
44
|
-
tree[parent] ||= []
|
45
|
-
tree[parent] << id
|
46
|
-
end
|
47
|
-
|
48
|
-
if moved_type == sns_items_type.to_s.singularize
|
49
|
-
item = sns_item_class.find(moved_id)
|
50
|
-
item.remove_from_list
|
51
|
-
item.update_attribute(sns_category_id_field, moved_parent)
|
52
|
-
item.insert_at(tree[moved_parent].index(moved_id))
|
53
|
-
else
|
54
|
-
moved_type.classify.constantize.find(moved_id).move(moved_parent, tree[moved_parent])
|
55
|
-
end
|
56
|
-
|
57
|
-
render :nothing => true
|
58
|
-
end
|
59
|
-
|
60
|
-
def sns_destroy_category
|
61
|
-
@category = sns_category_class.find(params[:id])
|
62
|
-
@category.destroy
|
63
|
-
render 'sortable_nested_set/sns_destroy_category'
|
64
|
-
end
|
65
|
-
|
66
|
-
def sns_destroy_item
|
67
|
-
@item = sns_item_class.find(params[:id])
|
68
|
-
@item.destroy
|
69
|
-
render 'sortable_nested_set/sns_destroy_item'
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
ActionController::Base.send :include, SortableNestedSet
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module ActionDispatch::Routing
|
2
|
-
class Mapper
|
3
|
-
def sortable_nested_set_for(category_type)
|
4
|
-
item_type = category_type.to_s.classify.constantize.sns_items_type
|
5
|
-
|
6
|
-
resources category_type do
|
7
|
-
resources category_type, :as => "sub#{category_type}"
|
8
|
-
resources item_type
|
9
|
-
|
10
|
-
member do
|
11
|
-
get :sns_toggle
|
12
|
-
get :sns_add_subcategory
|
13
|
-
get :sns_add_item
|
14
|
-
delete :sns_destroy_category
|
15
|
-
end
|
16
|
-
|
17
|
-
collection do
|
18
|
-
put :sns_sort
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
resources item_type do
|
23
|
-
delete :sns_destroy_item, :on => :member, :controller => category_type
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|