Avatar billede dj-sejler Praktikant
20. marts 2012 - 22:46 Der er 26 kommentarer

AJAX og multiselect

Hej Eksperter!

Jeg har et problem - jeg vil gerne have hjælp til at opdatere en multiselect boks ud fra hvad der er valgt i en anden multiselect boks.

BOKS 1:
regioner i DK m.m.
- Storkøbenhavn
- Nordsjælland
- Sjælland
osv...

Hver region ligger i en tabel (place) i min MySQL og har et unikt id og navn.

BOKS 2:
indholdet af boks 2 skal være de kommuner der er i hver af de valgt regioner. ALLE kommuner ligger i en anden tabel (place_municipal) med unikt id, place_id (der kæder til første tabels id) og navnet.

noget der kan hjælpe mig hele vejen her?
Avatar billede tjens Nybegynder
20. marts 2012 - 22:55 #1
Her er et eksempel på det:
http://tjens.dk/eksperten/937602/
Avatar billede olebole Juniormester
21. marts 2012 - 00:11 #2
<ole>

Ajax.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<style type="text/css">
select {
    vertical-align: top;
}
</style>
</head>
<body>

<script type="text/javascript">
var oTempl = null;
function callServer(sQuery) {
    var oXHR = new XMLHttpRequest();
    oXHR.open("post", "response.php", true);
    oXHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    oXHR.onreadystatechange = function() {
        if (this.readyState<4) return;
        insertOptions(JSON.parse(this.responseText));
    }
    oXHR.send("context=getKommuner&"+sQuery);
}
function insertOptions(oResp) {
    if (oResp.error) {
        alert(oResp.error);
        return;
    }
    var elmOpt, rows = oResp.rows,
    elmSel = document.getElementById("kommuner");
    while (elmSel.firstChild) elmSel.removeChild(elmSel.firstChild);
    for (var i=0,j=rows.length; i<j; i++) {
        elmOpt = oTempl.cloneNode(true);
        elmOpt.firstChild.nodeValue = rows[i].kommune;
        elmOpt.setAttribute("value", rows[i].id);
        elmSel.appendChild(elmOpt);
    }
    elmSel.style.display = "inline";
}
function loadSelect() {
    var elm = document.getElementById("regions"),
    colOpts = elm.getElementsByTagName("option"),
    sVarName = encodeURIComponent("select[]"),
    aSelected = [], inx = 0;
    for (var i=0,j=colOpts.length; i<j; i++) {
        if (colOpts[i].selected) aSelected[inx++] = encodeURIComponent(colOpts[i].value);
    }
    if (inx==0) {
        alert("Du skal vælge mindst én region.");
        return;
    }
    callServer(sVarName+"="+aSelected.join("&"+sVarName+"="));
   
    elm = document.getElementById("kommuner");
    elm.style.display = "none";
    if (!oTempl) {
        oTempl = elm.getElementsByTagName("option")[0];
        elm.removeChild(oTempl);
    }
}
</script>
<div id="displ"></div>
<div>
<select id="regions" multiple="multiple">
    <option value="1">Storkøbenhavn</option>
    <option value="2">Nordsjælland</option>
    <option value="3">Sjælland</option>
</select>

<select id="kommuner" style="display:none" multiple="multiple">
    <option>&nbsp;</option>
</select>
</div>

<p>
    <button onclick="loadSelect()">Load</button>
</p>

</body>
</html>

response.php:

<?php
function getKommuner($json) {
    $mysqli = new mysqli('server', 'brugernavn', 'kodeord', 'databasenavn');
    if (mysqli_connect_errno()) {
        $json->error = 'Der opstod en fejl ved forbindelsen: ' . mysqli_connect_error();
        return $json;
    }
   
    if ($stmt = $mysqli->prepare('SELECT `id`, `kommunenavn` FROM `kommuner` WHERE `place_id` = ?')) {
        $stmt->bind_param('i', $id);
        $result = array();
        foreach ($_POST['select'] as $val) {
            $id = $val;
            $stmt->execute();
            $stmt->bind_result($place_id, $kommune);
            while ($stmt->fetch()) {
                $result[] = array('id'=>$place_id, 'kommune'=>$kommune);
            }
        }
        $stmt->close();
        $json->rows = $result;
    } else {
        $json->error = 'Der opstod en fejl i erklæringen: ' . $mysqli->error;
        return $json;
    }
    $mysqli->close();
   
    return $json;
}
if (!empty($_POST)) {
    header("content-Type: applicaton/json; charset=utf-8");
    $json = new stdClass();
   
    if (isset($_POST['context'])) {
        switch ($_POST['context']) {
            case 'getKommuner':
                if (isset($_POST['select'])) $json = getKommuner($json);
                else $json->error = 'No region was selected';
            break;
            default:
                $json->error = 'Unknown context ID.';
        }
    } else {
        $json->error = 'No context ID found.';
    }
   
    $strJson = json_encode($json);
    header('Content-Length: '.strlen($strJson));
    echo $strJson;
}
?>

/mvh
</bole>
Avatar billede olebole Juniormester
21. marts 2012 - 00:42 #3
@tjens: Pas på med at bruge XHR-objektets navn i onreadystatechange. Det skaber en cirkulær reference over en closure, som kan være vanskelig at opløse (= memory leak). Brug i stedet keyword'et this  *o)
Avatar billede dj-sejler Praktikant
21. marts 2012 - 18:49 #4
Nu sidder jeg og skal til at prøve...
er det sådan at man skal trykke på knappen for at der sker noget?

jeg vil i hvert fald gerne have at det er når man vælger...
Avatar billede olebole Juniormester
21. marts 2012 - 19:00 #5
Det giver da ikke mening med en multiselect. Hvordan skal scriptet gætte, hvornår du er færdig med at vælge?
Avatar billede dj-sejler Praktikant
21. marts 2012 - 19:14 #6
det kan du have ret i..!
jeg giver mig...

