Showing posts with label drapdrop. Show all posts
Showing posts with label drapdrop. Show all posts

June 25, 2007

Scriptaculous 1.7.1 Beta 3 Repatched

Hi Everybody,

I added an attribute to "Sortable" so that you can turn off to show dropzone marker. (That is the original behaviour of the script.) Default of markDropZone attribute is true and you can turn it off by assigning false. (Thanks to Ben for asking for this attribute)

Example:
Sortable.create('Layer1',{tag:'div',dropOnEmpty: true, overlap:'horizontal',constraint:false, markDropZone:false});

Bugfix: I also got error in IE7 when you dont have margins and I think I solved it.

Also I realised the patch is not marking correctly when ghosting:true. So please do not use ghosting until I solve this problem.

You can find it here: http://tankut.googlepages.com/patched-scriptaculous-v2-1.7.1_beta3.zip

Waiting for your comments,
Tankut,

June 5, 2007

Scriptaculous 1.7.1_beta3 patched

You can find here:

http://tankut.googlepages.com/patched-scriptaculous-js-1.7.1_beta3.zip

Works with prototype 1.5.1 final release as it is included with scriptaculous.

But some previous bugs remains(look at test1.htm and test2.htm[thanks chamnap])

Hopefully I will fix these,
Tankut

May 2, 2007

Finally I patched 1.7.0 (revised)

Hi everybody,

I have been receiving comments for the patched 1.7.0 version. Finall, I patched it.:)

Bugfixed version is here: http://tankut.googlepages.com/patched1.1-scriptaculous-js-1.7.0.zip
First version is here: http://tankut.googlepages.com/patched-scriptaculous-js-1.7.0.zip

Any comments are welcome, (also please let me know if you are using this patch in your pages)

Tankut

January 15, 2007

Update for Scriptaculous 1.6.5

Finally I updated to new version of scriptaculous 1.6.5. Both 1.6.4 and 1.6.5 patched versions (including an example) can be downloaded from:

http://tankut.googlepages.com/home

Tankut

September 24, 2006

Scriptaculous Patch

If you are using scriptaculous script and its sortables for drag and drop in your web pages, you may realizied that you can have only an empty space where you will drop your dragging element. Here I will explain how you can have a div with a custom style so that you can a box that will mark where you will drop you element.

Here I am patching scriptaculous script 1.6.4 and I tested final script with FF 1.5 and IE 6. All the changes I will make is in the dragdrop.js that is coming with scriptaculous and I will modify Sortable class in the script.

Lets start with adding two new methods to Sortable class; createGuide and markEmptyPlace methods

