Amit a scriptaculousról tudni érdemes 4

scriptaculousA 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>
  1. szerda
  2. hétfő
  3. 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 egy name paramétert.
  • Az egyes elemek id-je adja meg az értékeket. Az id-knek xxx_ss formátumban kell lennie, az xxx 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>
  1. szerda
  2. hétfő
  3. 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 falsetrue-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.

6 thoughts on “Amit a scriptaculousról tudni érdemes 4

  1. 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? 🙂

  2. 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.

  3. 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 –

  4. 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 😛

  5. 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.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.