the_sortable_tree_mongoid 1.8.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +302 -0
- data/Rakefile +37 -0
- data/app/assets/images/iconza/blue/add.png +0 -0
- data/app/assets/images/iconza/blue/delete.png +0 -0
- data/app/assets/images/iconza/blue/down.png +0 -0
- data/app/assets/images/iconza/blue/downloads_folder.png +0 -0
- data/app/assets/images/iconza/blue/edit.png +0 -0
- data/app/assets/images/iconza/blue/move.png +0 -0
- data/app/assets/images/iconza/blue/up.png +0 -0
- data/app/assets/images/iconza/gray/add.png +0 -0
- data/app/assets/images/iconza/gray/delete.png +0 -0
- data/app/assets/images/iconza/gray/down.png +0 -0
- data/app/assets/images/iconza/gray/edit.png +0 -0
- data/app/assets/images/iconza/gray/lock.png +0 -0
- data/app/assets/images/iconza/gray/mail.png +0 -0
- data/app/assets/images/iconza/gray/push_pin.png +0 -0
- data/app/assets/images/iconza/gray/up.png +0 -0
- data/app/assets/images/iconza/red/add.png +0 -0
- data/app/assets/images/iconza/red/delete.png +0 -0
- data/app/assets/images/iconza/red/down.png +0 -0
- data/app/assets/images/iconza/red/edit.png +0 -0
- data/app/assets/images/iconza/red/newspaper.png +0 -0
- data/app/assets/images/iconza/red/trash.png +0 -0
- data/app/assets/images/iconza/red/up.png +0 -0
- data/app/assets/images/iconza/red/zoom.png +0 -0
- data/app/assets/javascripts/jquery.ui.nestedSortable.js +356 -0
- data/app/assets/stylesheets/the_sortable_tree.css +120 -0
- data/app/assets/stylesheets/the_sortable_tree_min.css +26 -0
- data/app/controllers/the_sortable_tree_controller.rb +67 -0
- data/app/helpers/the_sortable_tree_helper.rb +69 -0
- data/app/views/the_sortable_tree/_children.html.haml +1 -0
- data/app/views/the_sortable_tree/_controls.html.haml +16 -0
- data/app/views/the_sortable_tree/_js_init_sortable_tree.html.haml +17 -0
- data/app/views/the_sortable_tree/_js_on_update_tree.html.haml +12 -0
- data/app/views/the_sortable_tree/_js_rebuild_ajax.html.haml +13 -0
- data/app/views/the_sortable_tree/_link.html.haml +7 -0
- data/app/views/the_sortable_tree/_new.html.haml +3 -0
- data/app/views/the_sortable_tree/_node.html.haml +3 -0
- data/app/views/the_sortable_tree/_tree.html.haml +6 -0
- data/app/views/the_sortable_tree_min/_children.html.haml +1 -0
- data/app/views/the_sortable_tree_min/_link.html.haml +1 -0
- data/app/views/the_sortable_tree_min/_node.html.haml +3 -0
- data/app/views/the_sortable_tree_min/_tree.html.haml +2 -0
- data/config/locales/en.yml +10 -0
- data/config/locales/ru.yml +10 -0
- data/lib/generators/the_sortable_tree/views_generator.rb +29 -0
- data/lib/tasks/the_sortable_tree.rake +4 -0
- data/lib/the_sortable_tree.rb +18 -0
- data/lib/the_sortable_tree/engine.rb +6 -0
- data/lib/the_sortable_tree/version.rb +3 -0
- data/spec/controlllers/controller_mixin_spec.rb +49 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/tests_controller.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +17 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +56 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -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/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +4 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +15 -0
- metadata +231 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2009-2012 Ilya N. Zykin, Matthew Clark
|
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.md
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
### TheSortableTree
|
2
|
+
|
3
|
+
Engine Based Drag&Drop GUI for awesome_nested_set gem. **Rails >= 3.1**
|
4
|
+
|
5
|
+
School teacher came to help! TaDa! ;)
|
6
|
+
|
7
|
+
**Drag&Drop sortable tree**
|
8
|
+
|
9
|
+
![TheSortableTree](https://github.com/the-teacher/the_sortable_tree/raw/master/pic.jpg)
|
10
|
+
|
11
|
+
**Simple nested sets (__min__ option)**
|
12
|
+
|
13
|
+
![TheSortableTree](https://github.com/the-teacher/the_sortable_tree/raw/master/pic_min.jpg)
|
14
|
+
|
15
|
+
**sortable_tree** - recursive helper-method for render sortable awesome_nested_set tree.
|
16
|
+
|
17
|
+
**sortable_tree** uses partials for rendering, that's why it is **so easy to customize**!
|
18
|
+
|
19
|
+
### List of available variants of rendering
|
20
|
+
|
21
|
+
* Drag&Drop sortable tree
|
22
|
+
* Simple nested sets (**min** option)
|
23
|
+
* Nested sets with expand/collapse animation (**expand** option) [under development]
|
24
|
+
* Nested comments (**comments** option) [under development]
|
25
|
+
|
26
|
+
### Can I use gem with Rails 2 or Rails 3.0?
|
27
|
+
|
28
|
+
Take files from the gem and put it in your rails 2 application.
|
29
|
+
|
30
|
+
View helper and view files does not depend on the version of rails.
|
31
|
+
|
32
|
+
Copy and Paste rebuild function from TheSortableTreeController.
|
33
|
+
|
34
|
+
Perhaps, you may have to slightly change the function of the controller.
|
35
|
+
|
36
|
+
### Changelog
|
37
|
+
|
38
|
+
1.8.5 - helper can rendering a part tree
|
39
|
+
|
40
|
+
1.8.0 - stable release
|
41
|
+
|
42
|
+
### Is it fast?
|
43
|
+
|
44
|
+
Hmmmm...
|
45
|
+
|
46
|
+
* Development env
|
47
|
+
* 584 elements
|
48
|
+
* 3 levels deep
|
49
|
+
|
50
|
+
Rendered by 50 sec.
|
51
|
+
|
52
|
+
I think it is good result for rendering by partials.
|
53
|
+
|
54
|
+
Can you makes it faster? Welcome!
|
55
|
+
|
56
|
+
### ERB vs HAML vs SLIM
|
57
|
+
|
58
|
+
So, ERB and SLIM fans want to make gem independent of HAML.
|
59
|
+
|
60
|
+
Ok, let it be. But you will convert view partials youself. It's my revenge ;)
|
61
|
+
|
62
|
+
Read project wiki for looking ERB partials
|
63
|
+
|
64
|
+
**By default I'm use HAML, and now you should define it manually in your Gemfile.**
|
65
|
+
|
66
|
+
### Install
|
67
|
+
|
68
|
+
gem 'haml'
|
69
|
+
gem 'awesome_nested_set' # gem 'nested_set'
|
70
|
+
gem 'the_sortable_tree'
|
71
|
+
|
72
|
+
bundle
|
73
|
+
|
74
|
+
### Require
|
75
|
+
|
76
|
+
1. gem 'nested_set' or gem 'awesome_nested_set'
|
77
|
+
2. gem 'haml'
|
78
|
+
3. JQuery UI
|
79
|
+
|
80
|
+
### Example of using with Page Model
|
81
|
+
|
82
|
+
### Jquery
|
83
|
+
|
84
|
+
**app/assets/javascripts/application.js**
|
85
|
+
|
86
|
+
``` ruby
|
87
|
+
//= require jquery
|
88
|
+
//= require jquery-ui
|
89
|
+
//= require jquery_ujs
|
90
|
+
```
|
91
|
+
|
92
|
+
### Extend your Model
|
93
|
+
|
94
|
+
``` ruby
|
95
|
+
class Page < ActiveRecord::Base
|
96
|
+
include TheSortableTree::Scopes
|
97
|
+
# any code here
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
### Extend your Controller
|
102
|
+
|
103
|
+
``` ruby
|
104
|
+
class PagesController < ApplicationController
|
105
|
+
include TheSortableTreeController::Rebuild
|
106
|
+
# any code here
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
or (for reversed tree)
|
111
|
+
|
112
|
+
``` ruby
|
113
|
+
class PagesController < ApplicationController
|
114
|
+
include TheSortableTreeController::ReversedRebuild
|
115
|
+
# any code here
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Extend your Routes
|
120
|
+
|
121
|
+
``` ruby
|
122
|
+
resources :pages do
|
123
|
+
collection do
|
124
|
+
get :manage
|
125
|
+
post :rebuild
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
**manage** action or any else action for show sortable tree
|
131
|
+
|
132
|
+
**rebuild** action is _required_ action for correctly work of **the_sortable_tree**
|
133
|
+
|
134
|
+
### Find your tree
|
135
|
+
|
136
|
+
``` ruby
|
137
|
+
class PagesController < ApplicationController
|
138
|
+
include TheSortableTreeController::Rebuild
|
139
|
+
|
140
|
+
def manage
|
141
|
+
@pages = Page.nested_set.all
|
142
|
+
end
|
143
|
+
|
144
|
+
# any code here
|
145
|
+
end
|
146
|
+
|
147
|
+
```
|
148
|
+
|
149
|
+
or
|
150
|
+
|
151
|
+
``` ruby
|
152
|
+
class PagesController < ApplicationController
|
153
|
+
include TheSortableTreeController::ReversedRebuild
|
154
|
+
|
155
|
+
def manage
|
156
|
+
@pages = Page.reversed_nested_set.all
|
157
|
+
end
|
158
|
+
|
159
|
+
# any code here
|
160
|
+
end
|
161
|
+
```
|
162
|
+
|
163
|
+
### Render your tree with TheSortableTree (Haml markup)
|
164
|
+
|
165
|
+
``` ruby
|
166
|
+
- content_for :css do
|
167
|
+
= stylesheet_link_tag 'the_sortable_tree', :media => :screen
|
168
|
+
- content_for :js do
|
169
|
+
= javascript_include_tag 'jquery.ui.nestedSortable'
|
170
|
+
|
171
|
+
= sortable_tree @pages, :new_url => new_page_path, :max_levels => 4
|
172
|
+
```
|
173
|
+
|
174
|
+
or (without administrator controls and drag&drop)
|
175
|
+
|
176
|
+
``` ruby
|
177
|
+
- content_for :css do
|
178
|
+
= stylesheet_link_tag 'the_sortable_tree_min', :media => :screen
|
179
|
+
|
180
|
+
= sortable_tree @pages, :new_url => new_page_path, :path => 'the_sortable_tree_min'
|
181
|
+
```
|
182
|
+
|
183
|
+
### Customize tree for User (min version)
|
184
|
+
|
185
|
+
**Use sortable_tree as view helper for simple rendering of nested_set tree**
|
186
|
+
|
187
|
+
``` ruby
|
188
|
+
rails g the_sortable_tree:views pages min
|
189
|
+
```
|
190
|
+
|
191
|
+
It's will generate minimal set of view partials for **sortable_tree** helper
|
192
|
+
|
193
|
+
``` ruby
|
194
|
+
create app/views/pages/the_sortable_tree_min
|
195
|
+
create app/views/pages/the_sortable_tree_min/_children.html.haml
|
196
|
+
create app/views/pages/the_sortable_tree_min/_node.html.haml
|
197
|
+
create app/views/pages/the_sortable_tree_min/_link.html.haml
|
198
|
+
create app/views/pages/the_sortable_tree_min/_tree.html.haml
|
199
|
+
```
|
200
|
+
|
201
|
+
Just use it or Customize and use it!
|
202
|
+
|
203
|
+
``` ruby
|
204
|
+
- content_for :css do
|
205
|
+
= stylesheet_link_tag 'the_sortable_tree_min', :media => :screen
|
206
|
+
= sortable_tree @pages, :new_url => new_page_path, :path => 'pages/the_sortable_tree_min'
|
207
|
+
```
|
208
|
+
|
209
|
+
### Customize tree for Administrator (full version)
|
210
|
+
|
211
|
+
``` ruby
|
212
|
+
rails g the_sortable_tree:views pages
|
213
|
+
```
|
214
|
+
|
215
|
+
It's will generate view partials for **sortable_tree** helper
|
216
|
+
|
217
|
+
``` ruby
|
218
|
+
create app/views/pages/the_sortable_tree
|
219
|
+
create app/views/pages/the_sortable_tree/_controls.html.haml
|
220
|
+
create app/views/pages/the_sortable_tree/_node.html.haml
|
221
|
+
create app/views/pages/the_sortable_tree/_js_init_sortable_tree.html.haml
|
222
|
+
create app/views/pages/the_sortable_tree/_js_on_update_tree.html.haml
|
223
|
+
create app/views/pages/the_sortable_tree/_js_rebuild_ajax.html.haml
|
224
|
+
create app/views/pages/the_sortable_tree/_link.html.haml
|
225
|
+
create app/views/pages/the_sortable_tree/_children.html.haml
|
226
|
+
create app/views/pages/the_sortable_tree/_new.html.haml
|
227
|
+
create app/views/pages/the_sortable_tree/_tree.html.haml
|
228
|
+
```
|
229
|
+
|
230
|
+
Customize and use it!
|
231
|
+
|
232
|
+
``` ruby
|
233
|
+
- content_for :css do
|
234
|
+
= stylesheet_link_tag 'the_sortable_tree', :media => :screen
|
235
|
+
- content_for :js do
|
236
|
+
= javascript_include_tag 'jquery.ui.nestedSortable'
|
237
|
+
|
238
|
+
= sortable_tree @pages, :new_url => new_page_path, :path => 'pages/the_sortable_tree', :max_levels => 2
|
239
|
+
```
|
240
|
+
|
241
|
+
### Rendering a part of tree
|
242
|
+
|
243
|
+
``` ruby
|
244
|
+
@root = Page.root
|
245
|
+
@pages = @root.descendants.nested_set.all
|
246
|
+
```
|
247
|
+
|
248
|
+
``` ruby
|
249
|
+
= @root.inspect
|
250
|
+
= sortable_tree @pages, :new_url => new_page_path
|
251
|
+
```
|
252
|
+
|
253
|
+
### LiveDemo
|
254
|
+
|
255
|
+
https://github.com/the-teacher/the_sortable_tree_test_app
|
256
|
+
|
257
|
+
### Options
|
258
|
+
|
259
|
+
**id** - id field (:id => :friendly_id etc. **:id** by default)
|
260
|
+
|
261
|
+
**title** - title field of node (:title => :name etc. **:title** by default)
|
262
|
+
|
263
|
+
**path** - path to custom view partials (:path => 'pages/the_sortable_tree')
|
264
|
+
|
265
|
+
**max_levels** - how many draggable levels can be? (**3** by default). **Can't be 0 (zero) and negative**
|
266
|
+
|
267
|
+
**namespace** - namespace for admin sections for example. (:namespace => :admin, **:namespace** => nil by default)
|
268
|
+
|
269
|
+
**opts[:level]** - view helper define level of recursion for each node. You can call **opts[:level]** into view partials
|
270
|
+
|
271
|
+
### Partials
|
272
|
+
|
273
|
+
**_tree** - root container for nested set elements
|
274
|
+
|
275
|
+
**_node** - element of tree (link to current node and nested set of children)
|
276
|
+
|
277
|
+
**_link** - decoration of link to current element of tree
|
278
|
+
|
279
|
+
**_children** - decoration of children
|
280
|
+
|
281
|
+
**_new** - create new element link
|
282
|
+
|
283
|
+
**_controls** - control elements for current node
|
284
|
+
|
285
|
+
|
286
|
+
**_js_init_sortable_tree** - JS for sortable tree
|
287
|
+
|
288
|
+
**_js_on_update_tree**- JS for sortable tree
|
289
|
+
|
290
|
+
**_js_rebuild_ajax**- JS for sortable tree
|
291
|
+
|
292
|
+
### Contributors
|
293
|
+
|
294
|
+
* https://github.com/the-teacher
|
295
|
+
* https://github.com/winescout
|
296
|
+
* https://github.com/gbrain
|
297
|
+
* https://github.com/Mik-die
|
298
|
+
|
299
|
+
### Acknowledgments
|
300
|
+
|
301
|
+
* https://github.com/mjsarfatti/nestedSortable
|
302
|
+
* http://iconza.com
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'TheSortableTree'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
|
31
|
+
require 'rspec/rails'
|
32
|
+
|
33
|
+
RSpec.configure do |config|
|
34
|
+
config.use_transactional_fixtures = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :default => :test
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,356 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery UI Nested Sortable
|
3
|
+
* v 1.3.4 / 28 apr 2011
|
4
|
+
* http://mjsarfatti.com/sandbox/nestedSortable
|
5
|
+
*
|
6
|
+
* Depends:
|
7
|
+
* jquery.ui.sortable.js 1.8+
|
8
|
+
*
|
9
|
+
* License CC BY-SA 3.0
|
10
|
+
* Copyright 2010-2011, Manuele J Sarfatti
|
11
|
+
*/
|
12
|
+
|
13
|
+
(function($) {
|
14
|
+
|
15
|
+
$.widget("ui.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
|
16
|
+
|
17
|
+
options: {
|
18
|
+
tabSize: 20,
|
19
|
+
disableNesting: 'ui-nestedSortable-no-nesting',
|
20
|
+
errorClass: 'ui-nestedSortable-error',
|
21
|
+
listType: 'ol',
|
22
|
+
maxLevels: 0,
|
23
|
+
noJumpFix: 0
|
24
|
+
},
|
25
|
+
|
26
|
+
_create: function(){
|
27
|
+
if (this.noJumpFix == false)
|
28
|
+
this.element.height(this.element.height());
|
29
|
+
this.element.data('sortable', this.element.data('nestedSortable'));
|
30
|
+
return $.ui.sortable.prototype._create.apply(this, arguments);
|
31
|
+
},
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
_mouseDrag: function(event) {
|
36
|
+
|
37
|
+
//Compute the helpers position
|
38
|
+
this.position = this._generatePosition(event);
|
39
|
+
this.positionAbs = this._convertPositionTo("absolute");
|
40
|
+
|
41
|
+
if (!this.lastPositionAbs) {
|
42
|
+
this.lastPositionAbs = this.positionAbs;
|
43
|
+
}
|
44
|
+
|
45
|
+
//Do scrolling
|
46
|
+
if(this.options.scroll) {
|
47
|
+
var o = this.options, scrolled = false;
|
48
|
+
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
|
49
|
+
|
50
|
+
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
|
51
|
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
|
52
|
+
else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
|
53
|
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
|
54
|
+
|
55
|
+
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
|
56
|
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
|
57
|
+
else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
|
58
|
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
|
59
|
+
|
60
|
+
} else {
|
61
|
+
|
62
|
+
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
|
63
|
+
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
64
|
+
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
|
65
|
+
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
66
|
+
|
67
|
+
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
|
68
|
+
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
69
|
+
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
|
70
|
+
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
71
|
+
|
72
|
+
}
|
73
|
+
|
74
|
+
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
|
75
|
+
$.ui.ddmanager.prepareOffsets(this, event);
|
76
|
+
}
|
77
|
+
|
78
|
+
//Regenerate the absolute position used for position checks
|
79
|
+
this.positionAbs = this._convertPositionTo("absolute");
|
80
|
+
|
81
|
+
//Set the helper position
|
82
|
+
if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
|
83
|
+
if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
|
84
|
+
|
85
|
+
//Rearrange
|
86
|
+
for (var i = this.items.length - 1; i >= 0; i--) {
|
87
|
+
|
88
|
+
//Cache variables and intersection, continue if no intersection
|
89
|
+
var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
|
90
|
+
if (!intersection) continue;
|
91
|
+
|
92
|
+
if(itemElement != this.currentItem[0] //cannot intersect with itself
|
93
|
+
&& this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
|
94
|
+
&& !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
|
95
|
+
&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
|
96
|
+
//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
|
97
|
+
) {
|
98
|
+
|
99
|
+
this.direction = intersection == 1 ? "down" : "up";
|
100
|
+
|
101
|
+
if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
|
102
|
+
this._rearrange(event, item);
|
103
|
+
} else {
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
|
107
|
+
// Clear emtpy ul's/ol's
|
108
|
+
this._clearEmpty(itemElement);
|
109
|
+
|
110
|
+
this._trigger("change", event, this._uiHash());
|
111
|
+
break;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
var parentItem = (this.placeholder[0].parentNode.parentNode && $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length) ? $(this.placeholder[0].parentNode.parentNode) : null;
|
116
|
+
var level = this._getLevel(this.placeholder);
|
117
|
+
var childLevels = this._getChildLevels(this.helper);
|
118
|
+
var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
|
119
|
+
if (previousItem != null) {
|
120
|
+
while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0]) {
|
121
|
+
if (previousItem[0].previousSibling) {
|
122
|
+
previousItem = $(previousItem[0].previousSibling);
|
123
|
+
} else {
|
124
|
+
previousItem = null;
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
newList = document.createElement(o.listType);
|
131
|
+
|
132
|
+
this.beyondMaxLevels = 0;
|
133
|
+
|
134
|
+
// If the item is moved to the left, send it to its parent level
|
135
|
+
if (parentItem != null && this.positionAbs.left < parentItem.offset().left) {
|
136
|
+
parentItem.after(this.placeholder[0]);
|
137
|
+
this._clearEmpty(parentItem[0]);
|
138
|
+
this._trigger("change", event, this._uiHash());
|
139
|
+
}
|
140
|
+
// If the item is below another one and is moved to the right, make it a children of it
|
141
|
+
else if (previousItem != null && this.positionAbs.left > previousItem.offset().left + o.tabSize) {
|
142
|
+
this._isAllowed(previousItem, level+childLevels+1);
|
143
|
+
if (!previousItem.children(o.listType).length) {
|
144
|
+
previousItem[0].appendChild(newList);
|
145
|
+
}
|
146
|
+
previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
|
147
|
+
this._trigger("change", event, this._uiHash());
|
148
|
+
}
|
149
|
+
else {
|
150
|
+
this._isAllowed(parentItem, level+childLevels);
|
151
|
+
}
|
152
|
+
|
153
|
+
//Post events to containers
|
154
|
+
this._contactContainers(event);
|
155
|
+
|
156
|
+
//Interconnect with droppables
|
157
|
+
if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
|
158
|
+
|
159
|
+
//Call callbacks
|
160
|
+
this._trigger('sort', event, this._uiHash());
|
161
|
+
|
162
|
+
this.lastPositionAbs = this.positionAbs;
|
163
|
+
return false;
|
164
|
+
|
165
|
+
},
|
166
|
+
|
167
|
+
_mouseStop: function(event, noPropagation) {
|
168
|
+
|
169
|
+
// If the item is in a position not allowed, send it back
|
170
|
+
if (this.beyondMaxLevels) {
|
171
|
+
var parent = this.placeholder.parent().closest(this.options.items);
|
172
|
+
|
173
|
+
for (var i = this.beyondMaxLevels - 1; i > 0; i--) {
|
174
|
+
parent = parent.parent().closest(this.options.items);
|
175
|
+
}
|
176
|
+
|
177
|
+
this.placeholder.removeClass(this.options.errorClass);
|
178
|
+
parent.after(this.placeholder);
|
179
|
+
this._trigger("change", event, this._uiHash());
|
180
|
+
}
|
181
|
+
|
182
|
+
$.ui.sortable.prototype._mouseStop.apply(this, arguments);
|
183
|
+
|
184
|
+
},
|
185
|
+
|
186
|
+
serialize: function(o) {
|
187
|
+
|
188
|
+
var items = this._getItemsAsjQuery(o && o.connected);
|
189
|
+
var str = []; o = o || {};
|
190
|
+
|
191
|
+
$(items).each(function() {
|
192
|
+
var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
|
193
|
+
var pid = ($(o.item || this).parent(o.listType).parent('li').attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
|
194
|
+
if(res) str.push((o.key || res[1]+'['+(o.key && o.expression ? res[1] : res[2])+']')+'='+(pid ? (o.key && o.expression ? pid[1] : pid[2]) : 'root'));
|
195
|
+
});
|
196
|
+
|
197
|
+
if(!str.length && o.key) {
|
198
|
+
str.push(o.key + '=');
|
199
|
+
}
|
200
|
+
|
201
|
+
return str.join('&');
|
202
|
+
|
203
|
+
},
|
204
|
+
|
205
|
+
toHierarchy: function(o) {
|
206
|
+
|
207
|
+
o = o || {};
|
208
|
+
var sDepth = o.startDepthCount || 0;
|
209
|
+
var ret = [];
|
210
|
+
|
211
|
+
$(this.element).children('li').each(function() {
|
212
|
+
var level = _recursiveItems($(this));
|
213
|
+
ret.push(level);
|
214
|
+
});
|
215
|
+
|
216
|
+
return ret;
|
217
|
+
|
218
|
+
function _recursiveItems(li) {
|
219
|
+
var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
|
220
|
+
if (id != null) {
|
221
|
+
var item = {"id" : id[2]};
|
222
|
+
if ($(li).children(o.listType).children('li').length > 0) {
|
223
|
+
item.children = [];
|
224
|
+
$(li).children(o.listType).children('li').each(function () {
|
225
|
+
var level = _recursiveItems($(this));
|
226
|
+
item.children.push(level);
|
227
|
+
});
|
228
|
+
}
|
229
|
+
return item;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
},
|
233
|
+
|
234
|
+
toArray: function(o) {
|
235
|
+
|
236
|
+
o = o || {};
|
237
|
+
var sDepth = o.startDepthCount || 0;
|
238
|
+
var ret = [];
|
239
|
+
var left = 2;
|
240
|
+
|
241
|
+
ret.push({"item_id": 'root', "parent_id": 'none', "depth": sDepth, "left": '1', "right": ($('li', this.element).length + 1) * 2});
|
242
|
+
|
243
|
+
$(this.element).children('li').each(function () {
|
244
|
+
left = _recursiveArray(this, sDepth + 1, left);
|
245
|
+
});
|
246
|
+
|
247
|
+
function _sortByLeft(a,b) {
|
248
|
+
return a['left'] - b['left'];
|
249
|
+
}
|
250
|
+
ret = ret.sort(_sortByLeft);
|
251
|
+
|
252
|
+
return ret;
|
253
|
+
|
254
|
+
function _recursiveArray(item, depth, left) {
|
255
|
+
|
256
|
+
right = left + 1;
|
257
|
+
|
258
|
+
if ($(item).children(o.listType).children('li').length > 0) {
|
259
|
+
depth ++;
|
260
|
+
$(item).children(o.listType).children('li').each(function () {
|
261
|
+
right = _recursiveArray($(this), depth, right);
|
262
|
+
});
|
263
|
+
depth --;
|
264
|
+
}
|
265
|
+
|
266
|
+
id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
|
267
|
+
|
268
|
+
if (depth === sDepth + 1) pid = 'root';
|
269
|
+
else {
|
270
|
+
parentItem = ($(item).parent(o.listType).parent('li').attr('id')).match(o.expression || (/(.+)[-=_](.+)/));
|
271
|
+
pid = parentItem[2];
|
272
|
+
}
|
273
|
+
|
274
|
+
if (id != null) {
|
275
|
+
ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
|
276
|
+
}
|
277
|
+
|
278
|
+
return left = right + 1;
|
279
|
+
}
|
280
|
+
|
281
|
+
},
|
282
|
+
|
283
|
+
_clear: function(event, noPropagation) {
|
284
|
+
|
285
|
+
$.ui.sortable.prototype._clear.apply(this, arguments);
|
286
|
+
|
287
|
+
// Clean last empty ul/ol
|
288
|
+
for (var i = this.items.length - 1; i >= 0; i--) {
|
289
|
+
var item = this.items[i].item[0];
|
290
|
+
this._clearEmpty(item);
|
291
|
+
}
|
292
|
+
return true;
|
293
|
+
|
294
|
+
},
|
295
|
+
|
296
|
+
_clearEmpty: function(item) {
|
297
|
+
|
298
|
+
if (item.children[1] && item.children[1].children.length == 0) {
|
299
|
+
item.removeChild(item.children[1]);
|
300
|
+
}
|
301
|
+
|
302
|
+
},
|
303
|
+
|
304
|
+
_getLevel: function(item) {
|
305
|
+
|
306
|
+
var level = 1;
|
307
|
+
|
308
|
+
if (this.options.listType) {
|
309
|
+
var list = item.closest(this.options.listType);
|
310
|
+
while (!list.is('.ui-sortable')/* && level < this.options.maxLevels*/) {
|
311
|
+
level++;
|
312
|
+
list = list.parent().closest(this.options.listType);
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
return level;
|
317
|
+
},
|
318
|
+
|
319
|
+
_getChildLevels: function(parent, depth) {
|
320
|
+
var self = this,
|
321
|
+
o = this.options,
|
322
|
+
result = 0;
|
323
|
+
depth = depth || 0;
|
324
|
+
|
325
|
+
$(parent).children(o.listType).children(o.items).each(function (index, child) {
|
326
|
+
result = Math.max(self._getChildLevels(child, depth + 1), result);
|
327
|
+
});
|
328
|
+
|
329
|
+
return depth ? result + 1 : result;
|
330
|
+
},
|
331
|
+
|
332
|
+
_isAllowed: function(parentItem, levels) {
|
333
|
+
var o = this.options
|
334
|
+
// Are we trying to nest under a no-nest or are we nesting too deep?
|
335
|
+
if (parentItem == null || !(parentItem.hasClass(o.disableNesting))) {
|
336
|
+
if (o.maxLevels < levels && o.maxLevels != 0) {
|
337
|
+
this.placeholder.addClass(o.errorClass);
|
338
|
+
this.beyondMaxLevels = levels - o.maxLevels;
|
339
|
+
} else {
|
340
|
+
this.placeholder.removeClass(o.errorClass);
|
341
|
+
this.beyondMaxLevels = 0;
|
342
|
+
}
|
343
|
+
} else {
|
344
|
+
this.placeholder.addClass(o.errorClass);
|
345
|
+
if (o.maxLevels < levels && o.maxLevels != 0) {
|
346
|
+
this.beyondMaxLevels = levels - o.maxLevels;
|
347
|
+
} else {
|
348
|
+
this.beyondMaxLevels = 1;
|
349
|
+
}
|
350
|
+
}
|
351
|
+
}
|
352
|
+
|
353
|
+
}));
|
354
|
+
|
355
|
+
$.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
|
356
|
+
})(jQuery);
|