Sorozatunk harmadik részében a scriptaculous drag and drop moduljával fogunk megismerkedni melynek használatával remélhetőleg pár percen belül képesek leszünk webalkalmazásunkban mindenféle elemet ide-oda dobálni. A drag ‘n drop, vagyis egy elem egérrel való megfogása és rádobása többé kevésbé természetes az asztali alkalmazások terén. A weben egyenlőre elég ritkán találkozhatunk vele, de hamarosan látni fogjuk, hogy felettébb egyszerűen megvalósíthatók. Amit nem szabad elfelejtenünk, hogy itt egy olyan interfészt biztosítunk a user számára, amire nem feltétlenül számít egy webes alkalmazás esetében, ezért mindenképpen jó ha valahogyan tudatjuk vele, hogy az alkalmazásunk így (is) működik.
A minimális js betöltésünk így néz ki.
<script type="text/javascript" src="eleresi/ut/prototype.js"> </script> <script type="text/javascript" src="eleresi/ut/scriptaculous.js?load=effects,dragdrop"> </script>
Drag
Ahhoz, hogy egy elemet megfoghatóvá és mozgathatóvá tegyünk csupán a következő rövidke utasítás szükséges.
new Draggable(elem);
Callback függvények
Ha szeretnénk manipulálni a draggelhető elemünk viselkedését akkor az alábbi callback függvények megadásával tehetjük meg.
- onStart
- megfogtuk az elemet, a drag inicializálva van, de még nem indult el
- onDrag
- cibáljuk az elemet
- change
- rögtön az első mozdulat után
- onDropped
- az elemet elengedtük, egy beledobhatónak jelölt elemen
- onEnd
- a cibálás vége
A fentiek értelmében ha mondjuk azt szeretnénk elérni, hogy amennyiben a mozgatható elemet elkezdjük húzni, akkor egy értesítő területen erről megjelenjen egy üzenet, akkor a következőket kell tennünk.
var kijelzo = $('kijelzo'); new Draggable('dminta1', { onStart : function(){ kijelzo.update('Cibálás történik!'); new Effect.Highlight(kijelzo); }, onEnd : function(){ kijelzo.update('Az elem cibálása véget ért!'); new Effect.Highlight(kijelzo); } });
Visszaállítás – revert
A revert
opcióval szabályozhatjuk, hogy az elem mozgatás után vissza legyen-e állítva az eredeti helyzetbe vagy pedig ne. Alapértelmezett értéke false
azaz nincs visszaállítás, az elem ott marad ahová húztuk. Ha true
-ra állítjuk, akkor az elem a reverteffect
opcióval meghatározott módon (alapból Effect.Move
) visszatér az eredeti helyére. Ha azt szeretnénk, hogy az elem akkor térjen vissza a helyére ha a drop sikertelen volt akkor a failure
érték lesz a barátunk. Végül revert
-ként megadhatunk egy saját magunk által definiált függvényt is.
Drag finomhangolás
Ahogy a scriptaculoustól már megszokhattuk egy további rakat opció áll a rendelkezésünkre ahhoz, hogy a drag-et finomíthassuk, igényeinkhez állíthassuk.
- starteffect
- default: a megfogott elem opacity 70%-ra áll
- endeffect
- default: az opacity érték visszaáll az eredetire
- delay
- default: 0. Ha az elemnek reagálni kellene kattra is és dragra is, akkor a delay opcióval tudjuk elérni, hogy csak akkor aktiválódjon a drag kezelés ha ténylegesen dragról van szó. Ehhez mondjuk 500-as értéket kell adni neki, ennyi millisecundomot fog várni arra, hogy az egér gombja lenyomva maradjon mielőtt elindítaná a drag eseményt.
- snap
- azt szabályozza, hogy hogyan mozogjon a húzkodás alatt lévő elem.
new Draggable('dminta2', {snap: 75}); //75 pixeles ugrások x és y irányban is new Draggable('dminta3', {snap: [15, 5]}); //15 pixeles ugrások vízszintesen és 5 pixeles ugrások függőlegesen
Ha szeretnénk bezárni a dragelhető elemünket egy bizonyos területre akkor a következőképpen kell eljárnunk.
new Draggable('dminta4', {snap : function(x, y){ return[ x<0 ? 0 : (x>150 ? 150 : x), y<0 ? 0 : (y>50 ? 50 : y) ]; } });
- constraint
- default:
false
, azaz nincs korlátozás a mozgás irányára vonatkozóan. Ha szeretnénk csak vízszintes irányban engedélyezni a cibálást akkor ahorizontal
értéket, csak függőleges irányra pedig avertical
értéket használjuk. - handle
- default:
false
, mely azt eredményezi, hogy a draggelhető elem teljes felületén meg lehet fogni. Megadhatunk egy dom hivatkozást, egy id-t, vagy egy css class nevet. és ettől kezdve csak az erre illeszkedő résznél lehet megfogni az elemet. Az alábbi példában csak ateto
css classú piros csíknál lehet megfogni a dobozt, máshol nem.<div id="dminta5"> <div class="teto"></div> Góranga </div>
new Draggable('dminta5', {handle : 'teto'});
Góranga
- ghosting
- default: false. Ha
true
-ra állítjuk, akkor nem magát az elemet mozgatja, hanem annak egy szellemképét.new Draggable('dminta6', {ghosting : true});
- scroll
- ha a draggelhető elemünk benne van egy másik elemben és mozgatáskor szeretnénk a szülő elemet scrollozni, akkor itt meg kell adni a szülő elemet
- scrollSensitivity
- default: 20, pixelben a távolság a scroll elem szélétől, amire reagálni fog
- scrollSpeed
- default: 15, px/sec-ben
Drop
A draggelésnek az esetek nagy többségében akkor van értelme, ha a megfogott és elhúzott elemet van mire rádobnunk. Az ilyen célzónákat a következő utasítással hozhatjuk létre.
Droppables.add('celzona');
Pár használatos opciója van.
- accept
- ezzel határozzuk meg, hogy milyen elemeket dobhatunk rá a zónára. Css class név, vagy ezek tömbje adható meg.
- containment
- a draggelhető elemek szülőjének az id-je amiket rádobhatunk erre a zónára
- hoverclass
- annak a css osztálynak a neve amelyet érvényesíteni kell a zónára ha föléhúzunk egy elfogadható elemet
- callback
- a szokásos callback-ok közül az onDrop-ot használjuk jellemzően, egy függvényt adunk meg neki ami kezeli a zónára való dobást.
Droppables.add('celzona', { accept : 'product', hoverclass : 'dropvan', onDrop : function(){ $('ertesito').update('Éppen egy drop történik rajtam'); }});
A scriptaculous honlapján van egy szép és szemléletes példa egy drag and drop-ot használó ajax bevásárlókocsira, de létrehozhatunk vele épp egy kirakósjátékot, vagy bármi mást amivel a fantázinák megáld.
Megjegyzések
- Ha nagy mennyiségű megfogható elemmel dolgozunk akkor érdemes csak azokat draggelhetővé tenni ténylegesen amit a user valóban meg is ragad.
- Óvatosan töröljük a domból a Droppable és Sortable elemeket. H ilyenre vetemedünk akkor egyenlőre kézzel külön meg kell hívnunk a Draggable.destroy(), Droppables.remove(elem) vagy Sortable.destroy(elem) függvényeket.
- Ha az “
A
” droppable zónánk benne van a “B
” droppable zónában akkor a domban elfoglalt helyük szerint belülről kifelé haladó sorrendben kell őket regisztrálni.
Helló!
Próbálta már valaki rajtam kívül ezeket a bonyolult dolgokat? Csak mert change és onDropped Callback fvény nem létezik. Azok megírásához is jó lenne egy kis segítség…
Zotya: Nézz rá a what2Do JavaScript részére, ott használtam drag ‘n dropot.
Kösz a villám választ! 🙂