Dinamikus select lista javascripttel

Sok oldalon látni olyan lenyíló listákat, aminek azonnal megváltozik a tartalma, amint egy másik listában kiválasztunk valamit. Erre mutatok egy példát, és közben kitérek kapcsolódó témákra is.

Legyen a példa egy igen mesterkélt probléma. Adott egy select lista, amiben számok vannak 1-től 10-ig. Ha ebben kiválasztunk egy számot, akkor a második select listában jelenjenek meg a kiválasztott szám többszörösei maximum 20-ig. Ugyebár adja magát az első lépés. Kell az első select html kódja. Minden select-nek kell egy id, hogy lehessen rá hivatkozni majd javascript-ből. Nevet is lehet neki adni, ha netán szerver oldalon szeretnénk feldolgozni majd az űrlap elküldése után az eredményt. Amire azért igen nagy az esély.

<select size="11" name="szamok" id="szamok">
        <option value="0">Válassz</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
        <option value="5">5</option>
        <option value="6">6</option>
        <option value="7">7</option>
        <option value="8">8</option>
        <option value="9">9</option>
        <option value="10">10</option>
</select>

Különösebben gondolom nem kell magyaráznom. Talán csak annyit kiemelnék, hogy véletlenül sem muszáj a value-nak és a megjelenített értéknek egyezni. De akkor a példa többi részét is ahhoz mérten kell átírni.

Na, ha már ez is megvan, jöhet a második lista. Az értékei pedig meglepő, vagy kevésbé meglepő módon nem lesznek megadva, csak az alap, aminek nincs igazán funkciója.

<select size="11" name="tobbszoros" id="tobbszoros">
        <option value="0">Válassz</option>
</select>

Ezt fogja feltölteni majd a javascript. Ide a lista után rögtön be is lehet ágyazni.

<script type="text/javascript" src="dynselect.js"></script>

Ha már szóbahoztam, akkor gyorsan meg is írom.
Amit pedig tudni kell előre a megoldásról:
JavaScript-ből id alapján minden html elem elrérhető a document objektum getElementById metódusával. Select lista esetén a lekért objektumnak létezik egy selectedIndex tulajdonsága, ami megadja, hogy melyik option lett kiválasztva. Az option-ök az options tulajdonságban vannak. Ez egy lista, aminek minden eleme egy Option osztályú (típusú) objektum. Ennek tudatában ilyen objektumpéldányokkal fel lehet tölteni az options listát. Azt, hogy épp milyen értékekkel kell feltölteni, egy tömbben tárolhatjuk. Egy többdimenziós (akár asszociatív) tömbben.

Tömbök:
Tömböket létre lehet hozni az Array osztály segítségével.

var tomb = new Array('érték1','érték2','érték3');

vagy [ és ] jelek között felsorolva az értékeket.

var tomb = ['érték1','érték2','érték3'];

Asszociatív tömb:
Asszociatív tömböknek megadható az indexe és az értéke. Ezeket kapcsos zárójelek között kell felsorolni. Az index után kettőspontot követően jön az érték.

var tomb = {
   'index1': 'érték1',
   'index2': 'érték2',
   'index3': 'érték3'
}

Legyen tehát egy tobbszoros nevű tömb, amiben fel van sorolva az első select-ben választható elemekhez, hogy mik jelenjenek meg a második listában. Ezek lesznek a többszörösök. ( Ezt persze felsorolás helyett számolással is meg lehetne oldani, de így jobban látszanak a lépések. )

Jöjjön tehát a többszörösök listája:

