Má-li uživatel v rámci formuláře v HTML stránce vybrat nula až několik možností z předem daného seznamu, lze to provést například vytvořením zatržítek. Dalším – a leckdy přehlednějším – způsobem je použití dvou seznamů a přesouvání jejich obsahu pomocí tlačítek Add/Remove. V tomto článku si ukážeme, jak na to – pomůže nám krátký JavaScript.

Jak to funguje, můžete si ověřit zde. Zkuste vybrat položku v levém seznamu a přesunout ji pomocí horního tlačítka do seznamu druhého, respektive naopak:

Oba seznamy jsou realizovány pomocí pole SELECT, které se obvykle používá ve tvaru rozbalovacího seznamu (tzv. ComboBoxu). Zde jsme v definici tagu SELECT nastavili vlastnost SIZE na hodnotu 4, čímž se z „rozbalovacího“ seznamu stal seznam „posouvací“ – obdoba Windows prvku ListBox. V levém seznamu (nazvaném „list1“) jsme dále pomocí tagu OPTION nadefinovali 6 položek – názvů dopravních prostředků. Pravý seznam „list2“ kupodivu zpočátku není prázdný, ale obsahuje jednu položku, kterou vzápětí pomocí skriptu zase umažeme. Proč tomu tak je, řekneme si později.

Oba prvky, včetně tlačítek Add a Remove jsou umístěny ve formuláři, v tomto příkladu poněkud „očesaném“. Chybí např. pro naše účely nikoliv nezbytné tlačítko Submit, cílení formuláře atp. Celý formulář je dále umístněn do jednoduché tabulky. Zde je tedy příslušný HTML kód:

<form name="demo">
<table border="0" cellpadding="2"
cellspacing="0" bgcolor="#FF0000">
<tr><td rowspan="2">
    <select name="list1" size="4">
        <option value="Auto">Auto</option>
        <option value="Letadlo">Letadlo</option>
        <option value="Motorka">Motorka</option>
        <option value="Koloběžka">Koloběžka</option>
        <option value="Šlapadlo">Šlapadlo</option>
        <option value="Lyže">Lyže</option>
        </select>
</td>
<td align="center"><input type="button" value=" &gt;&gt; " name="add" onCLick="Add()"></td>
<td rowspan="2">
    <select name="list2" size="4">
        <option value="x">xxxxxxxxxxxxx</option>
    </select>
</td></tr>
<tr>
<td align="center"><input type="button" value=" &lt;&lt; " name="remove" onCLick="Remove()"></td>
</tr>
</table>
</form>

Jak jsme si řekli výše, nyní jedinou položku, definovanou v pravém seznamu, zase smažeme krátkým JavaScriptem (v adresaci využíváme názvu formuláře „demo“):

document.demo.list2.options[0] = null;

Proč tomu tak je? Jedná se opět o úlitbu proNetcape. Šířky polí SELECT jsou definovány „za běhu stránky“ tak, aby odpovídaly šířce nejdelší z položek. Zatímco u prohlížeče MSIE dochází k dynamické změně šířky pole SELECT (což mimochodem vede k onomu pěknému „skákání“ šířky při přidávání či ubírání položek), u Netcape verze 4.5, na kterém byl tento kód testován, je šířka nastavena ihned po ukončovacím tagu SELECT a dále se nemění. Proto jsme pro tento prohlížeč uměle nastavili šířku pole SELECT pomocí nevýznamné položky, jež je ihned po načtení stránky smazána.

Zbývá už jen napsat kód pro funkce Add a Remove, volané z událostí onClick na příslušných tlačítkách. Obě funkce můžeme definovat např. v hlavičce stránky. Nejprve funkce Add, zabezpečující smazání vybrané položky z levého seznamu a její přidání do pole pravého:

function Add()
{
    with(document.demo) {   
        menuNum = list1.selectedIndex;
        list2len = list2.length;
        if (menuNum < 0 ) return;
        list2.options[list2len] = new Option( list1.options[menuNum].value );
        list2.options[list2len].value = list1.options[menuNum].value;
        list1.options[menuNum] = null;
    }   
}

Funkce zjistí vybranou položku v levém seznamu, pomocí syntaxe new ji přidá na konec seznamu pravého (poznámka: jak vlastní hodnotu položky, tedy vlastnost value, tak zobrazený text nastavujeme na stejnou hodnotu), a nakonec smaže příslušnou položku ze seznamu vlevo. Funkce je ošetřena proti prázdnému výběru v levém poli, pro zestručnění zápisu jsme dále použili klauzuli with.

Funkce Remove se funkci Add podobá co vejce vejci, takže si uvedeme pouze její kód bez dalších vysvětlivek:

function Remove()
{
    with(document.demo) {   
        menuNum = list2.selectedIndex;
        list1len = list1.length;
        if (menuNum < 0 ) return;
        list1.options[list1len] = new Option( list2.options[menuNum].value );
        list1.options[list1len].value = list2.options[menuNum].value;
        list2.options[menuNum] = null;
    }   
}

Náměty na vylepšení:

Uvedený příklad je okleštěn na maximální možnou míru, způsobů, jak jej vylepšit, by se našlo určitě více než dost. Namátkou snad:

  • zachovat třídění seznamu i po několika přesunech zleva doprava a zpět
  • upravit skript tak, aby šlo zadávat různé hodnoty do nadpisu položky i do vlastnosti Value
  • zamezit „poskakování“ velikosti pravého pole SELECT v Internet Exploreru

Přeji vám tedy úspěšné experimentování, a samozřejmě, příjemný den.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět