Dynamiczne przypisanie tekstu do div - AJAX

Odpowiedz Nowy wątek
2013-08-19 15:44
0

Cześć, natrafiłem na problem, który okazał się dla mnie dość dziwny. Nie mogę przypisać do div.innerHTML czystego tekstu ze zmiennej.

Chodzi o to, że używając AJAX pobieram pewne dane z bazy danych. Dane przychodzą i są wyświetlane w listbox (obiekt select). Teraz chcę, żeby po kliknięciu na element listboxa, na konkretnym divie, pojawiła się konkretna informacja. Robię to w taki sposób:
(fragment funkcji AJAX, w której tworzę elementy listboxa)

len = data.length; //data to tablica z danymi
for(i = 0; i<len; i++)
{
    //tworzę i dodaję option do select
    var option = document.createElement("option");
    option.text = data[i]["name"];
    option.value = data[i]["ID"];
    option.onclick = function()
    {
        document.getElementById('bm_reason').innerHTML = data[i]["reason"];
    }

    select.add(option, null);
}           

Efektem tego jest dodanie elementów do listBoxa, ale jak klikam element, to dostaję błąd: "data[i] is undefined". Próbowałem też na inne sposoby:

div.innerHTML = new String(data[i]["reason"]);
div.innerHTML = data[i]["reason"].substr(0);

ale efekt zawsze był taki sam. Czy ja mogę to zrobić jakoś bez tworzenia dodatkowej globalnej tablicy, w której będę te stringi trzymał?

edytowany 1x, ostatnio: Juhas, 2013-08-19 15:45
użyj jQuery, będziesz mieć pięć razy łatwiej. - ŁF 2013-08-19 17:07
nie ogarniam go i właściwie to jedyne miejsce w całym projekcie, gdzie się przyda. Więc zanim doczytam co i jak, to zrobię szybciej za pomocą tej globalnej tablicy ;) - Juhas 2013-08-19 17:13

Pozostało 580 znaków

2013-08-19 17:04
ŁF
0

Wrzuć sobie logi do konsoli - console.log(data); console.log(data[i]); console.log(data.length); itp. (podejrzysz je np. pod ff w firebug), albo zdebuguj js w przeglądarce.

[edit]
Jeśli data jest zmienną lokalną, to jest obecna tylko w lokalnym scope, ale to oznacza, że będzie obecna i dostępna także w zdefiniowanych lokalnie (w tym samym scope) funkcjach anonimowych.


edytowany 1x, ostatnio: ŁF, 2013-08-19 17:06

Pozostało 580 znaków

2013-08-19 17:20
0

Zainstalowałem sobie tego Firebuga, ale generalnie nic mi to więcej nie dało. Te wpisy konsolowe wrzuciłem do pętli i pokazuje to, czego można byłoby się spodziewać. Jednak podczas kliknięcia na element jest ten błąd "data[i] is undefined". Wygląda to tak, jakby w tej funkcji anonimowej przypisywał na chama data[i], zamiast tego konkretnego stringa. Dopatruję się raczej czegoś w tej funkcji anonimowej, bo zarówno właściwość TEXT, jak i VALUE są ok. data jest zmienną lokalną. Błąd bym rozumiał, gdybym nie robił testów z new String.

jeśli data[i] nie istnieje, to dlaczego new String(data[i]) miałoby działać? - ŁF 2013-08-19 17:55
data[i] nie istnieje podczas klikania w element. Podczas przypisywania funkcji data[i] istnieje. - Juhas 2013-08-19 20:00

Pozostało 580 znaków

2013-08-19 17:42
0

Pokaż więcej kodu

edit: Jakiś taki gotowy do skopiowania i uruchomienia u siebie przykład byłby wskazany


edytowany 1x, ostatnio: dzek69, 2013-08-19 17:43

Pozostało 580 znaków

2013-08-19 19:47
0

Plik html (pomijam nagłówki itp):


<html>
<body>
<script language="javascript">

