Občas se stane, že v situaci, kdy v rámci jedné WWW stránky návštěvník vybírá z několika desítek hodnot, potřebujeme na tyto hodnoty uplatnit uživatelsky ovládaný filtr pro zlepšení orientace. Tento článek ukazuje jednu z možností, jak toho dosáhnout bez zatěžování serverového skriptu: stačí k tomu dvojice polí SELECT a obslužný JavaScript.

Nejprve ukázka. V následující tabulce jsou vypsány nejrůznější potraviny. Výběrem v horním rozbalovacím seznamu můžeme dolní seznam omezit na vybranou podmnožinu:

Skript je psán tak, aby každá z položek dolního seznamu mohla být členem jedné podmnožiny (např. „Mouka“), více podmnožin (oblíbené „Rajče“) nebo žádné podmnožiny („Cukr“). Každé z položek je dále přiřazeno identifikační číslo, které sice uvedený skript sám o sobě nevyužívá, lze jej však použít v dalším zpracování, například po odeslání objednávky jako výrobní číslo (jsou-li rajčata opatřena výrobními čísly).

Hlavní částí skriptu je definice objektu MeFilter, ktzerá je poměrně dlouhá, probereme si ji proto po částech. Nejprve hlavička objektu a inicializace proměnných:

function MeFilter( iName ){
    this.instanceName = iName
    this.iLength = 0
    this.arrIDs = new Array()
    this.arrNames = new Array()
    this.arrFlags = new Array()
    this.iLengthF = 0
    this.arrIDsF = new Array()
    this.arrNamesF = new Array()

Do členské proměnné instanceName je ukládáno jméno vytvořené instance objektu MeFilter – toto využijeme dále při obsluze událostí připojeného formuláře. První trojice polí (spolu s proměnnou iLength, udávající jejich délku), slouží k uložení jednotlivých položek dolního seznamu – v našem případě tedy potravin. arrIDs uchovává výše zmíněná identifikační čísla, arrNames jména, která se zobrazí v dolním seznamu, arrFlags řetězce – seznamy jednoznakových příznaků, které určují zařazení příslušné položky do podskupin. Tak si můžeme nadefinovat libovolný počet vlastních podskupin (ty jsou posléze vypsány v horním rozbalovacím seznamu) a k nim přiřadit jednotlivé položky z dolního seznamu. Konkrétní ukázka definice podskupin a položek je uvedena níže.

Druhá dvojice polí slouží právě k uložení seznamu podskupin. arrIDsF uchovává ID (tedy onen jednoznakový příznak) dané podskupiny, arrNamesF uchovává jména, zobrazená v horním rozbalovacím seznamu.

V definici objektu dále následuje dvojice metod, které do právě popsaných členských proměnných přidávají buď položku z dolního seznamu (metoda Add) nebo definují podskupinu (metoda AddFlag). Protože jde o triviální úkol, uvedeme si pouze kód těchto dvou metod bez dalšího vysvětlení:

    this.Add = function( ID, name, flags ) {
        this.iLength++;
        this.arrNames[this.iLength] = name
        this.arrIDs[this.iLength] = ID
        this.arrFlags[this.iLength] = flags
    }
    this.AddFlag = function( flagName, flagID ) {
        this.iLengthF++;
        this.arrNamesF[this.iLengthF] = flagName
        this.arrIDsF[this.iLengthF] = flagID
    }

Následuje metoda WriteTable, jež je volána z příslušného místa WWW stránky s účelem vypsat malou tabulku s dvojicí polí (horní se seznamem podskupin, dolní se seznamem položek) a naplnit tato pole výchozími hodnotami. Opět jde, i přes délku funkce, jen o jednoduché volání document.write, za zmínku stojí snad jen provázání formuláře s obslužným kódem – všimněte si handleru události onChange v horním poli SELECT:

    this.WriteTable = function( ) {
        document.write(‚<table><tr><td>‘)
        document.write(‚<select onChange="‘ + this.instanceName + ‚.FilterIt(this,this.form.filteredField)">‘)
        document.write(‚<option value="">–Všechno–</option>‘)
        for(var i=1; i<=this.iLengthF; i++ ) {
            document.write(‚<option value="‘ + this.arrIDsF[i] + ‚">‘ + this.arrNamesF[i] + ‚</option>‘ )             
        }
        document.write(‚</select>‘)
        document.write(‚</td></tr><tr><td>‘)
        document.write(‚<select size="10" name="filteredField">‘)
        for(i=1; i<=this.iLength; i++ ) {
            document.write(‚<option value="‘ + this.arrIDs[i] + ‚">‘ + this.arrNames[i] + ‚</option>‘ )             
        }
        document.write(‚</select>‘)
        document.write(‚</td></tr></table>‘)
    }

Z tohoto handleru je volána následující metoda, FilterIt, která provede vlastní filtrování obsahu dolního pole. Přijímá dva parametry, prvním je objekt horního pole SELECT (z něj zjistíme, která podmnožina byla vybrána), druhým je objekt dolního seznamu. Tento seznam metoda nejprve vyprázdní (volání DeleteSelect) a poté do něj zpětně vypíše všechny položky, které odpovídají vybranému seznamu, jinými slovy všechny ty, které ve svém příslušném řetězci arrFlags obsahují znak-příznak, odpovídající vybrané podskupině:

    this.FilterIt = function( sField, fField ) {
        filterStr = sField.options[sField.selectedIndex].value
        this.DeleteSelect( fField )
        for(var i=1; i<=this.iLength; i++ ) {
            if( (this.arrFlags[i].indexOf(filterStr)!=-1) ||
            (filterStr=="") ) {
                fField.options[fField.options.length] = new Option(this.arrNames[i]);
                fField.options[fField.options.length-1].value = this.arrIDs[i]
            }
        }
    }

Poslední metodou objektu je metoda DeleteSelect, která, jak již bylo řečeno, vyprazdňuje pole SELECT, předané jí jako parametr. Za kódem samotné funkce následuje jedna pravá složená závorka navíc jako ukončení definice celého objektu MeFilter:

    this.DeleteSelect = function( selectfield ) {
        while(selectfield.length > 0 ) {
        selectfield.options[0] = null;
        }
    }
}

