sortable_nested_set 0.1.23

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.
@@ -0,0 +1,34 @@
1
+ ul.menu_links li.category span.mega {
2
+ display: inline;
3
+ color: blue;
4
+ cursor: pointer;
5
+ }
6
+
7
+ ul.menu_links li.category {
8
+ position: relative;
9
+ }
10
+
11
+ ul.menu_links li.category div.links {
12
+ display: none;
13
+ z-index: 1;
14
+ border: 1px solid #eea;
15
+ position: absolute;
16
+ top: 1.6em;
17
+ left: 0em;
18
+ padding: 1.3em;
19
+ background: #ffc;
20
+ }
21
+
22
+ ul.menu_links li.category div.items {
23
+ min-height: 5px;
24
+ padding-left: 20px;
25
+ }
26
+
27
+ ul.menu_links li.category div.link_hover {
28
+ display: block;
29
+ }
30
+
31
+ ul.menu_links li.category div.pop_up_hover {
32
+ display: block;
33
+ border: 1px solid #cca;
34
+ }
@@ -0,0 +1,31 @@
1
+ ul.menu_links, ul.sub_menu_links {
2
+ list-style: none;
3
+ margin-left: 0px;
4
+ padding-left: 0px;
5
+ }
6
+
7
+ li > ul.sub_menu_links {
8
+ padding-left: 1em;
9
+ }
10
+
11
+ span.toggle a:hover {
12
+ background-color: white;
13
+ }
14
+
15
+ li.placeholder {
16
+ height: 3px;
17
+ }
18
+
19
+ li.hovered {
20
+ background: url(/images/drag.png) no-repeat bottom left;
21
+ }
22
+
23
+ li.category span.handle {
24
+ cursor: move;
25
+ font-variant: small-caps;
26
+ }
27
+
28
+ li.category div.item .handle {
29
+ cursor: move;
30
+ font-variant: normal;
31
+ }
@@ -0,0 +1,68 @@
1
+ require "awesome_nested_set"
2
+ include CollectiveIdea::Acts::NestedSet
3
+
4
+ module SortableNestedSet
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def acts_as_sortable_nested_set_of(items_type)
11
+ send(:include, InstanceMethods)
12
+
13
+ @subcategories_type = "sub#{name.tableize}".to_sym
14
+ @items_type = items_type
15
+
16
+ instance_eval do
17
+ def sns_subcategories_type ; @subcategories_type end
18
+ def sns_items_type ; @items_type end
19
+ end
20
+
21
+ class_eval do
22
+ define_method(:sns_subcategories) { send(self.class.sns_subcategories_type) }
23
+ define_method(:sns_items) { send(self.class.sns_items_type) }
24
+ end
25
+
26
+ acts_as_nested_set :parent_column => name.foreign_key
27
+
28
+ belongs_to name.underscore
29
+
30
+ has_many @subcategories_type, :class_name => name, :dependent => :destroy
31
+ has_many @items_type, :order => :position, :dependent => :destroy
32
+
33
+ default_scope :order => :lft
34
+ end
35
+ end
36
+
37
+ module InstanceMethods
38
+ def self_and_descendants_with_items
39
+ nested_set_scope.scoped :include => self.class.sns_items_type, :conditions => [
40
+ "#{self.class.quoted_table_name}.#{quoted_left_column_name} >= ? AND
41
+ #{self.class.quoted_table_name}.#{quoted_right_column_name} <= ?", left, right
42
+ ]
43
+ end
44
+
45
+ def lineage(options=Hash.new)
46
+ conditions = [ 'lft <= ? AND rgt >= ?', lft, rgt ]
47
+ unless options[:include_self] == true
48
+ conditions[0] << ' AND id != ?'
49
+ conditions << id
50
+ end
51
+
52
+ self.class.find(:all, :select => 'id, name', :conditions => conditions, :order => 'lft ASC')
53
+ end
54
+
55
+ # descendents() does "SELECT *" but only id field required
56
+ def descendant_subcategory_ids(options=Hash.new)
57
+ conditions = [ 'lft >= ? AND rgt <= ?', lft, rgt ]
58
+ unless options[:include_self] == true
59
+ conditions[0] << ' AND id != ?'
60
+ conditions << id
61
+ end
62
+
63
+ self.class.find(:all, :select => :id, :conditions => conditions).collect(&:id)
64
+ end
65
+ end
66
+ end
67
+
68
+ ActiveRecord::Base.send(:include, SortableNestedSet)
@@ -0,0 +1,10 @@
1
+ require "sortable_nested_set"
2
+ require "rails"
3
+
4
+ module SortableNestedSet
5
+ class Engine < Rails::Engine
6
+ config.to_prepare do
7
+ ApplicationController.helper(SortableNestedSetHelper)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,155 @@
1
+ require "sortable_element_for_nested_set"
2
+ include SortableElementForNestedSet
3
+
4
+ module SortableNestedSet
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def handles_sortable_nested_set
11
+ handles_sorting_of_nested_set
12
+
13
+ class_eval do
14
+ define_method(:sns_category_controller) { controller_name }
15
+ define_method(:sns_category_id_field) { "#{controller_name.singularize}_id" }
16
+ define_method(:sns_category_class) { controller_name.classify.constantize }
17
+ define_method(:sns_items_type) {sns_category_class.sns_items_type }
18
+ define_method(:sns_item_class) {sns_items_type.to_s.classify.constantize }
19
+ end
20
+
21
+ include(SortableNestedSet::InstanceMethods)
22
+ end
23
+ end
24
+
25
+ module InstanceMethods
26
+ def sns_add_subcategory
27
+ redirect_to(:controller => sns_category_controller, :action => :new, sns_category_id_field => params[:id])
28
+ end
29
+
30
+ def sns_add_item
31
+ redirect_to(:controller => sns_items_type, :action => :new, sns_category_id_field => params[:id])
32
+ end
33
+
34
+ def sns_sort_categories
35
+ category = sns_category_class.find(params[:moved])
36
+ new_pos = position_of(:moved).in_tree(:menu)
37
+
38
+ # Ambiguous moves occur when a category is dropped outside the menu AND
39
+ # a :root parameter is specified. In this case, move the element to the
40
+ # :root category in the database and also put it at the end with javascript.
41
+ ambiguous_move = nil
42
+
43
+ begin
44
+ category.transaction do
45
+ if new_pos[:parent]
46
+ category.move_to_child_of(new_pos[:parent])
47
+ elsif params[:root].nil?
48
+ category.move_to_root
49
+ else
50
+ root_id = params[:root].to_i
51
+ ambiguous_move = params[:menu]['0']['id'] == params[:moved] ? :top : :bottom
52
+
53
+ if ambiguous_move == :bottom
54
+ category.move_to_child_of(params[:root])
55
+ else
56
+ category.move_to_left_of(sns_category_class.find(params[:root]).sns_subcategories.first)
57
+ end
58
+ end unless category.parent_id === new_pos[:parent]
59
+
60
+ begin
61
+ if new_pos[:move_to_right_of]
62
+ category.move_to_right_of(new_pos[:move_to_right_of])
63
+ else
64
+ category.move_to_left_of(new_pos[:move_to_left_of])
65
+ end
66
+ rescue ActiveRecord::RecordNotFound
67
+ # FIXME error raised when making first child
68
+ end unless ambiguous_move
69
+
70
+ raise category.errors.full_messages.to_sentence unless category.valid?
71
+ end
72
+ rescue => err
73
+ render :update do |page|
74
+ page.alert err.message
75
+ page.reload # TODO return to original location with javascript
76
+ end
77
+ else
78
+ render :update do |page|
79
+ page.assign :categoryElement, page.literal("$('category_#{category.id}')")
80
+
81
+ if ambiguous_move
82
+ page.assign :rootElement, page.literal("$('subcategories_#{root_id}')")
83
+ page.remove "category_#{category.id}"
84
+
85
+ # there is a placeholder at index 0
86
+ page << (ambiguous_move == :top ?
87
+ 'rootElement.insertBefore(categoryElement, rootElement.childElements()[1])' :
88
+ 'rootElement.insert(categoryElement)')
89
+
90
+ page.visual_effect 'highlight', "category_#{category.id}"
91
+ else
92
+ page.assign :elderSibling, page.literal('categoryElement.nextElementSibling')
93
+ page.assign :parent, page.literal('categoryElement.parentNode')
94
+
95
+ page << <<EOF
96
+ if (elderSibling && elderSibling.hasClassName('placeholder')) {
97
+ elderSibling.remove();
98
+ parent.insertBefore(elderSibling, categoryElement);
99
+ }
100
+
101
+ /* WORKAROUND DEFECT: after dragdrop, z-index not abided by */
102
+ categoryElement.style.removeProperty('z-index');
103
+ EOF
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def sns_sort_items
110
+ container = params.find { |key, val| key =~ /items_\d+/ }
111
+
112
+ params[container.first].each_with_index do |id, index|
113
+ category_id = container.first.match(/items_(\d+)/)[1]
114
+ sns_item_class.update(id, sns_category_id_field => category_id, :position => index + 1)
115
+ end if container
116
+
117
+ render :update do |page|
118
+ id = "item_#{params[:moved]}"
119
+ page << "$('#{id}').style.removeProperty('z-index')"
120
+ end
121
+ end
122
+
123
+ def sns_toggle
124
+ render :update do |page|
125
+ page["items_#{params[:id]}"].toggle
126
+ page["subcategories_#{params[:id]}"].toggle
127
+ page.replace_html "toggle_#{params[:id]}",
128
+ :partial => 'sortable_nested_set/toggle',
129
+ :locals => { :category_type => params[:category_type],
130
+ :id => params[:id],
131
+ :state => (params[:state] == 'open' ? 'closed' : 'open') }
132
+ end
133
+ end
134
+
135
+ def sns_destroy_category
136
+ @category = sns_category_class.find(params[:id])
137
+ @category.destroy
138
+
139
+ render :update do |page|
140
+ page["category_#{@category.id}"].remove
141
+ end
142
+ end
143
+
144
+ def sns_destroy_item
145
+ @item = sns_item_class.find(params[:id])
146
+ @item.destroy
147
+
148
+ render :update do |page|
149
+ page["item_#{@item.id}"].remove
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ ActionController::Base.send(:include, SortableNestedSet)
@@ -0,0 +1,18 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def sortable_nested_set_for(category_type)
4
+ resources category_type do
5
+ get :sns_toggle, :on => :member
6
+ get :sns_add_subcategory, :on => :member
7
+ get :sns_add_item, :on => :member
8
+ put :sns_sort_categories, :on => :collection
9
+ put :sns_sort_items, :on => :collection
10
+ delete :sns_destroy_category, :on => :member
11
+ end
12
+
13
+ resources category_type.to_s.classify.constantize.sns_items_type do
14
+ delete :sns_destroy_item, :on => :member, :controller => category_type
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,4 @@
1
+ require "sortable_nested_set/engine" if defined?(Rails)
2
+ require "sortable_nested_set/acts_as_sortable_nested_set"
3
+ require "sortable_nested_set/handles_sortable_nested_set"
4
+ require "sortable_nested_set/routes"
@@ -0,0 +1,6 @@
1
+ namespace :sortable_nested_set do
2
+ desc "Sync public files"
3
+ task :sync do
4
+ system "rsync -ruvvh #{File.join File.dirname(__FILE__), "..", "public"} ."
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sortable_nested_set
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 23
9
+ version: 0.1.23
10
+ platform: ruby
11
+ authors: []
12
+
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-29 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: awesome_nested_set
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: sortable_element_for_nested_set
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ description:
47
+ email:
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - README
54
+ files:
55
+ - app/helpers/sortable_nested_set_helper.rb
56
+ - app/views/sortable_nested_set/_category.html.erb
57
+ - app/views/sortable_nested_set/_item.html.erb
58
+ - app/views/sortable_nested_set/_toggle.html.erb
59
+ - app/views/sortable_nested_set/_tree.html.erb
60
+ - lib/public/images/drag.png
61
+ - lib/public/images/folder_closed.png
62
+ - lib/public/images/folder_open.png
63
+ - lib/public/javascripts/controls.js
64
+ - lib/public/javascripts/dragdrop.js
65
+ - lib/public/javascripts/effects.js
66
+ - lib/public/javascripts/jquery.hoverIntent.minified.js
67
+ - lib/public/javascripts/jquery.js
68
+ - lib/public/javascripts/mega_menu.js
69
+ - lib/public/javascripts/prototype.js
70
+ - lib/public/stylesheets/mega_menu.css
71
+ - lib/public/stylesheets/menu_tree.css
72
+ - lib/sortable_nested_set.rb
73
+ - lib/sortable_nested_set/acts_as_sortable_nested_set.rb
74
+ - lib/sortable_nested_set/engine.rb
75
+ - lib/sortable_nested_set/handles_sortable_nested_set.rb
76
+ - lib/sortable_nested_set/routes.rb
77
+ - lib/tasks/sortable_nested_set_tasks.rake
78
+ - README
79
+ has_rdoc: true
80
+ homepage:
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options:
85
+ - --charset=UTF-8
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ segments:
102
+ - 0
103
+ version: "0"
104
+ requirements: []
105
+
106
+ rubyforge_project:
107
+ rubygems_version: 1.3.7
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Sortable Nested Set
111
+ test_files: []
112
+