function update_list()
{
    var xmlHttp;
    xmlHttp = new XMLHttpRequest();

    xmlHttp.onreadystatechange = function()
    {
        if(xmlHttp.readyState == 4) //odbiór całości
        {
            var select = document.getElementById('main_select'); 
            var data = JSON.parse(xmlHttp.responseText);

            if(data == null) return; 

            select_clear(select); //czyszczenie selectu - dla testów można pominąć, osobna funkcja, która w pętli usuwa wszystkie itemy z przekazanego selecta

            len = data.length;
            for(i = 0; i<len; i++)
            {
                //tworzę i dodaję option do select
                var option = document.createElement("option");
                option.text = data[i]["name"];
                option.value = data[i]["ID"];
                option.onclick = function()
                {
                    document.getElementById('bm_reason').innerHTML = data[i]["reason"];
                }

                select.add(option, null);
            }           
        }
    }

    xmlHttp.open("GET", "ajax.php?action=get_list", true);
    xmlHttp.send(null);
}
</script>

<select name="main_select" id="main_select" size="5" style="width: 150px">

</select>
<div id="bm_reason"></div>
[<a rel="nofollow" href="#" onclick="update_list()">wypełnij listę</a>]
</body>
</html>

Przykład tabeli w bazie danych:


CREATE TABLE `tabela` (
  `ID` bigint(20) NOT NULL,
  `name` varchar(255) NOT NULL,
  `reason` text collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`ID1`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

insert into tabela(name, reason) values("Item 1", "Tekst dla itemu 1");
insert into tabela(name, reason) values("Item 2", "Tekst dla itemu 2");
insert into tabela(name, reason) values("Item 3", "Tekst dla itemu 3");

Fragment pliku php:


$action = $_GET["action"];

switch($action)
{
    case 'get_list':
        $sql = "SELECT ID, name, reason FROM tabela"; //zapytanie

        //pseudokod - pobieramy dane
        $result = $db->sql_query($sql);
        while($row = $db->sql_fetchrow($result))
        {
             $arr[] = $row;
        }

        //wyrzucamy dane do AJAX
        echo json_encode($arr);
        exit();
}

Mniej więcej tak to właśnie wygląda. Aktualnie zrobiłem to, używając globalnej tablicy, ale dziwi mnie, dlaczego nie można w taki sposób.

edytowany 1x, ostatnio: Juhas, 2013-08-19 19:49
Atrybut language dla script nie istnieje. Relikt kilkunastoletniej przeszłości. Wywal to. - dzek69 2013-08-19 23:19

Pozostało 580 znaków

2013-08-19 22:36
ŁF
0

Po zakończeniu pętli zgadnij jaką wartość ma zmienna i? Kiedy klikniesz, z jakim i będzie wykonywana obsługa kliknięcia?


Pozostało 580 znaków

2013-08-20 11:22
0

No o to mi się rozchodzi, że po mojemu to wartość data[i]["reason"] powinna być przypisana do innerHTML. Zwłaszcza, że próbowałem z new String itp. Tak, jakbym zrobił:

<select>
<option ... onclick="ten_moj_div.innerHTML='blabla'">
</select>

Myślałem, że przypisanie tej funkcji anonimowej właśnie takie coś zrobi.
To teraz pytanie - czy da się to zrobić bez dodatkowej tablicy, która przechowuje te wartości? To już bardziej pytanie z ciekawości.

Pozostało 580 znaków

2013-08-20 11:47
0

Upewnij się, że i jest zmienną lokalną, IDE powinno Cię okrzyczeć za takie coś


Pozostało 580 znaków

2013-08-20 14:22
dgdfg
0

nie globalną bo to nie ma znaczenia tutaj żadnego - i będzie widoczne z tego miejsca z tym że to nie będzie i którego oczekujesz tylko to samo, współdzielone i po iteracji tablicy

to co musisz zrobić to przypisać aktualne i w iteracji do obiektu na którym operujesz czyli:

option.i = i;

a potem w funkcji zamiast:

data[i]
daj:
data[this.i]

albo najlepiej od razu zamiast pamiętać i to zapamiętaj sobie data[i]

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0