createGuide : function (element) {
if(!Sortable._guide) {
Sortable._guide = $('_guide') || document.createElement('DIV');
Sortable._guide.style.position = 'relative';
Sortable._guide.style.width = '1px';
Sortable._guide.style.height = '0px';
Sortable._guide.style.cssFloat = 'left';
Sortable._guide.id = 'guide';

document.getElementsByTagName("body").item(0).appendChild(Sortable._guide);
}


This createGuide method will create a div with 0px height and 1 px width so that it wont be visible. I will insert this div before the real element that we are dragging. After inserting, I will calculate its absolute position and move my marker div (which I will create in markEmptyPlace method) there. Here is a trick that I am copying dragging elements margins which will affect absolute position. markEmptyPlace method looks like this:
markEmptyPlace: function(element) {

if(!Sortable._emptyPlaceMarker) {
Sortable._emptyPlaceMarker = $('emptyPlaceMarker') || document.createElement('DIV');
Element.hide(Sortable._emptyPlaceMarker);
Element.addClassName(Sortable._emptyPlaceMarker, 'emptyPlaceMarker');
Sortable._emptyPlaceMarker.style.position = 'absolute';
document.getElementsByTagName("body").item(0).appendChild(Sortable._emptyPlaceMarker);
}

var pos = Position.cumulativeOffset(Sortable._guide);
Sortable._emptyPlaceMarker.style.left = (pos[0] + 5)+ 'px';
Sortable._emptyPlaceMarker.style.top = (pos[1] + 5) + 'px';

var dim = {};
dim.width = (Element.getDimensions(element).width-5) + 'px';
dim.height = (Element.getDimensions(element).height-5) + 'px';
Sortable._emptyPlaceMarker.setStyle(dim);

var mg = Element.getStyle(element, 'margin');
if(mg && mg != '') {
Sortable._emptyPlaceMarker.setStyle({margin : mg});
} else {
Sortable._emptyPlaceMarker.setStyle({ margin : ''});
}

Element.show(Sortable._emptyPlaceMarker);
},
Here I am calculating marker div's position by using guide div's position. Than I am making the marker div's size equal to the dragging element's size. +5 and -5 in calculations are there so that I have a slightly smaller box. Also it is important that this div is attached to a css class named as 'emptyPlaceMarker' so you need to have such a css class defined. Here is my emptyPlaceMarker css:
.emptyPlaceMarker
{
border-right: red thin dashed;
border-top: red thin dashed;
border-left: red thin dashed;
border-bottom: red thin dashed;
background-color: Transparent;
}
So we have our methods ready for creating necessary divs. Now lets use them. In scriptaculous, there are two methods used while dragging: onHover and onEmptyHover. onHover is called when you are hovering on another draggable element and onEmptyHover is called when you are hovering over an empty place in droppable. These methods are inserting the dragging element into a droppable as a child. So I modified these methods so that I will insert my guide before the dragging element in the child list. Here are the modified onHover and onEmptyHover methods; (red lines are the lines that I added)
 onHover: function(element, dropon, overlap) {
if(Element.isParent(dropon, element)) return;

if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
return;
} else if(overlap>0.5) {
Sortable.mark(dropon, 'before');
if(dropon.previousSibling != element) {
var oldParentNode = element.parentNode;
element.style.visibility = "hidden"; // fix gecko rendering

Sortable.createGuide(element);
dropon.parentNode.insertBefore(element, dropon);
dropon.parentNode.insertBefore(Sortable._guide, element);
Sortable.markEmptyPlace(element);

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

Sortable.createGuide(element);
dropon.parentNode.insertBefore(element, nextElement);
dropon.parentNode.insertBefore(Sortable._guide, element);
Sortable.markEmptyPlace(element);

if(dropon.parentNode!=oldParentNode)
Sortable.options(oldParentNode).onChange(element);
Sortable.options(dropon.parentNode).onChange(element);
}
}
},

onEmptyHover: function(element, dropon, overlap) {
var oldParentNode = element.parentNode;
var droponOptions = Sortable.options(dropon);

if(!Element.isParent(dropon, element)) {
var index;

var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
var child = null;

if(children) {
var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);

for (index = 0; index < children.length; index += 1) {
if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
offset -= Element.offsetSize (children[index], droponOptions.overlap);
} else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
child = index + 1 < children.length ? children[index + 1] : null;
break;
} else {
child = children[index];
break;
}
}
}
Sortable.createGuide(element);
dropon.insertBefore(element, child);
dropon.insertBefore(Sortable._guide, element);
Sortable.markEmptyPlace(element);

Sortable.options(oldParentNode).onChange(element);
droponOptions.onChange(element);
}
},

As a final touch, I updated the unmark method so that after dragging ends, I will hide the marker and remove the guide from droppables child list:
unmark: function() {
if(Sortable._marker) Element.hide(Sortable._marker);
if(Sortable._guide && Sortable._guide.parentNode){
Sortable._guide.parentNode.removeChild(Sortable._guide);
}
if(Sortable._emptyPlaceMarker) Element.hide(Sortable._emptyPlaceMarker);

},
After making these changes to your dragdrop.js and have a 'emptyPlaceMarker' css class defined, you will be able to have a box that will mark where you will drop your dragging element.

Tankut Koray