var tobbszoros = [
        ['Válassz'],
        ['Válassz',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
        ['Válassz',2,4,6,8,10,12,14,16,18,20],
        ['Válassz',3,6,9,12,15,18],
        ['Válassz',4,8,12,16,20],
        ['Válassz',5,10,15,20],
        ['Válassz',6,12,18],
        ['Válassz',7,14],
        ['Válassz',8,16],
        ['Válassz',9,18],
        ['Válassz',10, 20]
]

A modSelect függvény:
Ez a függvény lesz az, ami lefut, amikor az első listából valamit kiválasztunk. Tehát itt kell megírni a második lista feltöltését. Először is lekérdezzük a szamok id-jű select listát:

var szamok = document.getElementById('szamok');

Mint említettem, lekérdezhető a kiválasztott elem indexe. Ez nem a value-ban levő érték!

"]var selindex = szamok.selectedIndex;

Majd ha létezik a tobbszoros tömbben adott indexű elem, akkor beállítja a tobbszoros id-jű lista elemeit a megadott indexű elem alapján.

if(tobbszoros[selindex] != undefined)
{
        setOptions(document.getElementById('tobbszoros'),tobbszoros[selindex]);
}

A függvény egyben:

function modSelect()
{
        var szamok = document.getElementById('szamok');
        var selindex = szamok.selectedIndex;
        if(tobbszoros[selindex] != undefined)
        {
                setOptions(document.getElementById('tobbszoros'),tobbszoros[selindex]);
        }
}

A setOptions függvényt tehát még meg kell írni. Két paramétert vár. Az első a lista objektum (select), a második pedig egy tömb, ami az új értékeket tartalmazza.

function setOptions(select, options)
{
   //...
}

Először törölni kell a select lista elemeit, mert ha az új értékekből kevesebb van, mint a régiekből, akkor benne maradnak azok is a listában. A törlést megoldhatjuk egyszerűen a select.options objektum length tulajdonságának 0-ra állításával.

select.options.length = 0;

Végül ciklusban felvesszük az új elemeket.

var i;
var index=0;
for (i in options) //asszociatív tömb indexét is megtartja
{
        if (index >= options.length)
        {
                //objektum tulajdonságokat már ne listázza
                break;
        }
        select.options[index++] = new Option(options[i],i);
}

Az Option osztály konstruktorának 4 paramétere van. Ebből a példában kettőt használtam. Az első a megjelenített szöveg a listában. A második a value tulajdonságba kerül a html-ben.
A függvény egyben:

function setOptions(select, options)
{
        select.options.length = 0;
        var i;
        var index=0;
        for (i in options)
        {
                if (index >= options.length)
                {
                        break;
                }
                select.options[index++] = new Option(options[i],i);
        }
}

Most már csak azt kell megadni, hogy melyik függvény fusson le, amint kiválasztunk valamit az első listában:

document.getElementById('szamok').onchange = modSelect;

Végül nézzük az egészet egyben. Tehát a html fájl:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
    </head>
    <body>
                <form action="" method="post">
                        <div align="center">
                        Szám
                        <select size="11" name="szamok" id="szamok">
                                <option value="0">Válassz</option>
                                <option value="1">1</option>
                                <option value="2">2</option>
                                <option value="3">3</option>
                                <option value="4">4</option>
                                <option value="5">5</option>
                                <option value="6">6</option>
                                <option value="7">7</option>
                                <option value="8">8</option>
                                <option value="9">9</option>
                                <option value="10">10</option>
                        </select> többszöröse
                        <select size="11" name="tobbszoros" id="tobbszoros">
                                <option value="0">Válassz</option>
                        </select>
                        1-20-ig
                        <script type="text/javascript" src="dynselect.js"></script>
                        </div>
                </form>
    </body>
</html>

És a javascript fájl (dynselect.js):

var tobbszoros = [
        ['Válassz'],
        ['Válassz',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
        ['Válassz',2,4,6,8,10,12,14,16,18,20],
        ['Válassz',3,6,9,12,15,18],
        ['Válassz',4,8,12,16,20],
        ['Válassz',5,10,15,20],
        ['Válassz',6,12,18],
        ['Válassz',7,14],
        ['Válassz',8,16],
        ['Válassz',9,18],
        ['Válassz',10, 20]
]

function setOptions(select, options)
{
        select.options.length = 0;
        var i;
        var index=0;
        for (i in options) //asszociatív tömb indexét is megtartja
        {
                if (index >= options.length)
                {
                        //objektum tulajdonságokat már ne listázza
                        break;
                }
                select.options[index++] = new Option(options[i],i);
        }
}

function modSelect()
{
        var szamok = document.getElementById('szamok');
        var selindex = szamok.selectedIndex;
        if(tobbszoros[selindex] != undefined)
        {
                setOptions(document.getElementById('tobbszoros'),tobbszoros[selindex]);
        }
}
document.getElementById('szamok').onchange = modSelect;

Demo:

Szám
többszöröse
1-20-ig

Mi van, ha nekem a value-ba stringek kellenek, és nem csak számok?
Említettem fentebb az asszociatív tömbök használatát. A tobbszoros tömböt ennek megfelelően kell átírni. Például:

var tobbszoros = {
        'default': {'default': 'Válassz'},
        'egy': {'default': 'Válassz','egy': 1,'ketto': 2,'harom': 3 ...},
        ...
}

Természetesen itt a "..."-ok helyén folytatódik még a forráskód, de ezt már gondolom nem kell végigírnom. A módszer látszik.

Kategóriák: 
Megosztás/Mentés