Párování záznamů v JavaScriptu

29. prosince 2002

Zajímavým druhem uživatelského vstupu je takzvané párování záznamů, tedy akce, kdy uživatel ke každému záznamu z jedné sady vybírá jeho ekvivalentní protějšek v sadě druhé. V tomto článku si ukážeme, jak podobnou funkčnost realizovat prostřednictvím JavaScriptu.

Lépe, než poněkud kostrbatý popis činnosti, nám jako vždy poslouží malá ukázka. V následujícím formuláři můžete vyzkoušet přiřadit různé funkce v podnikové hierarchii jednotlivým osobám. Po vytvoření všech potřebných párů se pak celý výsledek odesílá serverovému skriptu ke zpracování.

Použitý skript

Nejdříve je potřeba napsat příslušný HTML formulář se třemi SELECT prvky a několika funkčními tlačítky. V příkladu byl použit následující kód, z něhož je důležité především pojmenování jednotlivých prvků (kvůli vazbám na JavaScript) a volání odpovídajících funkcí v handlerech událostí onClick na tlačítcích. Důvod, proč je v každém z prvků SELECT definována jedna položka OPTION s nesmyslnou hodnotou, se jmenuje Netscape Navigator. Tento prohlížeč (alespoň jeho starší verze) nemění dynamicky velikost pole SELECT dle jeho obsahu, proto je mu v mém řešení při načítání stránky ‚předhozen‘ jeden široký prvek, dle něhož NN nastaví velikost SELECT pole:

<form name=“matcher“>
<table border=“1″ cellpadding=“4″ cellspacing=“0″>
   <tr><td><font face=“Arial“ size=“2″>Vyberte odpovídající záznamy a spárujte je tlačítkem &quot;&lt;=&gt;&quot;</font>
      <table border=“0″ cellpadding=“0″>
        <tr><td align=“center“ valign=“top“><select name=“o1″ size=“7″ multiple>
                <option value=“—————————-„>—————————-</option></select></td>
            <td align=“center“>&nbsp; <input type=“button“ value=“ &lt;=&gt; “ name=“match“ onClick=“MatchIt()“>&nbsp; </td>
            <td align=“center“ valign=“top“><select name=“o2″ size=“7″ multiple>
                <option value=“—————————-„>—————————-</option></select></td> </tr>
       </table>
    </td></tr>
</table>
<table border=“0″ cellpadding=“0″ cellspacing=“0″><tr><td>&nbsp;</td></tr></table>
<table border=“1″ cellpadding=“4″ cellspacing=“0″>
    <tr><td><font face=“Arial“ size=“2″>Seznam vytvořených párů:</font>
        <table border=“0″ cellpadding=“0″>
            <tr><td align=“center“ valign=“top“><select name=“result“ size=“7″ multiple>
                <option value=“—————————————————————„>—————————————————————</option>
                </select></td>
            <td align=“left“ valign=“top“><input type=“button“ value=“Odstranit pár“ name=“remove“ onClick=“Remove()“><br>
            <br>
            <input type=“button“ value=“Odstranit vše“ name=“removeall“ onClick=“RemoveAll()“></td>
            </tr></table>
</td></tr></table>
<p><input type=“submit“ value=“ Odeslat “ name=“submit“></p>
</form>

V handleru události onLoad sekce body zajistíme volání funkce PrepareForm (<body bgcolor="#C0C0C0" onLoad="PrepareForm()">), která provede úvodní naplnění formulářových polí datovými hodnotami z polí a1 a a2. Tato pole jsou dvourozměrná, přičemž první sloupec obsahuje názvy jednotlivých záznamů, druhý pak jejich klíče – jednoznačné identifikátory, sloužící nejen ke správné funkčnosti celého skriptu, ale zejména jako výsledné hodnoty, předávané na server po odeslání formuláře. Pole a1 a a2 budou zřejmě nejčastěji generována při vytváření stránky serverovým skriptem z databáze. Pole mohou mít také různou délku:

var a1 = [
    [ „Jan Novák“, 10021 ],
    [ „Petr Horák“, 10022 ],
    [ „Zdeněk Nováček“, 10023 ],
    [ „Martin Novotný“, 10024 ],
    [ „Zdena Zelená“, 10025 ] ];
var a2 = [
    [ „Účetní“, 501 ],
    [ „Ředitel“, 502 ],
    [ „Náměstek výroby“, 503 ],
    [ „Generální ředitel“, 504 ],
    [ „Předseda představenstva“, 505 ],
    [ „Dělník“, 506 ] ];
