sortable_nested_set 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +5 -5
- data/README.rdoc +27 -14
- data/VERSION +1 -1
- data/app/helpers/sortable_nested_set_helper.rb +7 -12
- data/app/views/sortable_nested_set/_category.html.erb +8 -6
- data/app/views/sortable_nested_set/_item.html.erb +2 -2
- data/app/views/sortable_nested_set/_tree.html.erb +12 -17
- data/lib/sortable_nested_set/acts_as_sortable_nested_set.rb +4 -7
- data/public/javascripts/jquery.ui.nestedSortable.js +2 -2
- data/public/javascripts/sortable_nested_set.js +55 -59
- data/public/stylesheets/sortable_nested_set.css +6 -21
- data/sortable_nested_set.gemspec +2 -4
- metadata +4 -6
- data/README +0 -29
data/Gemfile.lock
CHANGED
@@ -22,23 +22,23 @@ GEM
|
|
22
22
|
arel (~> 2.0.2)
|
23
23
|
tzinfo (~> 0.3.23)
|
24
24
|
activesupport (3.0.3)
|
25
|
-
arel (2.0.
|
25
|
+
arel (2.0.7)
|
26
26
|
builder (2.1.2)
|
27
27
|
erubis (2.6.6)
|
28
28
|
abstract (>= 1.0.0)
|
29
29
|
git (1.2.5)
|
30
30
|
i18n (0.5.0)
|
31
|
-
jeweler (1.5.
|
31
|
+
jeweler (1.5.2)
|
32
32
|
bundler (~> 1.0.0)
|
33
33
|
git (>= 1.2.5)
|
34
34
|
rake
|
35
|
-
nested_set (1.6.
|
35
|
+
nested_set (1.6.3)
|
36
36
|
activerecord (>= 3.0.0)
|
37
37
|
railties (>= 3.0.0)
|
38
38
|
rack (1.2.1)
|
39
39
|
rack-mount (0.6.13)
|
40
40
|
rack (>= 1.0.0)
|
41
|
-
rack-test (0.5.
|
41
|
+
rack-test (0.5.7)
|
42
42
|
rack (>= 1.0)
|
43
43
|
railties (3.0.3)
|
44
44
|
actionpack (= 3.0.3)
|
@@ -49,7 +49,7 @@ GEM
|
|
49
49
|
rcov (0.9.9)
|
50
50
|
shoulda (2.11.3)
|
51
51
|
thor (0.14.6)
|
52
|
-
tzinfo (0.3.
|
52
|
+
tzinfo (0.3.24)
|
53
53
|
|
54
54
|
PLATFORMS
|
55
55
|
ruby
|
data/README.rdoc
CHANGED
@@ -1,19 +1,32 @@
|
|
1
|
-
|
1
|
+
jQuery is required.
|
2
2
|
|
3
|
-
|
3
|
+
In the Gemfile
|
4
|
+
gem 'sortable_nested_set'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
-
* Fork the project
|
10
|
-
* Start a feature/bugfix branch
|
11
|
-
* Commit and push until you are happy with your contribution
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* 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.
|
6
|
+
In each "Category" model (e.g. "Directory"):
|
7
|
+
acts_as_sortable_nested_set_of :items
|
8
|
+
where :items is the pluralized Item model (e.g. "File").
|
14
9
|
|
15
|
-
|
10
|
+
In each "Category" controller:
|
11
|
+
handles_sortable_nested_set
|
12
|
+
to include menu actions.
|
16
13
|
|
17
|
-
|
18
|
-
|
14
|
+
In the routes config file:
|
15
|
+
sortable_nested_set_for :categories
|
16
|
+
for each pluralized "Category" model.
|
19
17
|
|
18
|
+
In each "Category" migration:
|
19
|
+
name:string
|
20
|
+
lft:integer
|
21
|
+
rgt:integer
|
22
|
+
|
23
|
+
In each "Item" migration:
|
24
|
+
position:integer
|
25
|
+
|
26
|
+
In the <head> section of the layout(s) where the trees will be displayed:
|
27
|
+
yield(:head)
|
28
|
+
|
29
|
+
Helpers:
|
30
|
+
sns_options
|
31
|
+
sns_lineage
|
32
|
+
sortable_nested_set_tree
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
@@ -2,13 +2,14 @@ module SortableNestedSetHelper
|
|
2
2
|
def sortable_nested_set_tree(class_or_category)
|
3
3
|
if class_or_category.is_a?(Class)
|
4
4
|
@category_class = class_or_category
|
5
|
-
@categories =
|
5
|
+
@categories = @category_class.includes(@category_class.sns_items_type)
|
6
6
|
else
|
7
7
|
@category_class = class_or_category.class
|
8
|
-
@categories = class_or_category.self_and_descendants.
|
8
|
+
@categories = class_or_category.self_and_descendants.includes(@category_class.sns_items_type)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
sns_sort_path = "sns_sort_#{@category_class.name.underscore.pluralize}_path"
|
12
|
+
render 'sortable_nested_set/tree', :categories => @categories.arrange, :sns_sort_path => sns_sort_path
|
12
13
|
end
|
13
14
|
|
14
15
|
def sns_lineage(category, options={})
|
@@ -19,21 +20,15 @@ module SortableNestedSetHelper
|
|
19
20
|
ancestors = category.send(options[:include_self] ? :self_and_ancestors : :ancestors)
|
20
21
|
|
21
22
|
links = ancestors.select([:id, :name]).collect do |c|
|
22
|
-
link_to
|
23
|
+
link_to c.name, c, :class => :lineage
|
23
24
|
end
|
24
25
|
|
25
26
|
content_tag :p, links.join.html_safe unless links.empty?
|
26
27
|
end
|
27
28
|
|
28
29
|
def sns_options(category_class, mover=nil)
|
29
|
-
|
30
|
-
|
31
|
-
category_class.each_with_level(category_class.for_indented_list) do |category, level|
|
32
|
-
if mover.nil? || mover.new_record? || mover.move_possible?(category)
|
33
|
-
options << ['.' * level + category.name, category.id]
|
34
|
-
end
|
30
|
+
sorted_nested_set_options(category_class, lambda(&:left_column_name), mover) do |category, level|
|
31
|
+
'.' * level + category.name
|
35
32
|
end
|
36
|
-
|
37
|
-
options
|
38
33
|
end
|
39
34
|
end
|
@@ -1,18 +1,20 @@
|
|
1
|
+
<% cpath = category.class.name.underscore + '_path' %>
|
2
|
+
|
1
3
|
<div>
|
2
4
|
<span class="toggle open"></span>
|
3
5
|
<span class="handle"><%= category %></span>
|
4
|
-
|
6
|
+
<%= link_to image_tag('mega_menu.png'), category, :class => :mega_menu %>
|
5
7
|
<div class="mega_menu_links">
|
6
8
|
<%= link_to_unless_current 'show', category %> |
|
7
|
-
<%= link_to 'edit', send("edit_#{
|
9
|
+
<%= link_to 'edit', send("edit_#{cpath}", category) %> |
|
8
10
|
<%= link_to 'remove',
|
9
|
-
send("sns_destroy_category_#{
|
11
|
+
send("sns_destroy_category_#{cpath}", category),
|
10
12
|
:confirm => 'Are you sure?',
|
11
13
|
:method => :delete,
|
12
|
-
:remote => !current_page?(send(
|
14
|
+
:remote => !current_page?(send(cpath, category)) %> |
|
13
15
|
<%= link_to "add #{category.class.sns_subcategories_type.to_s.singularize}",
|
14
|
-
send("sns_add_subcategory_#{
|
16
|
+
send("sns_add_subcategory_#{cpath}", category) %> |
|
15
17
|
<%= link_to "add #{category.class.sns_items_type.to_s.singularize}",
|
16
|
-
send("sns_add_item_#{
|
18
|
+
send("sns_add_item_#{cpath}", category) %>
|
17
19
|
</div>
|
18
20
|
</div>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
<li id="<%= "#{item.class.name.underscore}_#{item.id}" %>" class="
|
1
|
+
<li id="<%= "#{item.class.name.underscore}_#{item.id}" %>" class="sns_item">
|
2
2
|
<div>
|
3
3
|
<div class="handle"><%= item %></div>
|
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
7
|
<%= link_to 'edit', send("edit_#{item.class.name.underscore}_path", item) %> |
|
@@ -1,23 +1,18 @@
|
|
1
1
|
<% content_for :head do %>
|
2
2
|
<%= stylesheet_link_tag 'sortable_nested_set' %>
|
3
|
-
<%= javascript_include_tag '
|
3
|
+
<%= javascript_include_tag 'jquery.hoverIntent.minified.js',
|
4
|
+
'jquery.ui.nestedSortable.js',
|
5
|
+
'sortable_nested_set' %>
|
4
6
|
<% end %>
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
<%= render_tree categories, :id => :sns_categories, :class => :sortable, 'data-url' => send(sns_sort_path) do |node, child| %>
|
9
|
+
<li id="<%= node.class.name.underscore %>_<%= node.id %>" class="sns_category">
|
10
|
+
<%= render :partial => 'sortable_nested_set/category', :object => node %>
|
8
11
|
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
<%=raw '</ol>' * (prev_level - level) if level < prev_level %>
|
12
|
+
<ul>
|
13
|
+
<%= render :partial => 'sortable_nested_set/item', :collection => node.sns_items %>
|
14
|
+
</ul>
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
<%= render :partial => 'sortable_nested_set/item', :collection => category.sns_items %>
|
18
|
-
|
19
|
-
<% prev_level = level %>
|
20
|
-
<% end %>
|
21
|
-
|
22
|
-
<%=raw '</ol></li>' * (prev_level + 1) if prev_level > -1 %>
|
23
|
-
</ol>
|
16
|
+
<%= child %>
|
17
|
+
</li>
|
18
|
+
<% end %>
|
@@ -24,17 +24,10 @@ module SortableNestedSet
|
|
24
24
|
|
25
25
|
acts_as_nested_set :parent_column => name.foreign_key
|
26
26
|
|
27
|
-
attr_accessible parent_column_name
|
28
|
-
|
29
27
|
belongs_to name.underscore.to_sym
|
30
28
|
|
31
29
|
has_many @subcategories_type, :class_name => name, :dependent => :destroy
|
32
30
|
has_many @items_type, :order => :position, :dependent => :destroy
|
33
|
-
|
34
|
-
scope :for_indented_list,
|
35
|
-
:select => [parent_column_name, :id, :name, left_column_name, right_column_name],
|
36
|
-
:order => left_column_name
|
37
|
-
scope :for_indented_list_with_items, lambda { self.for_indented_list.includes(sns_items_type) }
|
38
31
|
end
|
39
32
|
end
|
40
33
|
|
@@ -55,6 +48,10 @@ module SortableNestedSet
|
|
55
48
|
end
|
56
49
|
end
|
57
50
|
end
|
51
|
+
|
52
|
+
def indented_name(indentation_character='.')
|
53
|
+
indentation_character * level + name
|
54
|
+
end
|
58
55
|
end
|
59
56
|
end
|
60
57
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
tabSize: 20,
|
19
19
|
disableNesting: 'ui-nestedSortable-no-nesting',
|
20
20
|
errorClass: 'ui-nestedSortable-error',
|
21
|
-
listType: '
|
21
|
+
listType: 'ul'
|
22
22
|
},
|
23
23
|
|
24
24
|
_create: function(){
|
@@ -288,4 +288,4 @@
|
|
288
288
|
|
289
289
|
$.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
|
290
290
|
|
291
|
-
})(jQuery);
|
291
|
+
})(jQuery);
|
@@ -1,67 +1,63 @@
|
|
1
1
|
$(document).ready(function() {
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
function linkHover() {
|
3
|
+
$(this).next().addClass('link_hover');
|
4
|
+
}
|
5
|
+
|
6
|
+
function linkUnhover() {
|
7
|
+
if (!$(this).next().hasClass('pop_up_hover'))
|
8
|
+
$(this).next().removeClass('link_hover');
|
9
|
+
}
|
10
|
+
|
11
|
+
function popUpHover() {
|
12
|
+
$(this).removeClass('link_hover');
|
13
|
+
$(this).addClass('pop_up_hover');
|
14
|
+
}
|
15
|
+
|
16
|
+
function popUpUnhover() {
|
17
|
+
$(this).removeClass('pop_up_hover');
|
18
|
+
}
|
19
|
+
|
20
|
+
var linkConfig = {
|
21
|
+
interval: 200,
|
22
|
+
out: linkUnhover,
|
23
|
+
over: linkHover,
|
24
|
+
sensitivity: 4,
|
25
|
+
timeout: 250
|
26
|
+
};
|
27
|
+
|
28
|
+
var popUpConfig = {
|
29
|
+
interval: 0,
|
30
|
+
out: popUpUnhover,
|
31
|
+
over: popUpHover,
|
32
|
+
sensitivity: 4,
|
33
|
+
timeout: 250
|
34
|
+
};
|
35
|
+
|
36
|
+
$('.mega_menu').hoverIntent(linkConfig);
|
37
|
+
$('.mega_menu_links').hoverIntent(popUpConfig);
|
38
|
+
|
39
|
+
$('#sns_categories').nestedSortable({
|
40
|
+
disableNesting: 'sns_item',
|
41
|
+
forcePlaceholderSize: true,
|
42
|
+
handle: '.handle',
|
43
|
+
items: 'li',
|
44
|
+
opacity: .6,
|
45
|
+
placeholder: 'placeholder',
|
46
|
+
tabSize: 25,
|
47
|
+
tolerance: 'pointer',
|
48
|
+
toleranceElement: '> div',
|
49
|
+
update: function(event, ui) {
|
50
|
+
$.ajax({
|
51
|
+
type: 'put',
|
52
|
+
url: this.getAttribute('data-url'),
|
53
|
+
data: { moved: ui.item[0].id, tree: $('#sns_categories').nestedSortable('serialize') }
|
54
|
+
});
|
5
55
|
}
|
6
|
-
|
7
|
-
function linkUnhover() {
|
8
|
-
if (!$(this).next().hasClass('pop_up_hover'))
|
9
|
-
$(this).next().removeClass('link_hover');
|
10
|
-
}
|
11
|
-
|
12
|
-
function popUpHover() {
|
13
|
-
$(this).removeClass('link_hover');
|
14
|
-
$(this).addClass('pop_up_hover');
|
15
|
-
}
|
16
|
-
|
17
|
-
function popUpUnhover() {
|
18
|
-
$(this).removeClass('pop_up_hover');
|
19
|
-
}
|
20
|
-
|
21
|
-
var linkConfig = {
|
22
|
-
interval: 200,
|
23
|
-
out: linkUnhover,
|
24
|
-
over: linkHover,
|
25
|
-
sensitivity: 4,
|
26
|
-
timeout: 250
|
27
|
-
};
|
28
|
-
|
29
|
-
var popUpConfig = {
|
30
|
-
interval: 0,
|
31
|
-
out: popUpUnhover,
|
32
|
-
over: popUpHover,
|
33
|
-
sensitivity: 4,
|
34
|
-
timeout: 250
|
35
|
-
};
|
36
|
-
|
37
|
-
$('.mega_menu').hoverIntent(linkConfig);
|
38
|
-
$('.mega_menu_links').hoverIntent(popUpConfig);
|
39
|
-
});
|
40
|
-
|
41
|
-
$.getScript('/javascripts/jquery.ui.nestedSortable.js', function() {
|
42
|
-
$('#menu').nestedSortable({
|
43
|
-
disableNesting: 'item',
|
44
|
-
forcePlaceholderSize: true,
|
45
|
-
handle: '.handle',
|
46
|
-
items: 'li',
|
47
|
-
opacity: .6,
|
48
|
-
placeholder: 'placeholder',
|
49
|
-
tabSize: 25,
|
50
|
-
tolerance: 'pointer',
|
51
|
-
toleranceElement: '> div',
|
52
|
-
update: function(event, ui) {
|
53
|
-
$.ajax({
|
54
|
-
type: 'put',
|
55
|
-
url: this.getAttribute('data-url'),
|
56
|
-
data: { moved: ui.item[0].id, tree: $('#menu').nestedSortable('serialize') }
|
57
|
-
});
|
58
|
-
}
|
59
|
-
});
|
60
56
|
});
|
61
57
|
|
62
|
-
$('#
|
58
|
+
$('#sns_categories .toggle').click(function() {
|
63
59
|
$(this).toggleClass('open');
|
64
60
|
$(this).toggleClass('closed');
|
65
|
-
$(this).
|
61
|
+
$(this).closest('li').find('> ul').toggle();
|
66
62
|
});
|
67
63
|
});
|
@@ -1,9 +1,3 @@
|
|
1
|
-
.mega_menu {
|
2
|
-
background: url(/images/mega_menu.png) no-repeat center;
|
3
|
-
cursor: pointer;
|
4
|
-
padding-left: 30px;
|
5
|
-
}
|
6
|
-
|
7
1
|
.mega_menu_links {
|
8
2
|
background: #ffc;
|
9
3
|
border: 1px solid #eea;
|
@@ -13,15 +7,6 @@
|
|
13
7
|
z-index: 1;
|
14
8
|
}
|
15
9
|
|
16
|
-
.mega_menu_links a:link, a:visited {
|
17
|
-
color: blue;
|
18
|
-
text-decoration: none;
|
19
|
-
}
|
20
|
-
|
21
|
-
.mega_menu_links a:hover {
|
22
|
-
color: green;
|
23
|
-
}
|
24
|
-
|
25
10
|
.link_hover {
|
26
11
|
display: block;
|
27
12
|
}
|
@@ -31,23 +16,23 @@
|
|
31
16
|
border: 1px solid #cca;
|
32
17
|
}
|
33
18
|
|
34
|
-
|
19
|
+
#sns_categories, #sns_categories ul {
|
35
20
|
list-style-type: none;
|
36
21
|
margin: 0 0 0 25px;
|
37
22
|
padding: 0;
|
38
23
|
}
|
39
24
|
|
40
|
-
|
25
|
+
#sns_categories {
|
41
26
|
margin: 0;
|
42
27
|
}
|
43
28
|
|
44
|
-
|
29
|
+
#sns_categories li {
|
45
30
|
margin: 7px 0 0 0;
|
46
31
|
padding: 0;
|
47
32
|
position: relative;
|
48
33
|
}
|
49
34
|
|
50
|
-
|
35
|
+
#sns_categories .handle {
|
51
36
|
cursor: move;
|
52
37
|
display: inline;
|
53
38
|
margin: 0;
|
@@ -67,11 +52,11 @@
|
|
67
52
|
padding-right: 1em;
|
68
53
|
}
|
69
54
|
|
70
|
-
#
|
55
|
+
#sns_categories span.open {
|
71
56
|
background: url(/images/folder_open.png) no-repeat center;
|
72
57
|
}
|
73
58
|
|
74
|
-
#
|
59
|
+
#sns_categories span.closed {
|
75
60
|
background: url(/images/folder_closed.png) no-repeat center;
|
76
61
|
}
|
77
62
|
|
data/sortable_nested_set.gemspec
CHANGED
@@ -5,22 +5,20 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sortable_nested_set}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.3"
|
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{
|
12
|
+
s.date = %q{2011-01-22}
|
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 = [
|
16
|
-
"README",
|
17
16
|
"README.rdoc"
|
18
17
|
]
|
19
18
|
s.files = [
|
20
19
|
".document",
|
21
20
|
"Gemfile",
|
22
21
|
"Gemfile.lock",
|
23
|
-
"README",
|
24
22
|
"README.rdoc",
|
25
23
|
"Rakefile",
|
26
24
|
"VERSION",
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 3
|
9
|
+
version: 0.2.3
|
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:
|
17
|
+
date: 2011-01-22 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -93,13 +93,11 @@ executables: []
|
|
93
93
|
extensions: []
|
94
94
|
|
95
95
|
extra_rdoc_files:
|
96
|
-
- README
|
97
96
|
- README.rdoc
|
98
97
|
files:
|
99
98
|
- .document
|
100
99
|
- Gemfile
|
101
100
|
- Gemfile.lock
|
102
|
-
- README
|
103
101
|
- README.rdoc
|
104
102
|
- Rakefile
|
105
103
|
- VERSION
|
@@ -138,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
138
136
|
requirements:
|
139
137
|
- - ">="
|
140
138
|
- !ruby/object:Gem::Version
|
141
|
-
hash:
|
139
|
+
hash: 787758848533743446
|
142
140
|
segments:
|
143
141
|
- 0
|
144
142
|
version: "0"
|
data/README
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
jQuery is required.
|
2
|
-
|
3
|
-
In the Gemfile
|
4
|
-
gem 'sortable_nested_set'
|
5
|
-
|
6
|
-
In each "Category" model (e.g. "Directory"):
|
7
|
-
acts_as_sortable_nested_set_of :items
|
8
|
-
where :items is the pluralized Item model (e.g. "File").
|
9
|
-
|
10
|
-
In each "Category" controller:
|
11
|
-
handles_sortable_nested_set
|
12
|
-
to include menu actions.
|
13
|
-
|
14
|
-
In the routes config file:
|
15
|
-
sortable_nested_set_for :categories
|
16
|
-
for each pluralized "Category" model.
|
17
|
-
|
18
|
-
In each "Category" migration:
|
19
|
-
name:string
|
20
|
-
lft:integer
|
21
|
-
rgt:integer
|
22
|
-
|
23
|
-
In each "Item" migration:
|
24
|
-
position:integer
|
25
|
-
|
26
|
-
Helpers:
|
27
|
-
sns_options
|
28
|
-
sns_lineage
|
29
|
-
sortable_nested_set_tree
|