Moikka,
Tällainen eräs ongelma astui esiin, joka on jo hetken aikaa haitannut kaikenlaista koodin kirjoittelua:
Miten luodaan esimerkiksi onChange tyyppinen ratkaisu, jolla keskellä lomaketta voidaan vaihtaa seuraavan valintalistan muuttujia:
1. auto
-bmw
-vw
-opel
2. moottoripyörä
-aprilia
-suzuki
-yamaha
Eli kun valitsen <radio>:na kohdan auto, muuttuukin tyhjänä ollut kohta mp-merkeillä.
Hyviä ja toimivia ratkaisuja kiitos. Koitinkin jo kaivaa tuota javascriptinä ja ajaxina, huonoin tuloksin.
Koodia kiitos. Siis esittele epäonnistunutta koodia, niin voimme miettiä, mikä menee pieleen.
JavaScript on kuitenkin ihan oikea lähestymistapa ongelmaan.
Ajaxiakin voi käyttää, mikäli on kyseessä suuremmasta joukosta valintoja kuin esimerkissäsi.
onChangeen laitettava funktio pseudokoodina:
- poista listalla olevat elementit
- lisää listalle halutut elementit
Tarvittavat ominaisuudet ja metodit:
new Option([text[, value[, defaultSelected[, selected]]]]) selectObject.options selectObject.add(option,before) selectObject.remove(index)
Tällaisella koodilla voisi onnistua.
EDIT! Grez näköjään vastasikin jo samalla kun testailin tätä.
<!DOCTYPE html> <html> <head> <title>JS-vaihto</title> <script type="text/javascript" src="script.js"></script> </head> <body> <form action="" method="get"> <input type="radio" name="tyyppi" value="mp" onClick="tayta('mp')" />mp<br /> <input type="radio" name="tyyppi" value="mp" onClick="tayta('auto')" />auto<br /> <select name="tyyppit"></select> </form> </body> </html>
function tayta(arvo) { select = document.getElementsByTagName("select")[0]; options = document.getElementsByTagName("option"); if (options.length != 0) { for (j = options.length-1; j >= 0; --j) { select.removeChild(options[j]); } } if (arvo == "mp") { /** Hae arvot vaikka ajaxilla **/ pyorat = new Array("BMW", "Aprilia", "Honda", "Yamaha"); for (i = 0; i < pyorat.length; ++i) { option = new Option(pyorat[i], pyorat[i]); select.appendChild(option); } } else if (arvo == "auto") { /** Hae arvot vaikka ajaxilla **/ autot = new Array("Nissan", "Volvo", "Jeep", "Dodge"); for (i = 0; i < autot.length; ++i) { option = new Option(autot[i], autot[i]); select.appendChild(option); } } }
Olin ajatellut kannustaa omaan ajatteluun olemalla tarjoamatta valmista koodia.
Mutta kun nyt laitoit koodin, niin miksi ihmeessä tuossa koodissasi on samaa koodia kopioituna moneen kertaan? Itse selkeyttäisin tälleen
function tayta(arvo) { var select, uudet, option select = document.getElementById('tyypit') while (select.options.length > 0) { select.remove(0) } if (arvo == "mp") { uudet = new Array("BMW", "Aprilia", "Honda", "Yamaha") } if (arvo == "auto") { uudet = new Array("Nissan", "Volvo", "Jeep", "Dodge") } for (var i = 0; i < uudet.length; i++) { option = new Option(uudet[i], uudet[i]) select.add(option) } }
(ja tässä vaihtoehdossahan pitää laittaa sille selectille id="tyypit", mutta mielestäni parempi kuin ottaa tylysti eka select ja ihmetellä miksi homma hajosi kun sivua joskus myöhemmin laajennetaan )
Teuron koodissa on taas liuta globaaleja muuttujia. Erityisesti yleiset nimet kuten i ja j voivat ihan käytännössäkin aiheuttaa tosi ikäviä ongelmia. Onhan se var aika hirmuisen pitkä sana, mutta ainakin kun näytetään aloittelijoille esimerkkiä niin sitä olisi hyvä käyttää.
Tyyliseikkana mainitsen vielä että [a,b,c]
on siistimpi ja (ainakin hyvässä koodissa) yleisempi kuin new Array(a,b,c)
. Lisäksi sitä käyttämällä säästyy ikävältä rajatapaukselta, nimittäin new Array(42)
.
Edit: Itse varmaan laittaisin kaikki eri listat suoraan HTML-tiedostoon ja piilottaisin ne CSS:llä (yhtä lukuunottamatta). JavaScriptin ei sitten tarvitse tehdä muuta kuin lisätä/poistaa luokkia.
Komppaan jlairea olettaen, että HTML-tiedostolla tarkoitetaan DOM-puuta. Selectit
kannattaa luoda DocumentFragmentteina
, joihin lisätään sitten vaihtoehdot ja lopulta puupataan DOM-puuhun. Näin säästytään ylimääräisiltä piirtosykleiltä (puun päivittyessä (graafisesti?) elementtien sijainnit täytyy laskea uusiksi).
Tapoja on monia. Tarkennan kuitenkin että minulla oli mielessä ihan se staattinen HTML, niin että formin kaikki osat olisivat kivasti samassa paikassa. (Tämä ei tietenkään toimi jos vaihtoehdot haetaan dynaamisesti.)
Aivan tosiaan, komppaan myös tuota jos listat ei muutu :). Väsyneenä ei aivot osannu ajatella JavaScriptiä pidemmälle.
Aihe on jo aika vanha, joten et voi enää vastata siihen.