Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JS: Miksi pudotusvalikko ei päivitä tietoja?

s3t [09.02.2018 16:00:08]

#

En käsitä miksi tämä ei toimi. Java- sekä C -ohjelmointi on kyllä lastenleikkiä tähän JavaScriptiin. Perusasioidenkin tekemiseen kuluu päiviä aikaa kun mikään ei toimi. Se Helsingin yliopiston Java-kurssi oli helppo, kun taas JavaScriptissä valikonkin saaminen toimimaan on valtava urakka. Miten joku onnistuu tekemään tällä mitään toimivaa?

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="avaaTiedot.js"></script>

</head>

<body>
    <select id="menu" onchange = "change(this.value); noudaTiedot();"></select>

    <div id="tulosta"></div>

</body>
</html>
// Noudetaan tiedot ja siirretään ne taulukkoon
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://api.citybik.es/v2/networks/citybikes-helsinki", true);
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var haettuTaulukko = JSON.parse(xhttp.responseText);
        luoPudotusvalikko(haettuTaulukko.network.stations); // Siirretään taulukko funktioon.
        noudaTiedot(haettuTaulukko.network.stations); // Siirretään taulukko funktioon.
    }
}
xhttp.send();

// Haetaan pudotusvalikkoon nimet
function luoPudotusvalikko(myArr){
    var select = document.getElementById('menu');
    var option;
    var out = "";
    for (var i = 0; i < myArr.length; i++) {
    option = document.createElement('option');
    option.text = myArr[i]["name"];
    select.add(option);
    }
}

// Haetaan valinnan tiedot
function noudaTiedot(taulukko) {
    var out = "";
    var i;
    for(i = 0; i < taulukko.length; i++) {
        out = taulukko[i].name + " Tyhjiä paikkoja: " +
        taulukko[i].empty_slots + " Vapaita pyöriä: " +
        taulukko[i].free_bikes + " latitude: " +
        taulukko[i].latitude + " longitude: " +
        taulukko[i].longitude + '<br>' + '<br>';
        if(document.getElementById("menu").value == taulukko[i].name){ // Verrataan pudotusmenua ja taulukon tietoja.
            document.getElementById("tulosta").innerHTML = out; // Siirretään pyydetyt tiedot HTML-sivulle.
        }
    }
}

Grez [09.02.2018 17:31:00]

#

Ymmärrän turhautumisesi, mutta en silti sanoisi että Javascript olisi vaikeampaa kuin Java tai C. Tuossa Javan tapauksessa esimerkiksi olet käynyt kurssia (jossa opetetaan hyvin yksinkertaisia asioita ja sitten testataan niiden osaamista) ja nyt sitten teet itsenäisesti jotain asiaa, jota ei suoraan ole opetettu. Eli tässä joutuu soveltamaan paljon enemmän.

Jos nyt ihan tätä koodiasi katsoo, niin olet määritellyt alasvetovalikon onchange -käsittelijäksi "change(this.value); noudaTiedot();", mutta change -funktiota ei ole missään määritelty. Tämä aiheuttaa virheen "ReferenceError: change is not defined" joka, katkaisee koodin suorittamisen. Tämä selviää suunnilleen sekunnissa avaamalla selaimen kehittäjäkonsoli. En usko että Javalla tai C:lläkään toimisi ohjelma, jossa kutsutaan olematonta funktiota.

Javascriptiä koodatessa kannattaa opetella käyttämään sitä selaimen kehittäjäkonsolia. Yleisesti ottaen millä vaan kielellä kannattaa opetella käyttämään kehitystyökaluja ja debug-toiminnallisuuksia, niin säästää helposti ne päivät turhaa ihmettelyä.

VNabokov [09.02.2018 17:33:36]

#

Ihan noin tuo ei voi toimiakaan, koska selectin onChange -tapahtumankäsittelijä kutsuu olematonta change -funktiota

EDIT: Grez oli nopeampi

s3t [09.02.2018 17:47:20]

#

Tuo change() jäi vahingossa sinne, piti poistaa se. Koitin päivittää sivua omalla funktiolla kun mikään ei tunnu päivittyvän.

document.getElementById("menu").value antaa oikean arvon mihin vertailla, mutta jostain syystä pudotusvalikon käyttäminen ei muuta mitään.

