A dragndrop területén speciális eset amikor szeretnénk sorbarendezni különböző elemeket. Egy ilyen sorrend megváltoztató bizgentyű dragndrop nélkül igazi rémálom a user számára. A scriptaculous erre a problémára a
Sortable
objektumot adja a kezünkbe.
Ahhoz, hogy egy listát kedvünkre rendezgethessünk sorba, szokás szerint egy rendkívül bonyolult és összetett JavaScript hívás szükséges.
Sortable.create('alista');
Az igazságohoz azonban hozzátartozik, hogy ehhez a html-ünknek meg kell felelnie az alábbi mintának.
<ol id="alista"> <li id="elem_1">szerda</li> <li id="elem_2">hétfő</li> <li id="elem_3">kedd</li> </ol>
- szerda
- hétfő
- kedd
Ha már egyszer átrendeztük a sorrendet, akkor elképzelhető, hogy az új sorrendet el akarjuk majd tárolni szerver oldalon. Ehhez előszőr a Sortable.serialize('elem')
függvényhívást kell alkalmaznunk, majd a továbbiakról kicsit lentebb.
- Az elemek szülő id-je lesz használva mint mezőnév, az egyes elemeknél hozzáadva a tömbjelölő
[]
jeleket. Ha ez számunkra nem megfelelő, akkor megadhatunk egyname
paramétert. - Az egyes elemek id-je adja meg az értékeket. Az id-knek
xxx_ss
formátumban kell lennie, azxxx
közös minden elemnél, az_
jel utáni rész lesz értékként használva, így ezeknek ajánlatos egyedinek lennie. - Ha nem áll módunkban (kedvünkben) az id-ket e szerint módosítani, akkor a
format
paraméterrel módosíthatjuk az alap viselkedést.
Sortable.serialize('alista'); //alista[]=2&alista[]=3&alista[]=1 Sortable.serialize('alista', {name : 'gx'}); //gx[]=2&gz[]=3&gz[]=1 Sortable.serialize('maslista', {format : /^cucu(\d)/ }); //a <li id=cucu1>-re fog illeszkedni
Callback-ok
- ha az elem megragadására szeretnénk reagálni, akkor az
onChange
callback.ot kell használnunk - ha az elem elengedésére szeretnénk reagálni akkor pedig az
onUpdate
callback-ot
var changeEffect; Sortable.create('alista2' , { onChange: function(item) { var list = Sortable.options(item).element; $('changeJelzo' ).update(Sortable.serialize(list).escapeHTML()); if (changeEffect) changeEffect.cancel(); changeEffect = new Effect.Highlight('changeJelzo',{ restorecolor: 'transparent' }); }, onUpdate: function(list) { $('updateJelzo' ).update(Sortable.serialize(list).escapeHTML()); $('updateJelzo' ).highlight({ startcolor: '#99ff99' }); } });
<ol id="alista2" style="cursor:move;"> <li id="elem_1">szerda</li> <li id="elem_2">hétfő</li> <li id="elem_3">kedd</li> </ol> <p id="changeJelzo" ></p> <p id="updateJelzo" ></p>
- szerda
- hétfő
- kedd
Szerver kommunikáció
Valószínűleg ha már a user számára biztosítjuk az elemek átrendezésének a lehetőségét, akkor azért tesszük, hogy a user a következő csatlakozáskor is azt a sorrendet lássa amit ő állított be. Ehhez viszont több mint valószínű, hogy a szerver oldalon el kell mentenünk az új sorrendet. Ehhez az onUpdate
callback-unknak valahogy így kell kinéznie.
Sortable.create('alista3' , { onUpdate: function(list) { new Ajax.Request( 'listamento.php', { parameters: Sortable.serialize(list) } } });
Az Ajax objektumról itt olvashatsz ha még nem tetted meg.
Vízszintes rendezés
A constraint
opció gondoskodik a lehetséges mozgatási irányok biztosításáról.
- vertical
- ez a default érték, azaz a listaelemeket függőlegesen tudjuk mozgatni
- horizontal
- vízszintes mozgatás – vízszintesen rendezett listáknál alkalmazható
- false
- nincs limitálva
Az overlap
opció szabályozza azt, hogy az elemek hogyan változtassák a sorrendjüket. Ezt amennyiben a constraint
nem false
, akkor azonos értékre kell állítani.
Sortable.create('alista4', { constraint : 'horizontal', overlap : 'horizontal' });
- szerda
- hétfő
- kedd
Persze ehhez szükségünk van arra, hogy az egyes listaelemeket CSS segítségével vízszintesen jelenítsük meg.
Nem listaelemek rendezése
Ha nem (csak) listaelemeket akarunk rendezgetni, akkor a tag
opcióval kell definiálnunk, hogy mely az az elemcsoport a külső konténerünkben amiket rendezni szeretnénk. Alapértelmezett értéke a 'li'
.
Sortable.create('alista5', { tag : 'img'});
<div id="alista5"> <img src="/wp-content/uploads/maclinux.thumbnail.jpg" /> <img src="/wp-content/uploads/firefox.thumbnail.jpg" /> <img src="/wp-content/uploads/debug.thumbnail.jpg" /> </div>



Mozgatható elemek korlátozása
Ha egy boxon belül szeretnénk mozgatható és nem mozgatható elemeket is tartani, akkor ezt az only
opció megadásával tehetjük meg. Alapértelmezett értéke false
. Ha használjuk, akkor egy css class alapján határozhatjuk meg, hogy melyek a mozgatható elemek.
<div id="alista6"> <p>Ezt innen el nem veszed</p> <p class="mozdithato">Ezt cibálhatod (mozdithato css class)</p> <p class="mozdithato">Ezt szintén cibálhatod (mozdithato css class)</p> <p class="huzkodhato">Ezt is cibálhatod (huzkodhato css class)</p> </div>
Sortable.create('alista6', { tag : 'p', only : ['mozdithato', 'huzkodhato'] });
Ezt innen el nem veszed
Ezt cibálhatod (mozdithato css class)
Ezt szintén cibálhatod (mozdithato css class)
Ezt is cibálhatod (huzkodhato css class)
Ennél van egy gyorsabb megoldás is, mégpedig az elements
opció. Alapértelmezett értéke false
, ha adunk neki értéket, akkor az felülbírálja az only
opciót.
Sortable.create('alista6', { elements : $$('mozdithato') });
Fák rendezése
Jóval bonyolultabb probléma az egymásba ágyazott listák, azaz a fák újrarendezése. Sajnos azt kell mondanom, hogy ennek ellenére egy elég gyakran megjelenő igény. A scriptaculous ebben is a rendelkezésünkre áll a tree
és a treeTag
opciókkal. A tree
– alapból false
– true
-ra állításával engedélyezhetjük a fák kezelését. A treeTag
mondja meg, hogy mely elemek legyenek a fán belül rendezhetőek. Alapértelmezett értéke az 'ul'
.
<ul id="alista7"> <li id="t_1"> Édességek <ul> <li id="t_2"> Palacsinta </li> <li id="t_3"> Gulab Janum </li> <li id="t_4"> Srikant <ul> <li id="t_5">Málnás</li> <li id="t_6">Citromos</li> <li id="t_7">Mangós</li> </ul> </li> </ul> </li> </ul>
Sortable.create('alista7', { tree:true });
-
Édességek
- Palacsinta
- Gulab Janum
-
Srikant
- Málnás
- Citromos
- Mangós
Egy listából egy másikba húzkodás
Ha mondjuk van két listánk, egy a mi feladatainkkal, egy pedig a bátyánk feladataival, akkor biztosan szeretnénk a két listából elemeket húzogatni ide-oda. Ehhez egyidejűleg több opciót kell használnunk.
- constraint
- várhatólag
false
lesz, hogy bármerre tudjuk az elemeket cibálni - containment
- úgy lesz megadva, hogy csak ebből a két listából fogadjon el elemeket, és máshonnan ne
- dropOnEmpty
- akkor jön jól ha azt szeretnénk, hogy a listánkba akkor is lehessen elemet dobni, ha már egyszer kiürült, mert kihúzkodtunk belőle mindent
A következő példában az egyes listákon belül cserélgethetjük a sorrendet és az egyik listából áthúzhatunk elemeket a másikba.
<div style="height:200px;"> <div style="float:left;"> <h4>Rrd feladatai</h4> <ul id="egyiklista" style="width:200px;"> <li id="e_1">Megenni a palacsintákat (rrd)</li> <li id="e_2">Megenni a gulabokat (rrd)</li> <li id="e_3">Megenni a srikantot (rrd)</li> </ul> </div> <div style="float:left;"> <h4>Bátyó feladatai</h4> <ul id="masiklista" style="width:200px;"> <li id="m_1">Kivinni a szemetet (bátyó)</li> <li id="m_2">Elmosogatni (bátyó)</li> <li id="m_3">Lemosni a plafont (bátyó)</li> </ul> </div> </div>
A JavaScriptben a két Sortable-t olyan sorrendben kell létrehozni ahogy megjelennek a dom-ban, mert csak.
Sortable.create('egyiklista', { dropOnEmpty:true, containment:['egyiklista', 'masiklista'], constraint:false }); Sortable.create("masiklista", { dropOnEmpty:true, handle:'handle', containment:["egyiklista","masiklista"], constraint:false });
Rrd feladatai
- Megenni a palacsintákat (rrd)
- Megenni a gulabokat (rrd)
- Megenni a srikantot (rrd)
Bátyó feladatai
- Kivinni a szemetet (bátyó)
- Elmosogatni (bátyó)
- Lemosni a plafont (bátyó)
Sortable finomhangolás
Mivel egy Sortable
a háttérben egy kombinált Droppable
és Draggable
ezért ezek opcióit is lehet többnyire használni ha szeretnénk. A Droppable
oldalról a containment
, a hoverclass
és az overlap
, a Draggable
oldalról pedig a constraint
, delay
, ghosting
, handle
, scroll
, scrollSpeed
és a scrollSensitivity
opciók jöhetnek számításba.
Szia,
Nagyon jók a cikkek, gratulálok!
Nincs kedved a sorozatokat PDF-ben is megosztani?
Annyira hasznosnak tűnik, hogy érdemes volna kinyomtatni (megőrizni, archiválni) 🙂
u.i.:
Mikor jelenik meg a könyved? 🙂
kosan: Köszi. Pdf-re nem gondoltam, mondjuk ezeket a “próbáld ki” jellegű példákat elég nehéz is lenne pdf-ben szemléltetni 🙂
A print.css-ről meg meg voltam győződve, hogy már réges régen megcsináltam. Köszi, hogy szóltál, az egyik legutálatosabb dolog amikor ez hiányzik. Pótolva.
Hasznos cikk! Köszönöm!
Szivesen olvasnék még egy olyan példát ahol az egyes elemeket nem dragndrop módon mozognak, hanem klikkelésre kerülnek egyel lentebb vagy fentebb a sorban. Hasonló módon “egyszerű” az is? (arra gondoltam, hogy a funkciót megvalósító linket a mozgatni kívánt elem tartalmazza)
– L –
Akron: http://wiki.script.aculo.us/scriptaculous/show/Effect.Move
Rrd feladatai
* Lemosni a plafont (bátyó)
* Megenni a gulabokat (rrd)
* Megenni a srikantot (rrd)
* Megenni a palacsintákat (rrd)
* Elmosogatni (bátyó)
* Kivinni a szemetet (bátyó)
Bátyó feladatai
ilyen felállásnál nem tudok visszarakni dolgokat 😛
Domshow: igaz, én nem is próbáltam így eddig. Utánnakerestem, regisztrált bug, elvileg ha a lista nem ul hanem div akkor működik, de nem próbáltam. Mindenesetre viszonylag gyorsan javítani szokták az ilyesmiket, szóval remélhetőleg valamelyik új verzióban csont nélkül menni fog. Addig is ha ilyesmire van szükséged, akkor gondolom egy padding érték segíteni fog.