Hi Red
I did this with a drag and drop calendar i've been writing.
Basically, you leave revert as false, and do your checks (in my case im
making sure the item is not being dropped on another) and if it is, i use
code adapted from the sortable code to do a manual revert to the 'last known
position'.
In that, every time a peice is moved, I update an X/Y on the item to say
where it is now, a valid position... then ondrop, I can move it back to that
position if the drop/move is invalid.
var dropAllowed = true;
//Perform checks to set dropAllowed to be false.
if (dropAllowed)
{
//Valid drop
var ContainerOffset = Position.cumulativeOffset($('Board'));
//hourEl is the 'square' the droppable got dropped on, Im not sure why I
need the +30s but it fixes a location bug I'm having
var newTop = parsePx(hourEl.style.top) + 30;
var newLeft = parsePx(hourEl.style.left) + 30;
//We create a 2 element array to store a position array for the current
position, more for readability below
var currentPos = [parseInt(Element.getStyle(draggable,'top')),parseInt(
Element.getStyle(draggable,'left'))]
//This makes the element 'snap' (its more of a slide) to the correct
position in the dropped square
revertEffect(draggable, currentPos[0]-newTop, currentPos[1]-newLeft);
//We've moved the item so update the property on the object to state where
it is now, used later for an invalid move
draggable.lastKnownPosition = [parseInt(newTop),parseInt(newLeft)]
} else {
//This is an invalid drop
//We create a 2 element array to store a position array for the
current position, more for readability below
var currentPos = [parseInt(Element.getStyle
(draggable,'top')),parseInt(Element.getStyle(draggable,'left'))]
//Retrieve last known pos
var lastKnownPos = draggable.lastKnownPosition;
//Move the element back to the last known valid location/square
revertEffect(draggable, currentPos[0]-lastKnownPos[0],
currentPos[1]-lastKnownPos[1]);
}
//This is as per dragdrop.js but moved to be a top level function not a
class method.
function revertEffect(element, top_offset, left_offset) {
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*
0.02;
new Effect.Move(element, { x: -left_offset, y: -top_offset,
duration: dur,
queue: {scope:'_draggable', position:'end'}
});
}
You may also want to store which square the item is on, as well as the X/Y
because you know what square it has been dropped on when it is a valid drop
and its more work to calculate its position every time.
This way you can retreive it for your local lookup/ajax call.
Hope this helps.
Gareth
On 7/6/07, Red <[EMAIL PROTECTED]> wrote:
> Well, I'd want the same kind of snapping action that scriptaculous drag
> and drop gives. I guess I could write a function that keeps calling itself
> to slowly move the piece back. Not sure if this is the way to go.
>
> And now that I think about it, here's the issue with creating a list of
> droppables for each piece. If I do that, the list for each piece has to be
> updated with each and every move. I guess it's just a little bit of text, so
> bandwidth wouldn't be that much of an issue. But, for example, when black
> moves a piece, I'd have to fire off a script to get white's latest
> draggables and vice versa. I guess it's not that bad, but I don't know. I
> guess if nothing else, I can go this route.
>
>
> On 7/5/07, Diodeus <[EMAIL PROTECTED]> wrote:
> >
> >
> > I believe revert=true has to be set before the dragging occurs.
> >
> > Why not just move the chess piece back to the square it came from
> > using a function if the move is illegal?
> >
> > On Jul 5, 3:44 pm, Red < [EMAIL PROTECTED]> wrote:
> > > Whether I do that or do it the way I'm doing it, it would still
> > require that
> > > I set revert to true or false depending on whether or not the move is
> > legal.
> > > So I'd have to set revert programatically. I know it can be done, but
> > I
> > > don't know how to do it.
> > >
> > > It shouldn't matter whether I use ajax to verify the move or store the
> > legal
> > > moves locally. The ajax verification happens pretty instantaneously.
> > The
> > > issue becomes making it either stay at revert=true or revert=false
> > depending
> > > on whether or not the move is legal. Because no matter what, I need
> > the
> > > piece to stay there for a sec or so while the verification function
> > checks
> > > to see if the move is legal regardless of whether or not it's checking
> >
> > > locally or using ajax.
> > >
> > > So I need it to basically go to revert=false (and center itself in the
> > > square, which is a div) if the move is legal and revert if the move is
> > > false. I'm not even sure if this is possible, unless I come up with
> > > something custom.
> > >
> > > Thanks for the response.
> > >
> > > On 7/5/07, Jon Trelfa <[EMAIL PROTECTED]> wrote:
> > >
> > >
> > >
> > > > On 7/5/07, Red < [EMAIL PROTECTED]> wrote:
> > > > > I can't figure out an intelligent way to do this. If I set revert
> > to
> > > > true,
> > > > > it will snap back to it's original position when I want it to stay
> > at
> > > > the
> > > > > square while checking to see if the move is legit. If I set revert
> > to
> > > > false
> > > > > and the move is illegal, it's not going to know where to snap back
> > to.
> > >
> > > > > Anybody have any ideas how to go about this? Thanks in advance.
> > >
> > > > How about pre-fetching your legal moves for the piece using the XHR
> > call?
> > > > Then you can validate the move against a local set of data. For
> > example:
> > >
> > > > In a grid where the rows are numbered and the columns are lettered,
> > > > we'll say a pawn is in square 4A
> > > > The pre-fetch for that piece says that it can only legally move to
> > > > square 5A (if there were an opponent's piece in 5B, that square
> > would
> > > > also be returned)
> > > > The user moves the piece forward 1 square (legally) to square 5A (If
> > > > they tried 6A, the event would return false and snap the piece
> > back.)
> > > > If the ondrop event says it's "OK" for that piece, you fire off an
> > XHR
> > > > to get the next list of legal moves for that piece
> > >
> > > > I'm sure it will get more complicated with regards to taking another
> >
> > > > person's piece, etc - but using Ajax before the person actually has
> > to
> > > > make the move would be more sensible rather than making the person
> > > > wait for the response for each move.
> > >
> > > > You could then maintain an object with 32 (16 black, 16 white)
> > > > elements with arrays of "legal" moves.
> > >
> > > > My two cents :)
> > >
> > > > Jon
> >
> >
> > > >
> >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---