function PrepareForm() {
var i;
    with(document.forms[„matcher“]) {
        o1.options[0] = null;
        for( i=0; i<a1.length; i++ ) {
            o1.options[i] = new Option(a1[i][0], „“+a1[i][1]);
        }
        o2.options[0] = null;
        for( i=0; i<a2.length; i++ ) {
            o2.options[i] = new Option(a2[i][0], „“+a2[i][1]);
        }
        result.options[0] = null;
    }
}

Zbývající část kódu tvoří tři samostatné funkce, volané vždy po stisku odpovídajícího tlačítka, které provádějí akce párování, případně rozpojování párů. Nejprve jej funkce MatchIt, která vytvoří pár, vloží do spodního prvku SELECT a z horních dvou prvků SELECT odstraní hodnoty použité v páru. Identifikátory použitých záznamů jsou společně vloženy do vlastnosti value příslušného prvku spodního formulářového pole SELECT, a to jako řetězec se dvěma těmito hodnotami oddělenými čárkou:

function MatchIt() {
    with(document.forms[„matcher“]) {
        if( (o1.selectedIndex==-1) || (o2.selectedIndex==-1) ) {
            alert(„Musíte vybrat po jednom záznamu z každého okna, které chcete párovat.“);
            return;
        }
        var t = o1.options[o1.selectedIndex].text + “ <=> “ + o2.options[o2.selectedIndex].text;
        var v = o1.options[o1.selectedIndex].value + „,“ + o2.options[o2.selectedIndex].value;
        result.options[result.options.length] = new Option(t, v);
        o1.options[o1.selectedIndex] = null;
        o2.options[o2.selectedIndex] = null;
    }
}

Odstranění páru je proces opačný. Funkce Remove při něm nejprve získá ze zvoleného páru hodnoty identifikátorů jeho dvou členů, ty najde ve vstupních polích a1 a a2, a vrátí členy zpět do horních polí SELECT, zatímco ve spodním (výsledkovém) poli inkriminovaný pár odstraní:

function Remove() {
    with(document.forms[„matcher“]) {
        if( result.selectedIndex==-1) {
            alert(„Musíte vybrat pár, který chcete odstranit.“);
            return;
        }
        var v = result.options[result.selectedIndex].value;
        var i = v.indexOf(„,“);
        var v1 = 1*v.substring(0,i);
        var v2 = 1*v.substring(i+1);
        result.options[result.selectedIndex] = null;
        for(i=0; i<a1.length; i++ ) {
            if(a1[i][1]==v1) o1.options[o1.options.length] = new Option(a1[i][0], „“+a1[i][1]);
        }
        for(i=0; i<a2.length; i++ ) {
            if(a2[i][1]==v2) o2.options[o2.options.length] = new Option(a2[i][0], „“+a2[i][1]);
        }
    }
}

Odstranění všech párů už je pak úlohou víceméně triviální, spočívající v opakovaném volání právě popsané funkce Remove:

function RemoveAll() {
    with(document.forms[„matcher“]) {
        while( result.options.length ) {
            result.selectedIndex=0;
            Remove();
        }
    }
}

Po stisku tlačítka „Odeslat“ je obsah celého formuláře odeslán serverovému skriptu. Ten pak zpracuje především obsah spodního formulářového pole, zde pojmenovaného result, v němž jsou uvedeny ID vytvořených párů v řetězcích, oddělených čárkou (tedy ve tvaru „ID1,ID2“). Samozřejmě lze ještě před odesláním provést dodatečné kontroly, popřípadě přeformátovat obsah pole result do jiné podoby, tyto operace jsou však již součástí konkrétní aplikace skriptu a jako takové zde nejsou uvedeny.

Popsaný skript je poměrně úzce specializovaný, takže jej zřejmě v této podobě využije jen malá část čtenářů. Ostatním snad poslouží jako ukázka „předzpracování“ vstupu na straně klienta. I když by se celá funkčnost dala bez problémů realizovat serverovými skripty, u JavaScriptového řešení je výhodou řádově menší četnost dotazů na server a tedy i daleko větší rychlost odezvy. Právě nářky uživatelů na rychlost odezvy čistě serverové (byť intranetové) aplikace byly, mimochodem, hlavním důvodem vzniku skriptu, jenž se stal základem tohoto článku.

Kompletní zdrojový kód je k dispozici.

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

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

Předchozí článek olive.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *