Dynamiczne przypisanie tekstu do div - AJAX

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ł?

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.

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.

0

Pokaż więcej kodu

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

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.

0

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

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.

0

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

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]

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