jquery-sortable-rails 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +1 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/certs/bai.pem +20 -0
- data/jqeury-sortable-rails.gemspec +25 -0
- data/lib/jquery-sortable-rails.rb +10 -0
- data/lib/jquery-sortable-rails/version.rb +7 -0
- data/vendor/assets/javascripts/jquery.sortable.js +607 -0
- metadata +95 -0
- metadata.gz.sig +2 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 28dbb5f1f434adf64b76b443e6b7314d8f6f538c
|
4
|
+
data.tar.gz: c63660b8b9ae356b3ebdab7b6f1651184c2ccc6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7144dd4518bccb8a5f390f57aa5cd2c098bcd0ec3c81053604cccc710a31a0c0e46b6ec918a23a43fbd23f08ce29cfdf57fb68ec47339d959d44f3ebef79452b
|
7
|
+
data.tar.gz: 105b026a87e5f31ec6a3e8227493367507a1729264bbf39dd0cbd09f965d8d206038ee77d6b141316f6c97781cdf4e7c700edbfb6d1fcf678c9a56c09002fa3c
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
H]IĮ����zL�&�#Z��оZA���(l���"�؝�2�L�7� ���92�����v�?����j�߅����j8���݊����J �� a��6�pY��E�^ߧy-ՠ��#[�!���Ak����p��^ں&�.y�3;@�{olƫH��G���-����Gn���d���|y����R����[���H�m_�{�G
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Vlad Gorodetsky
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# jquery-sortable-rails
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add the following to your gemfile:
|
6
|
+
|
7
|
+
gem 'jquery-sortable-rails'
|
8
|
+
|
9
|
+
And then execute:
|
10
|
+
|
11
|
+
$ bundle
|
12
|
+
|
13
|
+
Add the following directive to your JavaScript manifest file (application.js):
|
14
|
+
|
15
|
+
//= require jquery.sortable
|
16
|
+
|
17
|
+
## HighSecurity
|
18
|
+
|
19
|
+
To ensure that you're including a gem with original code, you can install this gem using a HighSecurity policy.
|
20
|
+
|
21
|
+
gem cert --add <(curl -Ls https://gist.github.com/bai/5150087/raw/public_cert.pem)
|
22
|
+
bundle install --trust-policy HighSecurity
|
23
|
+
|
24
|
+
Or, if you don't use bundler:
|
25
|
+
|
26
|
+
gem install jquery-sortable-rails -P HighSecurity
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
1. Fork it
|
31
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
33
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/certs/bai.pem
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA1MQowCAYDVQQDDAF2MRMw
|
3
|
+
EQYKCZImiZPyLGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wHhcNMTMwNTIz
|
4
|
+
MjA0MTI3WhcNMTQwNTIzMjA0MTI3WjA1MQowCAYDVQQDDAF2MRMwEQYKCZImiZPy
|
5
|
+
LGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wggEiMA0GCSqGSIb3DQEBAQUA
|
6
|
+
A4IBDwAwggEKAoIBAQCtb8+GfjqcYl6M4IhIGomKsGgWEC4mwTXIq/Yl+jJAdP7s
|
7
|
+
bdV3lWnZybUPKtdHSQIJcxbm8GZspTqSqDgsECI/laTyLj7Srqcbyivf/ov50Tg1
|
8
|
+
CxMtt8STA6wNmY0ljO4SK72Pr8uQwFZIgNHBB9LcvrpmRn/TWDXlcqaq0db6QJKk
|
9
|
+
jGOv74ukiQun+saqthpxwNN6wm0rj1GDulrDuMeeMj/XDgu0piNHhBtsgQ6KrN94
|
10
|
+
cs0XGgwKihL0LdqWiOG9L8tZKeksKk72EcTpvaw1EYUfJ/rAcC8l6SluN2+BDMA0
|
11
|
+
/4LU70O+wTwHcHv2HimtKdlcpS936qOez3lXUD+3AgMBAAGjYzBhMAkGA1UdEwQC
|
12
|
+
MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSRvHatldjBIKT5agA2bnkfm4KUxTAT
|
13
|
+
BgNVHREEDDAKgQh2QGdvci5pbzATBgNVHRIEDDAKgQh2QGdvci5pbzANBgkqhkiG
|
14
|
+
9w0BAQUFAAOCAQEAmyGZCL6ISHS6UCkPAie1LZgyc+yS4ckMPtzBJtjODr5kfRTC
|
15
|
+
tLb9W4epJ9Aa2aGkKy/NL8MFS0BwTJmjSfufFDwFZlw0kI9aAvL4Nx9OHWNen9Dm
|
16
|
+
GtEWXXKpB0du12DBjfavJYl0QLcz18M0mtvug634t40H06GussO83uu7wHEvIPBP
|
17
|
+
Z5VMAbKvOmDgaP2I9XxZ2/lDmBKDZkVNqmqYiScw2CWsKxVPx3vhMGprTIz4O8y/
|
18
|
+
JCf887eMZl/8mEIeCLb+gH5sh5yJJpti2HTLnR4Q1QKWR/0T9tASoQPF3kL62n9+
|
19
|
+
m1B90+fEzJsBDQIAsnLPqxjivWbIIfZ7GeGZyA==
|
20
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jquery-sortable-rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "jquery-sortable-rails"
|
8
|
+
gem.version = Jquery::Sortable::Rails::VERSION
|
9
|
+
gem.authors = ["Vlad Gorodetsky"]
|
10
|
+
gem.email = ["v@gor.io"]
|
11
|
+
gem.description = %q{Sortable control for jQuery.}
|
12
|
+
gem.summary = %q{Gemified jquery-sortable asset for Rails}
|
13
|
+
gem.homepage = "http://github.com/bai/jquery-sortable-rails"
|
14
|
+
gem.licenses = ["MIT"]
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.signing_key = File.expand_path("~/.gem/private_key.pem") if $0 =~ /gem\z/
|
22
|
+
gem.cert_chain = ["certs/bai.pem"]
|
23
|
+
|
24
|
+
gem.add_dependency "railties", ">= 3.0", "< 5.0"
|
25
|
+
end
|
@@ -0,0 +1,607 @@
|
|
1
|
+
/* ===================================================
|
2
|
+
* jquery-sortable.js v0.9.11
|
3
|
+
* http://johnny.github.com/jquery-sortable/
|
4
|
+
* ===================================================
|
5
|
+
* Copyright (c) 2012 Jonas von Andrian
|
6
|
+
* All rights reserved.
|
7
|
+
*
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
10
|
+
* * Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* * Redistributions in binary form must reproduce the above copyright
|
13
|
+
* notice, this list of conditions and the following disclaimer in the
|
14
|
+
* documentation and/or other materials provided with the distribution.
|
15
|
+
* * The name of the author may not be used to endorse or promote products
|
16
|
+
* derived from this software without specific prior written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
19
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
22
|
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
23
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
24
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
25
|
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
26
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
* ========================================================== */
|
29
|
+
|
30
|
+
|
31
|
+
!function ( $, window, undefined){
|
32
|
+
var eventNames,
|
33
|
+
pluginName = 'sortable',
|
34
|
+
containerDefaults = {
|
35
|
+
// If true, items can be dragged from this container
|
36
|
+
drag: true,
|
37
|
+
// If true, items can be droped onto this container
|
38
|
+
drop: true,
|
39
|
+
// Exclude items from being draggable, if the
|
40
|
+
// selector matches the item
|
41
|
+
exclude: "",
|
42
|
+
// If true, search for nested containers within an item
|
43
|
+
nested: true,
|
44
|
+
// If true, the items are assumed to be arranged vertically
|
45
|
+
vertical: true
|
46
|
+
}, // end container defaults
|
47
|
+
groupDefaults = {
|
48
|
+
// This is executed after the placeholder has been moved.
|
49
|
+
afterMove: function ($placeholder, container) {
|
50
|
+
},
|
51
|
+
// The exact css path between the container and its items, e.g. "> tbody"
|
52
|
+
containerPath: "",
|
53
|
+
// The css selector of the containers
|
54
|
+
containerSelector: "ol, ul",
|
55
|
+
// Distance the mouse has to travel to start dragging
|
56
|
+
distance: 0,
|
57
|
+
// The css selector of the drag handle
|
58
|
+
handle: "",
|
59
|
+
// The exact css path between the item and its subcontainers
|
60
|
+
itemPath: "",
|
61
|
+
// The css selector of the items
|
62
|
+
itemSelector: "li",
|
63
|
+
// Check if the dragged item may be inside the container.
|
64
|
+
// Use with care, since the search for a valid container entails a depth first search
|
65
|
+
// and may be quite expensive.
|
66
|
+
isValidTarget: function ($item, container) {
|
67
|
+
return true
|
68
|
+
},
|
69
|
+
// Executed before onDrop if placeholder is detached.
|
70
|
+
// This happens if pullPlaceholder is set to false and the drop occurs outside a container.
|
71
|
+
onCancel: function ($item, container, _super) {
|
72
|
+
},
|
73
|
+
// Executed at the beginning of a mouse move event.
|
74
|
+
// The Placeholder has not been moved yet.
|
75
|
+
onDrag: function ($item, position, _super) {
|
76
|
+
$item.css(position)
|
77
|
+
},
|
78
|
+
// Called after the drag has been started,
|
79
|
+
// that is the mouse button is beeing held down and
|
80
|
+
// the mouse is moving.
|
81
|
+
// The container is the closest initialized container.
|
82
|
+
// Therefore it might not be the container, that actually contains the item.
|
83
|
+
onDragStart: function ($item, container, _super) {
|
84
|
+
$item.css({
|
85
|
+
height: $item.height(),
|
86
|
+
width: $item.width()
|
87
|
+
})
|
88
|
+
$item.addClass("dragged")
|
89
|
+
$("body").addClass("dragging")
|
90
|
+
},
|
91
|
+
// Called when the mouse button is beeing released
|
92
|
+
onDrop: function ($item, container, _super) {
|
93
|
+
$item.removeClass("dragged").removeAttr("style")
|
94
|
+
$("body").removeClass("dragging")
|
95
|
+
},
|
96
|
+
// Called on mousedown.
|
97
|
+
onMousedown: function($item, event, _super) {
|
98
|
+
event.preventDefault()
|
99
|
+
},
|
100
|
+
// Template for the placeholder. Can be any valid jQuery input
|
101
|
+
// e.g. a string, a DOM element.
|
102
|
+
// The placeholder must have the class "placeholder"
|
103
|
+
placeholder: '<li class="placeholder"/>',
|
104
|
+
// If true, the position of the placeholder is calculated on every mousemove.
|
105
|
+
// If false, it is only calculated when the mouse is above a container.
|
106
|
+
pullPlaceholder: true,
|
107
|
+
// Specifies serialization of the container group.
|
108
|
+
// The pair $parent/$children is either container/items or item/subcontainers.
|
109
|
+
// Note that this default method only works, if every item only has one subcontainer
|
110
|
+
serialize: function ($parent, $children, parentIsContainer) {
|
111
|
+
var result = $.extend({}, $parent.data())
|
112
|
+
|
113
|
+
if(parentIsContainer)
|
114
|
+
return $children
|
115
|
+
else if ($children[0]){
|
116
|
+
result.children = $children
|
117
|
+
delete result.subContainer
|
118
|
+
}
|
119
|
+
|
120
|
+
delete result.sortable
|
121
|
+
|
122
|
+
return result
|
123
|
+
},
|
124
|
+
// Set tolerance while dragging. Positive values decrease sensitivity,
|
125
|
+
// negative values increase it.
|
126
|
+
tolerance: 0
|
127
|
+
}, // end group defaults
|
128
|
+
containerGroups = {},
|
129
|
+
groupCounter = 0,
|
130
|
+
emptyBox = {
|
131
|
+
left: 0,
|
132
|
+
top: 0,
|
133
|
+
bottom: 0,
|
134
|
+
right:0
|
135
|
+
}
|
136
|
+
eventNames = {
|
137
|
+
start: "touchstart.sortable mousedown.sortable",
|
138
|
+
drop: "touchend.sortable touchcancel.sortable mouseup.sortable",
|
139
|
+
drag: "touchmove.sortable mousemove.sortable",
|
140
|
+
scroll: "scroll.sortable"
|
141
|
+
}
|
142
|
+
|
143
|
+
/*
|
144
|
+
* a is Array [left, right, top, bottom]
|
145
|
+
* b is array [left, top]
|
146
|
+
*/
|
147
|
+
function d(a,b) {
|
148
|
+
var x = Math.max(0, a[0] - b[0], b[0] - a[1]),
|
149
|
+
y = Math.max(0, a[2] - b[1], b[1] - a[3])
|
150
|
+
return x+y;
|
151
|
+
}
|
152
|
+
|
153
|
+
function setDimensions(array, dimensions, tolerance, useOffset) {
|
154
|
+
var i = array.length,
|
155
|
+
offsetMethod = useOffset ? "offset" : "position"
|
156
|
+
tolerance = tolerance || 0
|
157
|
+
|
158
|
+
while(i--){
|
159
|
+
var el = array[i].el ? array[i].el : $(array[i]),
|
160
|
+
// use fitting method
|
161
|
+
pos = el[offsetMethod]()
|
162
|
+
pos.left += parseInt(el.css('margin-left'), 10)
|
163
|
+
pos.top += parseInt(el.css('margin-top'),10)
|
164
|
+
dimensions[i] = [
|
165
|
+
pos.left - tolerance,
|
166
|
+
pos.left + el.outerWidth() + tolerance,
|
167
|
+
pos.top - tolerance,
|
168
|
+
pos.top + el.outerHeight() + tolerance
|
169
|
+
]
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
function getRelativePosition(pointer, element) {
|
174
|
+
var offset = element.offset()
|
175
|
+
return {
|
176
|
+
left: pointer.left - offset.left,
|
177
|
+
top: pointer.top - offset.top
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
function sortByDistanceDesc(dimensions, pointer, lastPointer) {
|
182
|
+
pointer = [pointer.left, pointer.top]
|
183
|
+
lastPointer = lastPointer && [lastPointer.left, lastPointer.top]
|
184
|
+
|
185
|
+
var dim,
|
186
|
+
i = dimensions.length,
|
187
|
+
distances = []
|
188
|
+
|
189
|
+
while(i--){
|
190
|
+
dim = dimensions[i]
|
191
|
+
distances[i] = [i,d(dim,pointer), lastPointer && d(dim, lastPointer)]
|
192
|
+
}
|
193
|
+
distances = distances.sort(function (a,b) {
|
194
|
+
return b[1] - a[1] || b[2] - a[2] || b[0] - a[0]
|
195
|
+
})
|
196
|
+
|
197
|
+
// last entry is the closest
|
198
|
+
return distances
|
199
|
+
}
|
200
|
+
|
201
|
+
function ContainerGroup(options) {
|
202
|
+
this.options = $.extend({}, groupDefaults, options)
|
203
|
+
this.containers = []
|
204
|
+
this.scrollProxy = $.proxy(this.scroll, this)
|
205
|
+
this.dragProxy = $.proxy(this.drag, this)
|
206
|
+
this.dropProxy = $.proxy(this.drop, this)
|
207
|
+
|
208
|
+
if(!this.options.parentContainer){
|
209
|
+
this.placeholder = $(this.options.placeholder)
|
210
|
+
if(!options.isValidTarget)
|
211
|
+
this.options.isValidTarget = undefined
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
ContainerGroup.get = function (options) {
|
216
|
+
if( !containerGroups[options.group]) {
|
217
|
+
if(!options.group)
|
218
|
+
options.group = groupCounter ++
|
219
|
+
containerGroups[options.group] = new ContainerGroup(options)
|
220
|
+
}
|
221
|
+
return containerGroups[options.group]
|
222
|
+
}
|
223
|
+
|
224
|
+
ContainerGroup.prototype = {
|
225
|
+
dragInit: function (e, itemContainer) {
|
226
|
+
this.$document = $(itemContainer.el[0].ownerDocument)
|
227
|
+
|
228
|
+
if(itemContainer.enabled()){
|
229
|
+
this.toggleListeners('on')
|
230
|
+
|
231
|
+
// get item to drag
|
232
|
+
this.item = $(e.target).closest(this.options.itemSelector)
|
233
|
+
this.itemContainer = itemContainer
|
234
|
+
|
235
|
+
this.setPointer(e)
|
236
|
+
|
237
|
+
this.options.onMousedown(this.item, e, groupDefaults.onMousedown)
|
238
|
+
} else {
|
239
|
+
this.toggleListeners('on', ['drop'])
|
240
|
+
}
|
241
|
+
|
242
|
+
this.dragInitDone = true
|
243
|
+
},
|
244
|
+
drag: function (e) {
|
245
|
+
if(!this.dragging){
|
246
|
+
if(!this.distanceMet(e))
|
247
|
+
return
|
248
|
+
|
249
|
+
this.options.onDragStart(this.item, this.itemContainer, groupDefaults.onDragStart)
|
250
|
+
this.item.before(this.placeholder)
|
251
|
+
this.dragging = true
|
252
|
+
}
|
253
|
+
|
254
|
+
this.setPointer(e)
|
255
|
+
// place item under the cursor
|
256
|
+
this.options.onDrag(this.item,
|
257
|
+
getRelativePosition(this.pointer, this.item.offsetParent()),
|
258
|
+
groupDefaults.onDrag)
|
259
|
+
|
260
|
+
var x = e.pageX,
|
261
|
+
y = e.pageY,
|
262
|
+
box = this.sameResultBox,
|
263
|
+
t = this.options.tolerance
|
264
|
+
|
265
|
+
if(!box || box.top - t > y || box.bottom + t < y || box.left - t > x || box.right + t < x)
|
266
|
+
if(!this.searchValidTarget())
|
267
|
+
this.placeholder.detach()
|
268
|
+
},
|
269
|
+
drop: function (e) {
|
270
|
+
this.toggleListeners('off')
|
271
|
+
|
272
|
+
this.dragInitDone = false
|
273
|
+
|
274
|
+
if(this.dragging){
|
275
|
+
// processing Drop, check if placeholder is detached
|
276
|
+
if(this.placeholder.closest("html")[0])
|
277
|
+
this.placeholder.before(this.item).detach()
|
278
|
+
else
|
279
|
+
this.options.onCancel(this.item, this.itemContainer, groupDefaults.onCancel)
|
280
|
+
|
281
|
+
this.options.onDrop(this.item, this.getContainer(this.item), groupDefaults.onDrop)
|
282
|
+
|
283
|
+
// cleanup
|
284
|
+
this.clearDimensions()
|
285
|
+
this.clearOffsetParent()
|
286
|
+
this.lastAppendedItem = this.sameResultBox = undefined
|
287
|
+
this.dragging = false
|
288
|
+
}
|
289
|
+
},
|
290
|
+
searchValidTarget: function (pointer, lastPointer) {
|
291
|
+
if(!pointer){
|
292
|
+
pointer = this.relativePointer || this.pointer
|
293
|
+
lastPointer = this.lastRelativePointer || this.lastPointer
|
294
|
+
}
|
295
|
+
|
296
|
+
var distances = sortByDistanceDesc(this.getContainerDimensions(),
|
297
|
+
pointer,
|
298
|
+
lastPointer),
|
299
|
+
i = distances.length
|
300
|
+
|
301
|
+
while(i--){
|
302
|
+
var index = distances[i][0],
|
303
|
+
distance = distances[i][1]
|
304
|
+
|
305
|
+
if(!distance || this.options.pullPlaceholder){
|
306
|
+
var container = this.containers[index]
|
307
|
+
if(!container.disabled){
|
308
|
+
if(!this.$getOffsetParent()){
|
309
|
+
var offsetParent = container.getItemOffsetParent()
|
310
|
+
pointer = getRelativePosition(pointer, offsetParent)
|
311
|
+
lastPointer = getRelativePosition(lastPointer, offsetParent)
|
312
|
+
}
|
313
|
+
if(container.searchValidTarget(pointer, lastPointer))
|
314
|
+
return true
|
315
|
+
}
|
316
|
+
}
|
317
|
+
}
|
318
|
+
if(this.sameResultBox)
|
319
|
+
this.sameResultBox = undefined
|
320
|
+
},
|
321
|
+
movePlaceholder: function (container, item, method, sameResultBox) {
|
322
|
+
var lastAppendedItem = this.lastAppendedItem
|
323
|
+
if(!sameResultBox && lastAppendedItem && lastAppendedItem[0] === item[0])
|
324
|
+
return;
|
325
|
+
|
326
|
+
item[method](this.placeholder)
|
327
|
+
this.lastAppendedItem = item
|
328
|
+
this.sameResultBox = sameResultBox
|
329
|
+
this.options.afterMove(this.placeholder, container)
|
330
|
+
},
|
331
|
+
getContainerDimensions: function () {
|
332
|
+
if(!this.containerDimensions)
|
333
|
+
setDimensions(this.containers, this.containerDimensions = [], this.options.tolerance, !this.$getOffsetParent())
|
334
|
+
return this.containerDimensions
|
335
|
+
},
|
336
|
+
getContainer: function (element) {
|
337
|
+
return element.closest(this.options.containerSelector).data(pluginName)
|
338
|
+
},
|
339
|
+
$getOffsetParent: function () {
|
340
|
+
if(this.offsetParent === undefined){
|
341
|
+
var i = this.containers.length - 1,
|
342
|
+
offsetParent = this.containers[i].getItemOffsetParent()
|
343
|
+
|
344
|
+
if(!this.options.parentContainer){
|
345
|
+
while(i--){
|
346
|
+
if(offsetParent[0] != this.containers[i].getItemOffsetParent()[0]){
|
347
|
+
// If every container has the same offset parent,
|
348
|
+
// use position() which is relative to this parent,
|
349
|
+
// otherwise use offset()
|
350
|
+
// compare #setDimensions
|
351
|
+
offsetParent = false
|
352
|
+
break;
|
353
|
+
}
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
this.offsetParent = offsetParent
|
358
|
+
}
|
359
|
+
return this.offsetParent
|
360
|
+
},
|
361
|
+
setPointer: function (e) {
|
362
|
+
var pointer = {
|
363
|
+
left: e.pageX,
|
364
|
+
top: e.pageY
|
365
|
+
}
|
366
|
+
|
367
|
+
if(this.$getOffsetParent()){
|
368
|
+
var relativePointer = getRelativePosition(pointer, this.$getOffsetParent())
|
369
|
+
this.lastRelativePointer = this.relativePointer
|
370
|
+
this.relativePointer = relativePointer
|
371
|
+
}
|
372
|
+
|
373
|
+
this.lastPointer = this.pointer
|
374
|
+
this.pointer = pointer
|
375
|
+
},
|
376
|
+
distanceMet: function (e) {
|
377
|
+
return (Math.max(
|
378
|
+
Math.abs(this.pointer.left - e.pageX),
|
379
|
+
Math.abs(this.pointer.top - e.pageY)
|
380
|
+
) >= this.options.distance)
|
381
|
+
},
|
382
|
+
scroll: function (e) {
|
383
|
+
this.clearDimensions()
|
384
|
+
this.clearOffsetParent()
|
385
|
+
},
|
386
|
+
toggleListeners: function (method, events) {
|
387
|
+
var that = this
|
388
|
+
events = events || ['drag','drop','scroll']
|
389
|
+
|
390
|
+
$.each(events,function (i,event) {
|
391
|
+
that.$document[method](eventNames[event], that[event + 'Proxy'])
|
392
|
+
})
|
393
|
+
},
|
394
|
+
clearOffsetParent: function () {
|
395
|
+
this.offsetParent = undefined
|
396
|
+
},
|
397
|
+
// Recursively clear container and item dimensions
|
398
|
+
clearDimensions: function () {
|
399
|
+
this.containerDimensions = undefined
|
400
|
+
var i = this.containers.length
|
401
|
+
while(i--){
|
402
|
+
this.containers[i].clearDimensions()
|
403
|
+
}
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
function Container(element, options) {
|
408
|
+
this.el = element
|
409
|
+
this.options = $.extend( {}, containerDefaults, options)
|
410
|
+
|
411
|
+
this.group = ContainerGroup.get(this.options)
|
412
|
+
this.rootGroup = this.options.rootGroup = this.options.rootGroup || this.group
|
413
|
+
this.parentContainer = this.options.parentContainer
|
414
|
+
this.handle = this.rootGroup.options.handle || this.rootGroup.options.itemSelector
|
415
|
+
|
416
|
+
this.el.on(eventNames.start, this.handle, $.proxy(this.dragInit, this))
|
417
|
+
|
418
|
+
if(this.options.drop)
|
419
|
+
this.group.containers.push(this)
|
420
|
+
}
|
421
|
+
|
422
|
+
Container.prototype = {
|
423
|
+
dragInit: function (e) {
|
424
|
+
var rootGroup = this.rootGroup
|
425
|
+
|
426
|
+
if( !rootGroup.dragInitDone &&
|
427
|
+
e.which === 1 &&
|
428
|
+
this.options.drag &&
|
429
|
+
!$(e.target).is(this.options.exclude))
|
430
|
+
rootGroup.dragInit(e, this)
|
431
|
+
},
|
432
|
+
searchValidTarget: function (pointer, lastPointer) {
|
433
|
+
var distances = sortByDistanceDesc(this.getItemDimensions(),
|
434
|
+
pointer,
|
435
|
+
lastPointer),
|
436
|
+
i = distances.length,
|
437
|
+
rootGroup = this.rootGroup,
|
438
|
+
validTarget = !rootGroup.options.isValidTarget ||
|
439
|
+
rootGroup.options.isValidTarget(rootGroup.item, this)
|
440
|
+
|
441
|
+
if(!i && validTarget){
|
442
|
+
rootGroup.movePlaceholder(this, this.el, "append")
|
443
|
+
return true
|
444
|
+
} else
|
445
|
+
while(i--){
|
446
|
+
var index = distances[i][0],
|
447
|
+
distance = distances[i][1]
|
448
|
+
if(!distance && this.hasChildGroup(index)){
|
449
|
+
var found = this.getContainerGroup(index).searchValidTarget(pointer, lastPointer)
|
450
|
+
if(found)
|
451
|
+
return true
|
452
|
+
}
|
453
|
+
else if(validTarget){
|
454
|
+
this.movePlaceholder(index, pointer)
|
455
|
+
return true
|
456
|
+
}
|
457
|
+
}
|
458
|
+
},
|
459
|
+
movePlaceholder: function (index, pointer) {
|
460
|
+
var item = $(this.items[index]),
|
461
|
+
dim = this.itemDimensions[index],
|
462
|
+
method = "after",
|
463
|
+
width = item.outerWidth(),
|
464
|
+
height = item.outerHeight(),
|
465
|
+
offset = item.offset(),
|
466
|
+
sameResultBox = {
|
467
|
+
left: offset.left,
|
468
|
+
right: offset.left + width,
|
469
|
+
top: offset.top,
|
470
|
+
bottom: offset.top + height
|
471
|
+
}
|
472
|
+
if(this.options.vertical){
|
473
|
+
var yCenter = (dim[2] + dim[3]) / 2,
|
474
|
+
inUpperHalf = pointer.top <= yCenter
|
475
|
+
if(inUpperHalf){
|
476
|
+
method = "before"
|
477
|
+
sameResultBox.bottom -= height / 2
|
478
|
+
} else
|
479
|
+
sameResultBox.top += height / 2
|
480
|
+
} else {
|
481
|
+
var xCenter = (dim[0] + dim[1]) / 2,
|
482
|
+
inLeftHalf = pointer.left <= xCenter
|
483
|
+
if(inLeftHalf){
|
484
|
+
method = "before"
|
485
|
+
sameResultBox.right -= width / 2
|
486
|
+
} else
|
487
|
+
sameResultBox.left += width / 2
|
488
|
+
}
|
489
|
+
if(this.hasChildGroup(index))
|
490
|
+
sameResultBox = emptyBox
|
491
|
+
this.rootGroup.movePlaceholder(this, item, method, sameResultBox)
|
492
|
+
},
|
493
|
+
getItemDimensions: function () {
|
494
|
+
if(!this.itemDimensions){
|
495
|
+
this.items = this.$getChildren(this.el, "item").filter(":not(.placeholder, .dragged)").get()
|
496
|
+
setDimensions(this.items, this.itemDimensions = [], this.options.tolerance)
|
497
|
+
}
|
498
|
+
return this.itemDimensions
|
499
|
+
},
|
500
|
+
getItemOffsetParent: function () {
|
501
|
+
var offsetParent,
|
502
|
+
el = this.el
|
503
|
+
// Since el might be empty we have to check el itself and
|
504
|
+
// can not do something like el.children().first().offsetParent()
|
505
|
+
if(el.css("position") === "relative" || el.css("position") === "absolute" || el.css("position") === "fixed")
|
506
|
+
offsetParent = el
|
507
|
+
else
|
508
|
+
offsetParent = el.offsetParent()
|
509
|
+
return offsetParent
|
510
|
+
},
|
511
|
+
hasChildGroup: function (index) {
|
512
|
+
return this.options.nested && this.getContainerGroup(index)
|
513
|
+
},
|
514
|
+
getContainerGroup: function (index) {
|
515
|
+
var childGroup = $.data(this.items[index], "subContainer")
|
516
|
+
if( childGroup === undefined){
|
517
|
+
var childContainers = this.$getChildren(this.items[index], "container")
|
518
|
+
childGroup = false
|
519
|
+
|
520
|
+
if(childContainers[0]){
|
521
|
+
var options = $.extend({}, this.options, {
|
522
|
+
parentContainer: this,
|
523
|
+
group: groupCounter ++
|
524
|
+
})
|
525
|
+
childGroup = childContainers[pluginName](options).data(pluginName).group
|
526
|
+
}
|
527
|
+
$.data(this.items[index], "subContainer", childGroup)
|
528
|
+
}
|
529
|
+
return childGroup
|
530
|
+
},
|
531
|
+
enabled: function () {
|
532
|
+
return !this.disabled && (!this.parentContainer || this.parentContainer.enabled())
|
533
|
+
},
|
534
|
+
$getChildren: function (parent, type) {
|
535
|
+
var options = this.rootGroup.options,
|
536
|
+
path = options[type + "Path"],
|
537
|
+
selector = options[type + "Selector"]
|
538
|
+
|
539
|
+
parent = $(parent)
|
540
|
+
if(path)
|
541
|
+
parent = parent.find(path)
|
542
|
+
|
543
|
+
return parent.children(selector)
|
544
|
+
},
|
545
|
+
_serialize: function (parent, isContainer) {
|
546
|
+
var that = this,
|
547
|
+
childType = isContainer ? "item" : "container",
|
548
|
+
|
549
|
+
children = this.$getChildren(parent, childType).not(this.options.exclude).map(function () {
|
550
|
+
return that._serialize($(this), !isContainer)
|
551
|
+
}).get()
|
552
|
+
|
553
|
+
return this.rootGroup.options.serialize(parent, children, isContainer)
|
554
|
+
},
|
555
|
+
clearDimensions: function () {
|
556
|
+
this.itemDimensions = undefined
|
557
|
+
if(this.items && this.items[0]){
|
558
|
+
var i = this.items.length
|
559
|
+
while(i--){
|
560
|
+
var group = $.data(this.items[i], "subContainer")
|
561
|
+
if(group)
|
562
|
+
group.clearDimensions()
|
563
|
+
}
|
564
|
+
}
|
565
|
+
}
|
566
|
+
}
|
567
|
+
|
568
|
+
var API = {
|
569
|
+
enable: function (ignoreChildren) {
|
570
|
+
this.disabled = false
|
571
|
+
},
|
572
|
+
disable: function (ignoreChildren) {
|
573
|
+
this.disabled = true
|
574
|
+
},
|
575
|
+
serialize: function () {
|
576
|
+
return this._serialize(this.el, true)
|
577
|
+
}
|
578
|
+
}
|
579
|
+
|
580
|
+
$.extend(Container.prototype, API)
|
581
|
+
|
582
|
+
/**
|
583
|
+
* jQuery API
|
584
|
+
*
|
585
|
+
* Parameters are
|
586
|
+
* either options on init
|
587
|
+
* or a method name followed by arguments to pass to the method
|
588
|
+
*/
|
589
|
+
$.fn[pluginName] = function(methodOrOptions) {
|
590
|
+
var args = Array.prototype.slice.call(arguments, 1)
|
591
|
+
|
592
|
+
return this.map(function(){
|
593
|
+
var $t = $(this),
|
594
|
+
object = $t.data(pluginName)
|
595
|
+
|
596
|
+
if(object && API[methodOrOptions])
|
597
|
+
return API[methodOrOptions].apply(object, args) || this
|
598
|
+
else if(!object && (methodOrOptions === undefined ||
|
599
|
+
typeof methodOrOptions === "object"))
|
600
|
+
$t.data(pluginName, new Container($t, methodOrOptions))
|
601
|
+
|
602
|
+
return this
|
603
|
+
});
|
604
|
+
};
|
605
|
+
|
606
|
+
}(jQuery, window)
|
607
|
+
;
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jquery-sortable-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.11
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vlad Gorodetsky
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDSDCCAjCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA1MQowCAYDVQQDDAF2MRMw
|
14
|
+
EQYKCZImiZPyLGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wHhcNMTMwNTIz
|
15
|
+
MjA0MTI3WhcNMTQwNTIzMjA0MTI3WjA1MQowCAYDVQQDDAF2MRMwEQYKCZImiZPy
|
16
|
+
LGQBGRYDZ29yMRIwEAYKCZImiZPyLGQBGRYCaW8wggEiMA0GCSqGSIb3DQEBAQUA
|
17
|
+
A4IBDwAwggEKAoIBAQCtb8+GfjqcYl6M4IhIGomKsGgWEC4mwTXIq/Yl+jJAdP7s
|
18
|
+
bdV3lWnZybUPKtdHSQIJcxbm8GZspTqSqDgsECI/laTyLj7Srqcbyivf/ov50Tg1
|
19
|
+
CxMtt8STA6wNmY0ljO4SK72Pr8uQwFZIgNHBB9LcvrpmRn/TWDXlcqaq0db6QJKk
|
20
|
+
jGOv74ukiQun+saqthpxwNN6wm0rj1GDulrDuMeeMj/XDgu0piNHhBtsgQ6KrN94
|
21
|
+
cs0XGgwKihL0LdqWiOG9L8tZKeksKk72EcTpvaw1EYUfJ/rAcC8l6SluN2+BDMA0
|
22
|
+
/4LU70O+wTwHcHv2HimtKdlcpS936qOez3lXUD+3AgMBAAGjYzBhMAkGA1UdEwQC
|
23
|
+
MAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSRvHatldjBIKT5agA2bnkfm4KUxTAT
|
24
|
+
BgNVHREEDDAKgQh2QGdvci5pbzATBgNVHRIEDDAKgQh2QGdvci5pbzANBgkqhkiG
|
25
|
+
9w0BAQUFAAOCAQEAmyGZCL6ISHS6UCkPAie1LZgyc+yS4ckMPtzBJtjODr5kfRTC
|
26
|
+
tLb9W4epJ9Aa2aGkKy/NL8MFS0BwTJmjSfufFDwFZlw0kI9aAvL4Nx9OHWNen9Dm
|
27
|
+
GtEWXXKpB0du12DBjfavJYl0QLcz18M0mtvug634t40H06GussO83uu7wHEvIPBP
|
28
|
+
Z5VMAbKvOmDgaP2I9XxZ2/lDmBKDZkVNqmqYiScw2CWsKxVPx3vhMGprTIz4O8y/
|
29
|
+
JCf887eMZl/8mEIeCLb+gH5sh5yJJpti2HTLnR4Q1QKWR/0T9tASoQPF3kL62n9+
|
30
|
+
m1B90+fEzJsBDQIAsnLPqxjivWbIIfZ7GeGZyA==
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2013-09-02 00:00:00.000000000 Z
|
33
|
+
dependencies:
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: railties
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- - <
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '5.0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '3.0'
|
51
|
+
- - <
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '5.0'
|
54
|
+
description: Sortable control for jQuery.
|
55
|
+
email:
|
56
|
+
- v@gor.io
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- .gitignore
|
62
|
+
- Gemfile
|
63
|
+
- LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- certs/bai.pem
|
67
|
+
- jqeury-sortable-rails.gemspec
|
68
|
+
- lib/jquery-sortable-rails.rb
|
69
|
+
- lib/jquery-sortable-rails/version.rb
|
70
|
+
- vendor/assets/javascripts/jquery.sortable.js
|
71
|
+
homepage: http://github.com/bai/jquery-sortable-rails
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.0.3
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Gemified jquery-sortable asset for Rails
|
95
|
+
test_files: []
|
metadata.gz.sig
ADDED