Nyní je potřeba vytvořit instanci objektu MeFilter a tuto (pomocí série volání metod Add, případně AddFlag, naplnit hodnotami. V tomto článku byl použit následující kód (všimněte si vždy třetího parametru metody Add, řetězce, jehož jednotlivé znaky odpovídají dříve definovaným podskupinám – O jako Ovoce, P jako suroviny na pizzu atp.):

var f1 = new MeFilter( "f1" )
f1.AddFlag( ‚ovoce‘ , ‚O‘ )
f1.AddFlag( ‚zelenina‘ , ‚Z‘ )
f1.AddFlag( ‚ryby‘, ‚R‘ )
f1.AddFlag( ‚suroviny na pizzu‘ , ‚P‘ )
f1.Add( 100, ‚Jablko‘ , ‚O‘ )
f1.Add( 101, ‚Hruška‘ , ‚O‘ )
f1.Add( 102, ‚Ananas‘ , ‚OP‘ )
f1.Add( 103, ‚Paprika‘ , ‚ZP‘ )
f1.Add( 104, ‚Rajče‘ , ‚ZP‘ )
f1.Add( 105, ‚Květák‘ , ‚Z‘ )
f1.Add( 106, ‚Kapr‘ , ‚R‘ )
f1.Add( 107, ‚Tuňák‘ , ‚RP‘ )
f1.Add( 108, ‚Plejtvák obrovský‘ , ‚R‘ )
f1.Add( 109, ‚Mouka‘ , ‚P‘ )
f1.Add( 110, ‚Cukr‘ , “ )
f1.Add( 111, ‚Vejce‘ , ‚P‘ )

Posledním úkolem je „někde“ v HTML stránce vytvořit kostru formuláře a do ní, voláním metody WriteTable, vypsat tabulku s dvojicí polí SELECT. Formulář může být, a asi většinou i bude, samozřejmě rozsáhlejší než zde níže uvedený minimální tvar:

<form name="abc">
    <script>
        f1.WriteTable()
    </script>
</form>

Tolik ke kódu, co se týká využití, lze objevit množství nejrůznějších aplikací, namátkou výběr města podle okresu či kraje, náhradního dílu dle stroje, odpovědného pracovníka dle oboru činnosti atd. atd. (dle fantazie).

Přeji vám 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