přejít na obsah přejít na navigaci

Linux E X P R E S, jQuery (22) – výběr a přetahování v jQuery UI

jQuery (22) – výběr a přetahování v jQuery UI

jquery.png

Přetahování objektů a výběr položek lze spojit dohromady a přesouvat tak více objektů najednou. Úplně triviální na implementaci to není, ale složité také ne.


Výběr a přetahování objektů

Snad každý zná přetahování vybraných objektů na jiné místo, například souborů mezi různými adresáři. Něco takového můžeme celkem oprávněně chtít také ve webové aplikaci. Problém ale je, že jQuery UI k tomu neposkytuje přímé prostředky, tak jako je poskytuje pro přetahování jednotlivých objektů. Je potřeba část práce udělat ručně.

Existují pluginy, které to usnadňují, ale k těm se dostaneme později. Teď je důležité, o co je vlastně potřeba se postarat. Jsou to v zásadě tři věci:

  • vykreslování přesouvaných objektů na správných místech,
  • ponechání pozice objektů po skončení přetahování,
  • zpracování upuštění objektů.

Implementace

Celé to bude fungovat vlastně tak, že základem bude obyčejné přetahování jednoho objektu, které se bude „promítat“ do ostatních objektů. S výhodou k tomu lze využít událostí, které v procesu nastávají. Pokud bude přetahován nevybraný objekt, všechno se bude chovat „jako obvykle“. Při přetahování některého z vybraných objektů však bude chování jiné.

Asi bude nejlepší začít příkladem – nejdřív jen pro obyčejné přetahování, bez reakce na upuštění někam (předpokládejme, že přetahovatelnými objekty budou všechny elementy div uvnitř kontejneru s identifikátorem cont):

function updateMultidragOffsets(jq) {
  var oldpos = jq.data('oldpos');
  if (typeof oldpos != 'undefined') {
    var pos = jq.offset();
    var diff = { left: pos.left - oldpos.left, top: pos.top - oldpos.top };
    var sel = $('.multidrag');
    for (var i = 0; i < sel.length; i++) {
      var o = $(sel.get(i));
      var op = o.data('oldpos');
      o.offset({ left: op.left + diff.left, top: op.top + diff.top });
    }
  }
}

$(document).ready(function() {
  var opts = {
    start: function() {
      if ($(this).hasClass('ui-selected')) {
        $('.ui-selected').not(this).addClass('multidrag');
        $('.ui-selected').each(function() {
          $(this).data('oldpos', $(this).offset());
        });
      }
    },
    drag: function() {
      updateMultidragOffsets($(this));
    }
    stop: function() {
      updateMultidragOffsets($(this));
      $('.multidrag').removeClass('multidrag').removeData('oldpos');
      $(this).removeData('oldpos');
    },
  };

  $('#cont div').draggable(opts);
  $('#cont').selectable();

});

Vezměme to od konce. Metody selectable()draggable() připravují widgety pro výběr, resp. přetahování. Pro přetahování je potřeba připravit reakce na již zmíněné události. Na událost start (začátek tažení) se reaguje tím, že se vybraným objektům (kromě aktuálního) nastaví třída multidrag ke snazší identifikaci a všem vybraným objektům se uloží původní pozice pro výpočet pozice nové.

Pokud se přesouvá nevybraný objekt, nestane se nic, jak je z kódu zřejmé.

Při události drag se volá funkce aktualizující pozice objektů (viz dále), při události stop se aktualizuje pozice (což je nutné, protože při probíhajícím přetahování události obecně nenastávají tak často, aby se pozice aktualizovala vždy přesně), odebere se třída multidrag a odstraní uložené pozice.

Funkce updateMultidragOffsets() vypočítává rozdíl v pozici přímo přetahovaného objektu a podle něj vypočítá pozice všech ostatních objektů (přetahovaných prostřednictvím výběru). Pokud se přetahuje jen nevybraný objekt, funkce nedělá nic.

Reakce na upuštění objektů

Ještě zbývá vyřešit reakci na upuštění přetahovaných vybraných objektů někam. Klíčem je samozřejmě reakce na upuštění přímo přetahovaného objektu, ty ostatní vybrané se s ním „svezou“. Tady je krátký příklad, jak to může vypadat:

opts = {
  drop: function(e, ui) {
    ui.draggable.removeClass('ui-selected');
    $('.multidrag').removeClass('ui-selected');
    $(this).append(ui.draggable.detach());
    $(this).append($('.multidrag').detach());      
  }
};

$('#target').droppable(opts);

Objekt s identifikátorem target je cílem, kam se budou přetahované objekty pouštět. V tomto případě bude reakcí na upuštění to, že se objekty přesunou do cíle. Je potřeba je „odvybrat“ (protože už jsou jinde a pracujeme s nimi tedy jinak) a následně provést jejich přesun v DOM.

Zde se počítá s tím, že cílový objekt ty přetahované vždy přijme. Pokud by tomu tak nebylo (byl by použit filtr), mohli bychom požadovat třeba návrat objektů na původní místo. Pak by se přepsala obsluha události stop tak, že se by v případě neakceptace nastavily zpět původní pozice, případně by to šlo také animovat.

Konkrétní widgety

Tímto dílem seriálu končí pasáž zabývající se interakcí s uživatelem a příště už se podíváme na konkrétní widgety, které jQuery UI poskytuje. Jako první přijdou na řadu tlačítka různého druhu.

Nahoru

Přidat téma diskuse

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz

Lukáš Jelínek

Lukáš Jelínek

Dlouholetý člen autorského týmu LinuxEXPRESu a OpenOffice.cz. Vystudoval FEL ČVUT v oboru Výpočetní technika. Žije v Kutné Hoře, podniká v oblasti IT a zároveň pracuje v týmu projektu Turris. Ve volném čase rád fotografuje, natáčí a stříhá video, občas se věnuje powerkitingu a na prahu čtyřicítky začal hrát tenis.


  • Distribuce: Debian, Kubuntu, Linux Mint
  • Grafické prostředí: KDE

| proč linux | blog