med de få tilpasning jeg har lavet, får jeg kun 2 ud af 4 resultater ud af min database... nogen ideer?
Avatar billede dj-sejler Praktikant
21. marts 2012 - 20:08 #7
Derudover sender knappen formen på hele siden i aktion, det vil sige at siden loades igen... og så er jeg tilbage til udgangspunktet...
Avatar billede dj-sejler Praktikant
21. marts 2012 - 20:29 #8
narj...

for hvert "valg" i regioner, kan den jo bare opdatere kommunerne...
så mange er der jo heller ikke mere...

jeg kan i hvert fald ikke få det andet til at virke, når jeg smider det ind i mine eksisterende sider...
Avatar billede olsensweb.dk Ekspert
21. marts 2012 - 21:21 #9
#5 Hvordan skal scriptet gætte, hvornår du er færdig med at vælge?
man kunne vel lave en event på onblur.
det bliver så ikke helt når man vælger, man får opdateret den næste, men når man forlader select boxen
Avatar billede dj-sejler Praktikant
21. marts 2012 - 21:27 #10
kan man ikke gøre det "onclick" et eller andet sted i select boxen...
Avatar billede olsensweb.dk Ekspert
21. marts 2012 - 21:33 #11
>kan man ikke gøre det "onclick" et eller andet sted i select boxen...
hvordan vil du så kunne vælge flere ??
hver gang du vælger en ny region så sletter du indholdet af kommune select boxen
Avatar billede dj-sejler Praktikant
21. marts 2012 - 22:50 #12
Det jeg rigtig gerne vil er...

jeg har en profil-side med flere inputfelter

her skal jeg bruge min regions og kommuneliste...

Den udemærkede kode som du <ole> har givet har jeg tilpasset min database og for at teste http://aktivjoblog.dk/test/ajax.html

men på selve min profil-side sker der det når jeg trykker load, så sendes hele formen og siden reloades... kan jeg komme ud over det?
Avatar billede olebole Juniormester
21. marts 2012 - 22:45 #13
Jeg tror, du skal begynde med at tænke dig grundigt om og finde ud af, hvad det egentlig er, du vil gøre for brugeren.

Sluk PC'en og tag fat i noget papir og en pen - tænk dig rigtig grundigt om - og skitser og tag noter imens. Det er den allervigtigste fase i det at skrive en hvilken somhelst (web)applikation. Det at kode skidtet er kun en lille, ubetydelig del af arbejdet  *o)
Avatar billede olebole Juniormester
21. marts 2012 - 23:26 #14
Der er ingen form - og ingen side, der reloades
Avatar billede olebole Juniormester
21. marts 2012 - 23:29 #15
- al kommunikation med serveren sker gennem browserens XMLHttpRequest object. Der er ingen form, og derfor er der ingenting i HTML'en, der kan reloade siden. På samme måde er der heller ingenting i scriptet, der kan reloade siden
Avatar billede dj-sejler Praktikant
22. marts 2012 - 19:47 #16
jeg forstår godt at det ikke skulle ske nogen reload eller sending af siden... ikke distomindre så reloader siden når jeg trykker på knappen...

det hele er placeret mellem to <form></form> da jeg skal gemme dataene når brugeren har valgt...
Avatar billede olebole Juniormester
22. marts 2012 - 20:19 #17
Vi kan ikke se, hvad du laver. Prøv at lægge et link til et eksempel
Avatar billede dj-sejler Praktikant
22. marts 2012 - 20:26 #18
problemet med det er at det er i et lukket brugerområde...
men jeg prøver...
Avatar billede olebole Juniormester
22. marts 2012 - 20:26 #19
Det er rigtigt! De fleste browsere er lamme nok til at opfatte enhver uspecificeret knap i en form som en submitknap. Sæt type på knappen:

<button type="button"
Avatar billede dj-sejler Praktikant
22. marts 2012 - 20:35 #20
Perfekt... det var lige det der skulle til...
så arbejder jeg videre...
Nu må vi også snart kalde det for et løst problem, og jeg vil udbede dig at svare... :)
Avatar billede dj-sejler Praktikant
22. marts 2012 - 20:37 #21
tillæg...

jeg kan ikke få den til at skrive de kommuner ud der er skrevet i databasen med æøå... nogen ide til hvorfor og rettelse?
Avatar billede olsensweb.dk Ekspert
22. marts 2012 - 20:50 #22
hvilke tegnsæt kører du med fra sql serveren ??
du skal kører UTF-8, AJAX understøtter ikke andet
prøv at sætte din db charset connection http://dk.php.net/manual/en/function.mysql-set-charset.php
Avatar billede olsensweb.dk Ekspert
22. marts 2012 - 21:03 #23
skulle selvføgelig have været http://dk2.php.net/mysqli_set_charset da du fornuftigt nok anvender mysqli
og dine tabeller skal også være utf-8_danish_ci
filerne skal være incodet med utf-8
filerne skal være gemt som UTF-8 uden BOM
kort sagt UTF-8 hele vejen rundt, så går det aldrig galt

i den perfekte verden burde mysql(i)_set_charset være overflødig
Avatar billede olebole Juniormester
22. marts 2012 - 21:03 #24
Ja, du skal sørge for, at indholdet af databasen er skrevet ind som utf-8 - samt at database og kollationer er sat til utf8_danish_ci
Avatar billede dj-sejler Praktikant
14. august 2012 - 23:35 #25
smid svar og tak for ulejligheden!
Avatar billede olsensweb.dk Ekspert
17. august 2012 - 12:26 #26
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester