mmofacts.com

Kann man einen jQuery drop abbrechen?

gepostet vor 14 Jahre, 9 Monate von Jackflash

ich würde gerne einen drop mittels Ajax überprüfen. Ich bekomme dann true oder false... kann ich jetzt den Drop von jQuery rückgängig machen? Also das Drag Element soll einen revert bekommen.

Z.B.:

drop: function() {
zugelassen = ajaxtest($(this));
if (zugelassen == false){
  Mach bitte, dass das Drag Element reverted wird.
}
}

Hintergrund ist unter anderem, olgendes Problem: http://www.jquerytest.at.tf/2/sc-test.php
Wie in diesem Beispeil sollen die "Spieler" auf ihren "Platz" gedroppt werden. Ist ein Spieler auf dem Platz, wird mit:

drop: function() {
$(this).droppable('disable');
}

dafür gesorgt, dass nicht noch ein Spieler auf den selben Platz gedroppt werden kann. So, jetzt soll aber auch, wenn ein Spieler wieder aus seinem Platz entfernt wird das Element wieder aktiviert werden.

out: function() {
$(this).droppable('enable');
}

leider funktioniert das nicht, ich denke mal, weil das Element schon dissablet wurde, springt das "out:" nicht mehr an. Da aber die Plätze sowieso mit Ajax validiert werden, dachte ich jetzt an die Lösung mit dem Abbruch des draggens.

Gruß, Sam.

gepostet vor 14 Jahre, 9 Monate von Jackflash

Hi, danke für deine Tipps.

Leider tritt das Stop-Event erst nach dem revert ein. Ich muss also bei drop: etwas machen. In Deinem verlinkten Beispiel, wird ja einfach der geclonte Helper ausgeblendet, dass hilft leider nicht weiter, da er ja unsichtbar trotzdem zurück fährt. Außerdem ist dann ja mein Spieler "verschwunden".

Ich bin drauf und dran das wieder mit Scriptaculous zu machen, damit habe ich das ganze schon fertig. Ich wollte nur auf jQuery umsteigen da es dafür mittlerweile einfach mehr gibt. Aber zwei Frameworks laufen lassen ist eigentlich scheiße.

gepostet vor 14 Jahre, 9 Monate von altertoby

ich hatte das so verstanden:

Du hast einen freien Platz. Wenn der User einen Spieler dahin droped (dh. er ihn da auch wirklich platzieren möchte) willst du per Ajax überprüfen, ob der Platz wirklich belegbar ist...wenn er dies nicht ist, soll der Spieler wieder zu seinem Ausgangspunkt "reverted" werden. Und das sollte mit

JavaScript:

stop: function() {
zugelassen = ajaxtest($(this));
if (zugelassen == false){
  return false;
}
}

soweit eigentlich funktionieren (das Event gibts im Draggable nicht im Dropable).

Dein Problem mit dem revert enable/disable konnte ich nicht ganz nachvollziehen (und dachte, dass es nur ein Workaround-Versuch von dir war, der so nicht ganz funktioniert hat).

(Aber vllt. hilft da auch ein verwenden von start und stop des Draggables anstatt das drop-Event im Dropable)

Oder noch eine ganz andere Idee:

Die Plätze von den Spielern sind dropable und auch die Bank. Wenn ein Spieler wieder auf die Bank gesetzt wird, musst du in dessen drop-Event nur noch den vorherigen Platz freigeben. Mit dem automatischen "revert" ist auch dann auch wirklich nur ein Wechsel zwischen Bank und Platz möglich.

gepostet vor 14 Jahre, 9 Monate von Jackflash

Hi, danke. Ja, Du hast das absolut korrekt verstanden.

JavaScript:

stop: function() {
zugelassen = ajaxtest($(this));
if (zugelassen == false){
  return false;
}
}

Macht leider keinen revert, wenn ich das Draggable revert: 'invalid' gesetzt habe.

Wenn ein Spieler wieder auf die Bank gesetzt wird, musst du in dessen drop-Event nur noch den vorherigen Platz freigeben.

Stimmt, hatte ich anfangs auch so vor. Dann habe ich mir aber gedacht, dass die Spieler -also die vor dem PC- ja immer alles ausprobieren um zu bescheissen. Drum dachte ich, ich überprüfe sowieso alles mit Ajax in der Db, also brauch ich eigentlich nur noch etwas, dass mir den Drop abbricht.

Allerdings habe ich jetzt auch nach endlosem herumprobiere eine Lösung gefunden: http://groups.google.com/group/threedubmedia Die haben "jquery.event.drag.js" dort gibt es das Event "dropstart, drop, dropend" da funktioniert dann der Abbruch. Sind zwar nochmal 3kb mehr Code, aber das ist mir jetzt egal. 5 Stunden für so einen Popelkram vergeudet wo doch noch Klausuren anstehen.  ;-)

gepostet vor 14 Jahre, 9 Monate von Phoscur

Original von Jackflash

JavaScript:

zugelassen = ajaxtest($(this));

Wie bekommst du einen Rückgabewert aus einer Ajax-Abfrage? Syncron? Buggt das nicht stark herum?

gepostet vor 14 Jahre, 9 Monate von knalli

Synchrone Requests buggen nicht rum - sie sind halt nur synchron. Mit allen Nachteilen. Eine Synchrone Validierung einer Drag-and-Drop kann aber quasi nur in der Idealwelt in Sekundenbruchteilen (immer) funktionieren, will heißen: Das dauert und sieht dann buggy aus.

Ich denke, da gibt es nur 2 Möglichkeiten: 

a) Drag-and-Drop ausführen, Validieren und im Zweifelsfall die Aktion rückgängig machen (Animation rückgängig?) - vor allem, wenn die Wahrscheinlichkeit gering ist, dass es ungültig ist

b) Drag-and-Drop nur vormerken (bspw. mit Rahmen, etc., vgl. Windows Fenster minimieren/maximieren ohne Inhalt), Validieren und erst im Erfolgsfall auch ausführen - vor allem, wenn die Wahrscheinlichkeit groß ist bzw. es sehr wichtig ist

gepostet vor 14 Jahre, 9 Monate von Phoscur

Original von knalli

Synchrone Requests buggen nicht rum - sie sind halt nur synchron. Mit allen Nachteilen. Eine Synchrone Validierung einer Drag-and-Drop kann aber quasi nur in der Idealwelt in Sekundenbruchteilen (immer) funktionieren, will heißen: Das dauert und sieht dann buggy aus.

In wieweit unterscheidet sich diese Aussage jetzt von meiner, bis auf das du mehr ausfomuliert hast? Ich hatte auf Feedback gewartet bis ich mögliche Lösungen ausgepackt hätte. Gut, was besseres wie dir wäre mir auch nicht eingefallen.

gepostet vor 14 Jahre, 9 Monate von knalli

Original von Phoscur

Original von knalli

Synchrone Requests buggen nicht rum - sie sind halt nur synchron. Mit allen Nachteilen. Eine Synchrone Validierung einer Drag-and-Drop kann aber quasi nur in der Idealwelt in Sekundenbruchteilen (immer) funktionieren, will heißen: Das dauert und sieht dann buggy aus.

In wieweit unterscheidet sich diese Aussage jetzt von meiner, bis auf das du mehr ausfomuliert hast? Ich hatte auf Feedback gewartet bis ich mögliche Lösungen ausgepackt hätte. Gut, was besseres wie dir wäre mir auch nicht eingefallen.

Genau das. :)

gepostet vor 14 Jahre, 9 Monate von buhrmi

Ich hab am meisten klukheit und was ihr alles schreibt weiß ich auch aber bin nur zu faul es auszuformulieren!!!1

So ähnlich wie das a) von knalli, aber schonmal auf Praxistauglichkeit geprüft:

Nach dem loslassen clientseitig alles so durchführen als hätte es geklappt, aber gleichzeitig ajax losschicken. Falls Validierung fehlschlägt, einfach komplette Seite neuladen. Sehr pragmatisch. In den Fällen in den davon auszugehen ist, dass die Validierung nur in Ausnahmefällen fehlschlägt, ist das eine einfache und angemessene Lösung. Weitere Möglichkeit wäre auch, anstatt die ganze Seite neuzuladen, eine "Rückgängigmach"-Animation abzuspielen (oder auch nicht) und den DOM korrigieren.

gepostet vor 14 Jahre, 9 Monate von MrMaxx

Solch eine Undo-Funktionalität wird oft mittels Command-Pattern realisiert. Oder einfacher formuliert: Wenn immer du eine Aktion (wie das Verschieben deiner Einheiten) machst erstellst du ein Objekt, das alle Informationen hat, um die Aktion auszuführen und auch wieder rückgängig zu machen. Auf diesem Objekt sind zwei Funktionen definiert: do() und undo().

Machst du eine Aktion, so erstellst du das Objekt, führst do() auf ihm aus und hängst es in deine History-Liste. Über diese History hast du dann durch rückwärtiges Aufrufen von undo() (und evtl auch wieder vorwärtiges von do()) ein Multi-Level Undo/Redo. In deinem Fall reicht aber, so wie ich das verstanden habe ein einziger Level. Besonders ja auch daher, da ja auf das CallBack des Ajax-Calls gewartet werden muss.

Das ist nur eine Möglichkeit....vielleicht auch etwas zu viel...und im Grunde genommen nur ausformuliert, was buhrmi angedeutet hat.

So long...

Maxx

gepostet vor 14 Jahre, 9 Monate von knalli

Original von MrMaxx

Solch eine Undo-Funktionalität wird oft mittels Command-Pattern realisiert. Oder einfacher formuliert: Wenn immer du eine Aktion (wie das Verschieben deiner Einheiten) machst erstellst du ein Objekt, das alle Informationen hat, um die Aktion auszuführen und auch wieder rückgängig zu machen. Auf diesem Objekt sind zwei Funktionen definiert: do() und undo().

Machst du eine Aktion, so erstellst du das Objekt, führst do() auf ihm aus und hängst es in deine History-Liste. Über diese History hast du dann durch rückwärtiges Aufrufen von undo() (und evtl auch wieder vorwärtiges von do()) ein Multi-Level Undo/Redo. In deinem Fall reicht aber, so wie ich das verstanden habe ein einziger Level. Besonders ja auch daher, da ja auf das CallBack des Ajax-Calls gewartet werden muss.

Das ist nur eine Möglichkeit....vielleicht auch etwas zu viel...und im Grunde genommen nur ausformuliert, was buhrmi angedeutet hat.

So long...

Maxx

Ja, auch wenn ich sowas natürlich genauso gern sehe und machen würde.. je nach Problemstellung ist das echt ein Beispiel für die Geschichte mit den Kanonen und Spatzen..

Ich meine: Insofern die Animation sofort starten soll, dann ist eh die Animation von der eigentlichen Logik/Datenhaltung komplett entkoppelt (im Sinne des Tasks)..

@buhrmi: Das klappt aber nur, wenn du mittels Ajax nur Würze in die Seite bringst. Eine komplette (RIA)-Seite will ich/man nicht neuladen ;)

gepostet vor 14 Jahre, 9 Monate von buhrmi

auch wieder wahr

gepostet vor 14 Jahre, 9 Monate von Jackflash

Zur Zeit dauert es im Schnitt 40ms bis die Antwort da ist, das erkennt man natürlich schon, wenn man weiß worauf man achten muss, allerdings glaub ich kaum das das einem Spieler aufgefallen währe. Aber, ihr habt schon recht. Ich lasse jetzt erst den Drop ausführen, mache dann die Ajax-Abfrage und falls der Drop falsch war, wird wieder zurück gesetzt.

Tausend dank für die Antworten.

gepostet vor 14 Jahre, 9 Monate von TheUndeadable

> Zur Zeit dauert es im Schnitt 40ms bis die Antwort da ist

Bei  mir allein durch das DSL-Interleaving mindestens 50 ms.... Zzgl Serverzeiten und anderen Späßen

Auf diese Diskussion antworten