kirjoittelen koodia kdevelopilla ja olin täysin unohtanut nuo selaimen kehitystyökalut. Pitää tutustua niihin tarkemmin. Kävin jotain kurssia vuosia sitten, mutta jätin sen kesken kun en päässyt kieleen sisään.

Outoa on kun joka paikassa sanotaan ettei globaaleja muuttujia pitäisi käyttää. Miten sitten tietoa siirretään funktioiden kesken? Käytetäänkö returnia kun funktioon on ensin viety tietoa vai se tehdään?

Grez [09.02.2018 17:47:21]

#

Ja sinänsä vaikka tuon change -funktiokutsun poistaisi, niin noudaTiedot kaatuu siihen, että sille ei ole annettu tuota taulukko-parametria ja se yrittää käyttää sitä.

Edit: ehditkin jo kommentoida tuota asiaa.

Mutta joo, kyllä globaaleja muuttujia voi Javascriptissä ihan hyvin käyttää kun tehdään sivukohtaista toiminnallisuutta. Nehän on globaaleja vain sillä sivulla jossa skriptiä käytetään. Nimeämisessä voi ajatella käytäntöä, että ei käytä esim. muuttujanimeä "i" tai "taulukko", vaan esim. s3t_taulukko tai jopa s3t_avaaTiedot_taulukko, jolloin ei vahingossa tule tilannetta että kahdessa eri skriptissä olisi samanniminen globaali (joka toki sotkisi)

Sinänsä pakkohan globaalien käyttö ei ole. Voit esimerkiksi tuossa luopudotusvalikko -funktiossa määrittää tuon onchange -eventin ja välittää sen taulukon siinä, esim:

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="avaaTiedot.js"></script>

</head>

<body>
    <select id="menu"></select>

    <div id="tulosta"></div>

</body>
</html>
// Noudetaan tiedot ja siirretään ne taulukkoon
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "https://api.citybik.es/v2/networks/citybikes-helsinki", true);
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var haettuTaulukko = JSON.parse(xhttp.responseText);
        luoPudotusvalikko(haettuTaulukko.network.stations); // Siirretään taulukko funktioon.
        noudaTiedot(haettuTaulukko.network.stations); // Siirretään taulukko funktioon.
    }
}
xhttp.send();

// Haetaan pudotusvalikkoon nimet
function luoPudotusvalikko(myArr){
    var select = document.getElementById('menu');
    select.onchange = function() { noudaTiedot(myArr) }
    var option;
    var out = "";
    for (var i = 0; i < myArr.length; i++) {
    option = document.createElement('option');
    option.text = myArr[i]["name"];
    select.add(option);
    }
}

// Haetaan valinnan tiedot
function noudaTiedot(taulukko) {
    var out = "";
    var i;
    for(i = 0; i < taulukko.length; i++) {
        out = taulukko[i].name + " Tyhjiä paikkoja: " +
        taulukko[i].empty_slots + " Vapaita pyöriä: " +
        taulukko[i].free_bikes + " latitude: " +
        taulukko[i].latitude + " longitude: " +
        taulukko[i].longitude + '<br>' + '<br>';
        if(document.getElementById("menu").value == taulukko[i].name){ // Verrataan pudotusmenua ja taulukon tietoja.
            document.getElementById("tulosta").innerHTML = out; // Siirretään pyydetyt tiedot HTML-sivulle.
        }
    }
}

Huomaa siis että tässä esimerkissä ei html-koodissa ole menu-elementille määritelty mitään tapahtumakäsittelijää. Tuolla luoPudotusvalikko -funktiossa sitten määritellään tuo onchange-käsittelijä ja siinä yhteydessä funktiokutsuun sidotaan tuo saatu myArr -taulukko, ja ei siis tarvitse tallentaa globaaliin muuttujaan.

s3t [09.02.2018 18:20:26]

#

Kiitos, tuolla alkoi toimimaan ja pääsen taas eteenpäin. :) Nyt vaan karttaa lisäämään. Se aikaisemmassa versiossa onnistui lähes ongelmitta.

The Alchemist [09.02.2018 21:37:05]

#

Vähän outo kysymys, että miten javascriptillä koodatessa "välitetään tietoa", kun kielen perusperiaatteet ovat samat kuin muissakin c-sukuisissa kielissä. Samoin globaalien käyttö on huonoa ohjelmointia, jos sitä pitää huonona ohjelmointina muillakin kielillä.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta