aboutsummaryrefslogtreecommitdiffstats
path: root/railties/html/javascripts/dragdrop.js
diff options
context:
space:
mode:
authorThomas Fuchs <thomas@fesch.at>2005-09-28 08:20:47 +0000
committerThomas Fuchs <thomas@fesch.at>2005-09-28 08:20:47 +0000
commit516dc2c0f16cf187f981b5e8648a7f7f1b31d190 (patch)
treed645e19a02ab5eb371302fe4742b7fd7e0a1a1e2 /railties/html/javascripts/dragdrop.js
parentdd21e9ae39a2dc4b7eb607ff2c200c864fa19b28 (diff)
downloadrails-516dc2c0f16cf187f981b5e8648a7f7f1b31d190.tar.gz
rails-516dc2c0f16cf187f981b5e8648a7f7f1b31d190.tar.bz2
rails-516dc2c0f16cf187f981b5e8648a7f7f1b31d190.zip
Update script.aculo.us to 1.5_rc2, and Prototype to 1.4.0_pre7
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2386 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'railties/html/javascripts/dragdrop.js')
-rw-r--r--railties/html/javascripts/dragdrop.js509
1 files changed, 238 insertions, 271 deletions
diff --git a/railties/html/javascripts/dragdrop.js b/railties/html/javascripts/dragdrop.js
index c0fd1d1e53..a8ed953a7f 100644
--- a/railties/html/javascripts/dragdrop.js
+++ b/railties/html/javascripts/dragdrop.js
@@ -2,193 +2,79 @@
//
// Element.Class part Copyright (c) 2005 by Rick Olson
//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Element.Class = {
- // Element.toggleClass(element, className) toggles the class being on/off
- // Element.toggleClass(element, className1, className2) toggles between both classes,
- // defaulting to className1 if neither exist
- toggle: function(element, className) {
- if(Element.Class.has(element, className)) {
- Element.Class.remove(element, className);
- if(arguments.length == 3) Element.Class.add(element, arguments[2]);
- } else {
- Element.Class.add(element, className);
- if(arguments.length == 3) Element.Class.remove(element, arguments[2]);
- }
- },
-
- // gets space-delimited classnames of an element as an array
- get: function(element) {
- element = $(element);
- return element.className.split(' ');
- },
-
- // functions adapted from original functions by Gavin Kistner
- remove: function(element) {
- element = $(element);
- var regEx;
- for(var i = 1; i < arguments.length; i++) {
- regEx = new RegExp("^" + arguments[i] + "\\b\\s*|\\s*\\b" + arguments[i] + "\\b", 'g');
- element.className = element.className.replace(regEx, '')
- }
- },
-
- add: function(element) {
- element = $(element);
- for(var i = 1; i < arguments.length; i++) {
- Element.Class.remove(element, arguments[i]);
- element.className += (element.className.length > 0 ? ' ' : '') + arguments[i];
- }
- },
-
- // returns true if all given classes exist in said element
- has: function(element) {
- element = $(element);
- if(!element || !element.className) return false;
- var regEx;
- for(var i = 1; i < arguments.length; i++) {
- regEx = new RegExp("\\b" + arguments[i] + "\\b");
- if(!regEx.test(element.className)) return false;
- }
- return true;
- },
-
- // expects arrays of strings and/or strings as optional paramters
- // Element.Class.has_any(element, ['classA','classB','classC'], 'classD')
- has_any: function(element) {
- element = $(element);
- if(!element || !element.className) return false;
- var regEx;
- for(var i = 1; i < arguments.length; i++) {
- if((typeof arguments[i] == 'object') &&
- (arguments[i].constructor == Array)) {
- for(var j = 0; j < arguments[i].length; j++) {
- regEx = new RegExp("\\b" + arguments[i][j] + "\\b");
- if(regEx.test(element.className)) return true;
- }
- } else {
- regEx = new RegExp("\\b" + arguments[i] + "\\b");
- if(regEx.test(element.className)) return true;
- }
- }
- return false;
- },
-
- childrenWith: function(element, className) {
- var children = $(element).getElementsByTagName('*');
- var elements = new Array();
-
- for (var i = 0; i < children.length; i++) {
- if (Element.Class.has(children[i], className)) {
- elements.push(children[i]);
- break;
- }
- }
-
- return elements;
- }
-}
+// See scriptaculous.js for full license.
/*--------------------------------------------------------------------------*/
var Droppables = {
- drops: false,
-
+ drops: [],
+
remove: function(element) {
- for(var i = 0; i < this.drops.length; i++)
- if(this.drops[i].element == element)
- this.drops.splice(i,1);
+ this.drops = this.drops.reject(function(e) { return e==element });
},
-
+
add: function(element) {
- var element = $(element);
+ element = $(element);
var options = Object.extend({
greedy: true,
hoverclass: null
}, arguments[1] || {});
-
+
// cache containers
if(options.containment) {
- options._containers = new Array();
+ options._containers = [];
var containment = options.containment;
if((typeof containment == 'object') &&
(containment.constructor == Array)) {
- for(var i=0; i<containment.length; i++)
- options._containers.push($(containment[i]));
+ containment.each( function(c) { options._containers.push($(c)) });
} else {
options._containers.push($(containment));
}
- options._containers_length =
- options._containers.length-1;
}
-
+
Element.makePositioned(element); // fix IE
-
options.element = element;
-
- // activate the droppable
- if(!this.drops) this.drops = [];
+
this.drops.push(options);
},
-
- is_contained: function(element, drop) {
- var containers = drop._containers;
+
+ isContained: function(element, drop) {
var parentNode = element.parentNode;
- var i = drop._containers_length;
- do { if(parentNode==containers[i]) return true; } while (i--);
- return false;
+ return drop._containers.detect(function(c) { return parentNode == c });
},
-
- is_affected: function(pX, pY, element, drop) {
+
+ isAffected: function(pX, pY, element, drop) {
return (
(drop.element!=element) &&
((!drop._containers) ||
- this.is_contained(element, drop)) &&
+ this.isContained(element, drop)) &&
((!drop.accept) ||
(Element.Class.has_any(element, drop.accept))) &&
Position.within(drop.element, pX, pY) );
},
-
+
deactivate: function(drop) {
- Element.Class.remove(drop.element, drop.hoverclass);
+ if(drop.hoverclass)
+ Element.Class.remove(drop.element, drop.hoverclass);
this.last_active = null;
},
-
+
activate: function(drop) {
if(this.last_active) this.deactivate(this.last_active);
- if(drop.hoverclass) {
+ if(drop.hoverclass)
Element.Class.add(drop.element, drop.hoverclass);
- this.last_active = drop;
- }
+ this.last_active = drop;
},
-
+
show: function(event, element) {
- if(!this.drops) return;
+ if(!this.drops.length) return;
var pX = Event.pointerX(event);
var pY = Event.pointerY(event);
Position.prepare();
-
+
var i = this.drops.length-1; do {
var drop = this.drops[i];
- if(this.is_affected(pX, pY, element, drop)) {
+ if(this.isAffected(pX, pY, element, drop)) {
if(drop.onHover)
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
if(drop.greedy) {
@@ -197,43 +83,41 @@ var Droppables = {
}
}
} while (i--);
+
+ if(this.last_active) this.deactivate(this.last_active);
},
-
+
fire: function(event, element) {
if(!this.last_active) return;
Position.prepare();
-
- if (this.is_affected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))
+
+ if (this.isAffected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))
if (this.last_active.onDrop)
- this.last_active.onDrop(element, this.last_active);
-
+ this.last_active.onDrop(element, this.last_active.element);
},
-
+
reset: function() {
if(this.last_active)
this.deactivate(this.last_active);
}
}
-Draggables = {
- observers: new Array(),
+var Draggables = {
+ observers: [],
addObserver: function(observer) {
this.observers.push(observer);
},
removeObserver: function(element) { // element instead of obsever fixes mem leaks
- for(var i = 0; i < this.observers.length; i++)
- if(this.observers[i].element && (this.observers[i].element == element))
- this.observers.splice(i,1);
+ this.observers = this.observers.reject( function(o) { return o.element==element });
},
notify: function(eventName, draggable) { // 'onStart', 'onEnd'
- for(var i = 0; i < this.observers.length; i++)
- this.observers[i][eventName](draggable);
+ this.observers.invoke(eventName, draggable);
}
}
/*--------------------------------------------------------------------------*/
-Draggable = Class.create();
+var Draggable = Class.create();
Draggable.prototype = {
initialize: function(element) {
var options = Object.extend({
@@ -242,7 +126,8 @@ Draggable.prototype = {
new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7});
},
reverteffect: function(element, top_offset, left_offset) {
- new Effect.MoveBy(element, -top_offset, -left_offset, {duration:0.4});
+ var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
+ new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
},
endeffect: function(element) {
new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
@@ -250,12 +135,12 @@ Draggable.prototype = {
zindex: 1000,
revert: false
}, arguments[1] || {});
-
+
this.element = $(element);
this.handle = options.handle ? $(options.handle) : this.element;
-
- Element.makePositioned(this.element); // fix IE
-
+
+ Element.makePositioned(this.element); // fix IE
+
this.offsetX = 0;
this.offsetY = 0;
this.originalLeft = this.currentLeft();
@@ -263,27 +148,34 @@ Draggable.prototype = {
this.originalX = this.element.offsetLeft;
this.originalY = this.element.offsetTop;
this.originalZ = parseInt(this.element.style.zIndex || "0");
-
+
this.options = options;
-
+
this.active = false;
this.dragging = false;
-
+
this.eventMouseDown = this.startDrag.bindAsEventListener(this);
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.update.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
- Event.observe(this.handle, "mousedown", this.eventMouseDown);
+ this.registerEvents();
+ },
+ destroy: function() {
+ Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+ this.unregisterEvents();
+ },
+ registerEvents: function() {
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
+ Event.observe(this.handle, "mousedown", this.eventMouseDown);
},
- destroy: function() {
- Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
- Event.stopObserving(document, "mouseup", this.eventMouseUp);
- Event.stopObserving(document, "mousemove", this.eventMouseMove);
- Event.stopObserving(document, "keypress", this.eventKeypress);
+ unregisterEvents: function() {
+ //if(!this.active) return;
+ //Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ //Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ //Event.stopObserving(document, "keypress", this.eventKeypress);
},
currentLeft: function() {
return parseInt(this.element.style.left || '0');
@@ -293,27 +185,42 @@ Draggable.prototype = {
},
startDrag: function(event) {
if(Event.isLeftClick(event)) {
- this.active = true;
- var style = this.element.style;
- this.originalY = this.element.offsetTop - this.currentTop() - this.originalTop;
- this.originalX = this.element.offsetLeft - this.currentLeft() - this.originalLeft;
- this.offsetY = event.clientY - this.originalY - this.originalTop;
- this.offsetX = event.clientX - this.originalX - this.originalLeft;
+ // abort on form elements, fixes a Firefox issue
+ var src = Event.element(event);
+ if(src.tagName && (
+ src.tagName=='INPUT' ||
+ src.tagName=='SELECT' ||
+ src.tagName=='BUTTON' ||
+ src.tagName=='TEXTAREA')) return;
+ // this.registerEvents();
+ this.active = true;
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var offsets = Position.cumulativeOffset(this.element);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
Event.stop(event);
}
},
finishDrag: function(event, success) {
+ // this.unregisterEvents();
+
this.active = false;
this.dragging = false;
-
+
+ if(this.options.ghosting) {
+ Position.relativize(this.element);
+ Element.remove(this._clone);
+ this._clone = null;
+ }
+
if(success) Droppables.fire(event, this.element);
Draggables.notify('onEnd', this);
-
+
var revert = this.options.revert;
if(revert && typeof revert == 'function') revert = revert(this.element);
-
+
if(revert && this.options.reverteffect) {
this.options.reverteffect(this.element,
this.currentTop()-this.originalTop,
@@ -322,12 +229,13 @@ Draggable.prototype = {
this.originalLeft = this.currentLeft();
this.originalTop = this.currentTop();
}
-
+
this.element.style.zIndex = this.originalZ;
-
+
if(this.options.endeffect)
this.options.endeffect(this.element);
-
+
+
Droppables.reset();
},
keyPress: function(event) {
@@ -347,13 +255,15 @@ Draggable.prototype = {
this.dragging = false;
},
draw: function(event) {
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var offsets = Position.cumulativeOffset(this.element);
+ offsets[0] -= this.currentLeft();
+ offsets[1] -= this.currentTop();
var style = this.element.style;
- this.originalX = this.element.offsetLeft - this.currentLeft() - this.originalLeft;
- this.originalY = this.element.offsetTop - this.currentTop() - this.originalTop;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
- style.left = ((event.clientX - this.originalX) - this.offsetX) + "px";
+ style.left = (pointer[0] - offsets[0] - this.offsetX) + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
- style.top = ((event.clientY - this.originalY) - this.offsetY) + "px";
+ style.top = (pointer[1] - offsets[1] - this.offsetY) + "px";
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
},
update: function(event) {
@@ -363,17 +273,24 @@ Draggable.prototype = {
this.dragging = true;
if(style.position=="") style.position = "relative";
style.zIndex = this.options.zindex;
+
+ if(this.options.ghosting) {
+ this._clone = this.element.cloneNode(true);
+ Position.absolutize(this.element);
+ this.element.parentNode.insertBefore(this._clone, this.element);
+ }
+
Draggables.notify('onStart', this);
if(this.options.starteffect) this.options.starteffect(this.element);
}
-
+
Droppables.show(event, this.element);
this.draw(event);
if(this.options.change) this.options.change(this);
-
+
// fix AppleWebKit rendering
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
-
+
Event.stop(event);
}
}
@@ -381,7 +298,7 @@ Draggable.prototype = {
/*--------------------------------------------------------------------------*/
-SortableObserver = Class.create();
+var SortableObserver = Class.create();
SortableObserver.prototype = {
initialize: function(element, observer) {
this.element = $(element);
@@ -391,147 +308,197 @@ SortableObserver.prototype = {
onStart: function() {
this.lastValue = Sortable.serialize(this.element);
},
- onEnd: function() {
+ onEnd: function() {
+ Sortable.unmark();
if(this.lastValue != Sortable.serialize(this.element))
this.observer(this.element)
}
}
-Sortable = {
+var Sortable = {
sortables: new Array(),
options: function(element){
- var element = $(element);
- for(var i=0;i<this.sortables.length;i++)
- if(this.sortables[i].element == element)
- return this.sortables[i];
- return null;
+ element = $(element);
+ return this.sortables.detect(function(s) { return s.element == element });
},
destroy: function(element){
- var element = $(element);
- for(var i=0;i<this.sortables.length;i++) {
- if(this.sortables[i].element == element) {
- var s = this.sortables[i];
- Draggables.removeObserver(s.element);
- for(var j=0;j<s.droppables.length;j++)
- Droppables.remove(s.droppables[j]);
- for(var j=0;j<s.draggables.length;j++)
- s.draggables[j].destroy();
- this.sortables.splice(i,1);
- }
- }
+ element = $(element);
+ this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
+ Draggables.removeObserver(s.element);
+ s.droppables.each(function(d){ Droppables.remove(d) });
+ s.draggables.invoke('destroy');
+ });
+ this.sortables = this.sortables.reject(function(s) { return s.element == element });
},
create: function(element) {
- var element = $(element);
+ element = $(element);
var options = Object.extend({
element: element,
tag: 'li', // assumes li children, override with tag: 'tagname'
+ dropOnEmpty: false,
+ tree: false, // fixme: unimplemented
overlap: 'vertical', // one of 'vertical', 'horizontal'
constraint: 'vertical', // one of 'vertical', 'horizontal', false
containment: element, // also takes array of elements (or id's); or false
handle: false, // or a CSS class
only: false,
hoverclass: null,
+ ghosting: false,
onChange: function() {},
onUpdate: function() {}
}, arguments[1] || {});
-
+
// clear any old sortable with same element
this.destroy(element);
-
+
// build options for the draggables
var options_for_draggable = {
revert: true,
+ ghosting: options.ghosting,
constraint: options.constraint,
- handle: handle };
+ handle: options.handle };
+
if(options.starteffect)
options_for_draggable.starteffect = options.starteffect;
+
if(options.reverteffect)
options_for_draggable.reverteffect = options.reverteffect;
+ else
+ if(options.ghosting) options_for_draggable.reverteffect = function(element) {
+ element.style.top = 0;
+ element.style.left = 0;
+ };
+
if(options.endeffect)
options_for_draggable.endeffect = options.endeffect;
+
if(options.zindex)
options_for_draggable.zindex = options.zindex;
-
+
// build options for the droppables
var options_for_droppable = {
overlap: options.overlap,
containment: options.containment,
hoverclass: options.hoverclass,
- onHover: function(element, dropon, overlap) {
- if(overlap>0.5) {
- if(dropon.previousSibling != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, dropon);
- if(dropon.parentNode!=oldParentNode && oldParentNode.sortable)
- oldParentNode.sortable.onChange(element);
- if(dropon.parentNode.sortable)
- dropon.parentNode.sortable.onChange(element);
- }
- } else {
- var nextElement = dropon.nextSibling || null;
- if(nextElement != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = "hidden"; // fix gecko rendering
- dropon.parentNode.insertBefore(element, nextElement);
- if(dropon.parentNode!=oldParentNode && oldParentNode.sortable)
- oldParentNode.sortable.onChange(element);
- if(dropon.parentNode.sortable)
- dropon.parentNode.sortable.onChange(element);
- }
- }
- }
+ onHover: Sortable.onHover,
+ greedy: !options.dropOnEmpty
}
// fix for gecko engine
Element.cleanWhitespace(element);
-
+
options.draggables = [];
options.droppables = [];
-
- // make it so
- var elements = element.childNodes;
- for (var i = 0; i < elements.length; i++)
- if(elements[i].tagName && elements[i].tagName==options.tag.toUpperCase() &&
- (!options.only || (Element.Class.has(elements[i], options.only)))) {
-
- // handles are per-draggable
- var handle = options.handle ?
- Element.Class.childrenWith(elements[i], options.handle)[0] : elements[i];
-
- options.draggables.push(new Draggable(elements[i], Object.extend(options_for_draggable, { handle: handle })));
-
- Droppables.add(elements[i], options_for_droppable);
- options.droppables.push(elements[i]);
-
- }
-
+
+ // make it so
+
+ // drop on empty handling
+ if(options.dropOnEmpty) {
+ Droppables.add(element,
+ {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false});
+ options.droppables.push(element);
+ }
+
+ (this.findElements(element, options) || []).each( function(e) {
+ // handles are per-draggable
+ var handle = options.handle ?
+ Element.Class.childrenWith(e, options.handle)[0] : e;
+ options.draggables.push(
+ new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+ Droppables.add(e, options_for_droppable);
+ options.droppables.push(e);
+ });
+
// keep reference
this.sortables.push(options);
-
+
// for onupdate
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
},
+
+ // return all suitable-for-sortable elements in a guaranteed order
+ findElements: function(element, options) {
+ if(!element.hasChildNodes()) return null;
+ var elements = [];
+ $A(element.childNodes).each( function(e) {
+ if(e.tagName && e.tagName==options.tag.toUpperCase() &&
+ (!options.only || (Element.Class.has(e, options.only))))
+ elements.push(e);
+ if(options.tree) {
+ var grandchildren = this.findElements(e, options);
+ if(grandchildren) elements.push(grandchildren);
+ }
+ });
+
+ return (elements.length>0 ? elements.flatten() : null);
+ },
+
+ onHover: function(element, dropon, overlap) {
+ if(overlap>0.5) {
+ Sortable.mark(dropon, 'before');
+ if(dropon.previousSibling != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden"; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, dropon);
+ if(dropon.parentNode!=oldParentNode)
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ } else {
+ Sortable.mark(dropon, 'after');
+ var nextElement = dropon.nextSibling || null;
+ if(nextElement != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden"; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, nextElement);
+ if(dropon.parentNode!=oldParentNode)
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ }
+ },
+
+ onEmptyHover: function(element, dropon) {
+ if(element.parentNode!=dropon) {
+ dropon.appendChild(element);
+ }
+ },
+
+ unmark: function() {
+ if(Sortable._marker) Element.hide(Sortable._marker);
+ },
+
+ mark: function(dropon, position) {
+ // mark on ghosting only
+ var sortable = Sortable.options(dropon.parentNode);
+ if(sortable && !sortable.ghosting) return;
+
+ if(!Sortable._marker) {
+ Sortable._marker = $('dropmarker') || document.createElement('DIV');
+ Element.hide(Sortable._marker);
+ Element.Class.add(Sortable._marker, 'dropmarker');
+ Sortable._marker.style.position = 'absolute';
+ document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+ }
+ var offsets = Position.cumulativeOffset(dropon);
+ Sortable._marker.style.top = offsets[1] + 'px';
+ if(position=='after') Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
+ Sortable._marker.style.left = offsets[0] + 'px';
+ Element.show(Sortable._marker);
+ },
+
serialize: function(element) {
- var element = $(element);
+ element = $(element);
var sortableOptions = this.options(element);
var options = Object.extend({
tag: sortableOptions.tag,
only: sortableOptions.only,
name: element.id
}, arguments[1] || {});
-
- var items = $(element).childNodes;
- var queryComponents = new Array();
-
- for(var i=0; i<items.length; i++)
- if(items[i].tagName && items[i].tagName==options.tag.toUpperCase() &&
- (!options.only || (Element.Class.has(items[i], options.only))))
- queryComponents.push(
- encodeURIComponent(options.name) + "[]=" +
- encodeURIComponent(items[i].id.split("_")[1]));
-
- return queryComponents.join("&");
+ return $A(element.childNodes).collect( function(item) {
+ return (encodeURIComponent(options.name) + "[]=" +
+ encodeURIComponent(item.id.split("_")[1]));
+ }).join("&");
}
-} \ No newline at end of file
+} \ No newline at end of file