Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: AJAX ongelma

Sivun loppuun

mika132 [22.08.2010 13:54:10]

#

Eli katselin putkan opasta ja otin sen autokaupan lähdekoodin itselleni johon lähdin muokkaamaan selostus engineäni. Selostus engine toimii automaattisesti ajastimen kautta, mutta koitin nyt ensin saada edes tekstiä tekstikenttään, mutta ei tule. Tiedän oikeastaan syynkin, mutta en osaa korjata. Olettaisin, että syy on "debuggauksen" jälkeen siinä, että i ei saa arvoa mistään. Se on minulla koko ajan null. Alertiin tulostin I:n arvon funktiossa "listaaAutot" niin arvo oli "undefined" eli. Missäs vika?

function alustaPyynto()
{
	if(window.ActiveXObject)
	{
		// Jos käytetään Internet Exploreria:
		Pyynto = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else
	{
		// Jos käytetään muita selaimia:
		Pyynto = new XMLHttpRequest();
	}
}

function suoritaPyynto()
{
	// Haetaan valintalistasta valitun merkin indeksi:
    var ind = document.autokauppa.merkit.selectedIndex;

    // Jos indeksi on nolla, ei käyttäjä ole valinnut merkkiä:
    if(ind == 0)
    {
    	alert("Valitse ensin haettava merkki!");
    	return;
	}

   	 merkki = document.autokauppa.merkit.options[ind].value;
	alustaPyynto();

	// Määritellään funktio, joka suoritetaan kun vastaus on saapunut:
	Pyynto.onreadystatechange = listaaAutot;

	// Käytetään POST-muuttujia, määritellään pyynnön vastaanottava skripti ja käytetään asynkronista tiedonsiirtoa:
	Pyynto.open("POST", "selostus.php", true);

	// Asetetaan tarvittava HTTP-otsake:
	Pyynto.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	alert("Lähetettävän tiedon arvo = " +merkki +".");
	// Lähetetään pyyntö palvelimelle parametrina hakuehto:
	Pyynto.send("merkki=" + merkki);
}

function listaaAutot()
{
	var i = 0;
	var autot = "";
	if(Pyynto.readyState == 4)
	{
		if(Pyynto.status == 200)
		{
			alert("Pyynnön while arvo = " +Pyynto.responseXML.getElementsByTagName("merkki")[i] +".");
			while(Pyynto.responseXML.getElementsByTagName("merkki")[i] != null)
			{
				alert("Whileä suoritetaan");
				var merkit = Pyynto.responseXML.getElementsByTagName("merkki");
				var merkki = merkit[i].childNodes[0].nodeValue;

				var mallit = Pyynto.responseXML.getElementsByTagName("malli");
				var malli = mallit[i].childNodes[0].nodeValue;

				var hinnat = Pyynto.responseXML.getElementsByTagName("hinta");
				var hinta = hinnat[i].childNodes[0].nodeValue;

				autot += merkki + " " + malli + ", " + hinta + " €, ";
				alert("autot =" +autot +".");
				i++;
			}
			document.autokauppa.hakutulos.value = autot;
			document.autokauppa.hakutulos.value = "VITTU";
		}
        	else
        	{
			alert("Pyynnön suorituksessa on tapahtunut virhe!");
		}
	}
}

ja selostus.php:

<?php
header("Content-type: text/xml");

$palvelimen_tiedot = file("Tietokantapalvelin.txt");

// Sijoitetaan tiedot omiin muuttujiin (yksi tieto yhdellä rivillä tiedostossa):
$palvelin 			= trim($palvelimen_tiedot[0]);
$kayttajatunnus 	= trim($palvelimen_tiedot[1]);
$salasana			= trim($palvelimen_tiedot[2]);
$tietokanta			= trim($palvelimen_tiedot[3]);

// Muodostetaan yhteys tietokantapalvelimeen:
$yhteys = mysql_connect($palvelin, $kayttajatunnus, $salasana);

// Valitaan käytettävä tietokanta:
mysql_select_db($tietokanta, $yhteys);

// Poimitaan merkki POST-muuttujasta:
$merkki_ehto 		= $_POST['merkki'];

$haku_tulos = mysql_query("SELECT Data, Selostus, Tapahtuma FROM Selostukset WHERE Data = $merkki_ehto ", $yhteys);

// Muodostetaan selaimelle lähetettävä XML-muotoinen data vastaus-muuttujaan:
$vastaus = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><autot>";

for($i = 0; $i < mysql_num_rows($haku_tulos); $i++)
{
	$data			= mysql_result($haku_tulos, $i, "Data");
	$selostus		= mysql_result($haku_tulos, $i, "Selostus");
	$tapahtuma		= mysql_result($haku_tulos, $i, "Tapahtuma");

	$vastaus .= "<auto>" .
					"<merkki>$data</merkki>" .
					"<malli>$selostus</malli>" .
					"<hinta>$tapahtuma</hinta>" .
				"</auto>";
}

$vastaus .= "</autot>";
echo $vastaus;

mysql_close($yhteys);
?>

mika132 [22.08.2010 15:08:53]

#

Uutta tietoa. Kirjoitin linkkiriviin suoraan osoitteen perään "selostus.php" ja annoin $merkki_ehto arvoksi 1 niin tuli tälläinen:

XML-jäsennysvirhe: ylimääräistä sisältöä juurielementin jälkeen
URL: http://pelila.com/gameheaven/autourheilu/jokkismanager/selostus.php
Rivinumero 2, sarake 1:

<b>Warning</b>:  mysql_num_rows(): supplied argument is not a valid MySQL result resource in <b>/home/web00439/public_html/gameheaven/autourheilu/jokkismanager/selostus.php</b> on line <b>38</b><br />
^

ja rivi 38:

for($i = 0; $i < mysql_num_rows($haku_tulos); $i++)

lahtis [22.08.2010 17:00:55]

#

Huomasin vain että

$palvelimen_tiedot = file("Tietokantapalvelin.txt");

tietokantapalvelimen tiedot ovat täysin kaikkien luettavissa jos sen noin tekee.

mika132 [22.08.2010 17:12:34]

#

Jes kiitos. Alkoi heti toimimaankin! :D

mika132 [23.08.2010 16:24:13]

#

Noniin. Ongelma taas. Luen .txt tiedostosta selostuksia. Tai siis ohjelma lukee, mutta silti ei tule mitään. Aivan kun tuo ei ymmärtäisi, että rivi tarkoittaa yhtä asiaa. Esimerkki:

<?php
$selostus = file("selostukset.txt");
for($a = 0; $a < count($autot); $a++)
{
	$selostukset 			= explode("\n", $selostus[$a]);
	$selostus 			= $selostukset[$merkki_ehto]; //Perkki ehto on randomi arvo
	$selostus_2 			= $selostukset[6];
}

sitte selostukset.txt:

Ensimmäiseen kurviin tullaan erittäin lujaa
Ja ekassa kurvissa kolisee pahasti
Sieltä tullaan aika vauhtia
Noin...
Sieltä tullaan aivan liian kovin
Suoraan metsään
suoraan puuhun
suoraan penkkan
suoraan katolleen
pyörähti

Teuro [23.08.2010 17:35:02]

#

mika132 kirjoitti:

<?php
$selostus = file("selostukset.txt");
for($a = 0; $a < count($autot); $a++)
?>

Muuta ei tartte kai lainata...

mika132 [23.08.2010 18:43:17]

#

Viitsisikö joku vielä ohjastaa miten saa tekstin tekstikenttään tulostumaan samalla tavalla kun kirjoittaisi tekstiä. Eli kirjainkerrallaan tulisi näkyviin?

Macro [23.08.2010 18:47:49]

#

Tarvitset siihen esimerkiksi Javascriptiä.

Sijoita teksti muuttujaan, ja lisää aina yksi kirjan kerrallaan tekstiä lisää esimerkiksi diviin tai textareaan. Lisää myös pieni viive kirjainten välille.

Esimerkki, joka ei ole mitään kieltä.

muuttuja = "Teksti."
for(i = 0; i < length(muuttuja); i++) {
   div.sisalto = div.sisalto + muuttuja[i]
}

mika132 [23.08.2010 19:54:54]

#

Juu. Melkein ymmärsin, mutta tämä ei tulosta mitään.

selostus += selostus_1 +kisaaja[random_kisaaja] +" " +selostus_2 +" " +kisaaja[random_kisaaja_2] +".";

for(l = 0; l < length(selostus); l++) {
	document.formselostus.selostustulos.value = selostus[l] ;
	setTimeout(300);
}

Macro [23.08.2010 20:37:09]

#

Javascriptissä length taitaa toimia muuttuja.length.

Kai olet luonut formin, jossa nameksi on määritetty formselostus ja siinä on kenttä namella selostustulos?

mika132 [23.08.2010 20:49:44]

#

Juu formit ja namet on kunnossa, mutta muutin tuon length kohdan ja se alkoi toimimaan, mutta nyt se kirjoittaa kirjaimen kummaa vanhan tekee uuden vaikka sen pitäisi tehdä lause ilman kummaamisia. Lisäksi kirjaimet vilahtaa alta sadasosan.

pistin tämän:
setTimeout(300);

mutta siihenhän kuuluisi ilmeisesti laittaa se mitä tehdään ajan jälkeen, että se ei toimi muuten. Joten onko jotain toista ajastin funktion tapasta juttua? Mikä pysäyttää hetkeksi ohjelman ja jatkaa sitten taas.

Teuro [23.08.2010 21:03:54]

#

setTimeout haluaa ajan lisäksi ns. callback funktion, joka voisi tässä tapauksessa kirjoittaa vaikka yhden kirjaimen. Tämä kirjain kannattaa antaa parametrinä funktiolle. Tällainen esimerkki tuli tehtyä.

<html>
<head>
<title>Sivut</title>
<script type="text/javascript">
var teksti = "Juha Teurokoski";
var i = 0;
var aika = 200;

function kirjoita(paikka) {
	if (i == teksti.length || teksti.length == 0) {
		return;
	}

	kirjain = teksti[i];
	elementti = document.getElementById(paikka);
	elementti.textContent += kirjain;
	++i;
	setTimeout('kirjoita("sis")', aika);
}

function aloita(time, data) {
	aika = time;
	teksti = data;
	kirjoita("sis");
}

</script>
</head>
<body>
	<p id="info">Kirjoita tekstiä alla olevaan kenttään, poistuttuasi teksti tulee hauskasti esille.</p>
	<p id="sis"></p>
	<input type="text" onBlur="aloita(200, this.value)" />
</body>
</html>

tsuriga [24.08.2010 00:44:42]

#

Tässä vois käyttää ihan setInterval+clearInterval-komboa. Lisäksi noille setInterval & setTimeout kannattaa antaa aina se funktiokutsu merkkijonon sijaan ettei lauseketta tarvitse aina evaluoida. Parametrit voi antaa sitten loppuun, tai hoitaa parametrituksen muuta kautta jos pitää toimia Interwebs Exploderillakin (?). Eli var timerID = setInterval(kirjoita, 200, this.value) ja niin etiäpäin, MDC:stä löytyy hyvät sepostukset näistä ja myös muista JavaScript-funkkareista.

mika132 [24.08.2010 17:01:44]

#

Joo. En koittanut vielä tuota tsurigan ohjetta, kun testasin ensin tätä ensimmäistä yritystä. Nyt se tulostaa yhden kirjaimen, mutta ei sen enempää ja ongelma on pakko olla settime:ssä koska jos laitan ilman timeä vain suoraan funkti kutsun takaisin funktioon se kirjoittaa koko tekstin, mutta erittäin nopeasti. Eli mikä menee väärin:

function KirjoitaKirjain(selostus) {
	if (a == selostus.length || selostus.length == 0) {
		return;
	}
	kirjain = selostus[a];
	document.formselosus.selo.value += kirjain ;
	a+=1;
	setTimeout("KirjoitaKirjain(selostus)",500);
}

Teuro [24.08.2010 17:07:41]

#

No mitä tulee virheeksi? Ja mikäs vika toimivassa esimerkissä oli, että sitä mennä muuttamaan? Katso vaikka firefoksin virhekonsolista / firebugista, että mikä menee pieleen.

mika132 [24.08.2010 17:35:59]

#

Olin jo kokonaan unohtanut firofoxin virhekonsolin. :D

Virhe oli setTimeout rivillä ja virhe oli, että "selostus ei ole määritelty" Vähän nyt ihmetyttää. Miksi se sitten ensimmäisellä kerralla sen osaa lukea ja osaa lukea vielä selostus muuttujan ennen setTimeout:ia, mutta ei enää timeoutissa?

Enkä osannut käyttää esimerkistäsi muutamaa kohtaa, mutta siis perjaatteelta omani on lähes sama.

Teuro [24.08.2010 17:39:57]

#

No mitä kohtaa et ymmärtänyt kysy ihmeessä, niin vastaan kyllä.

mika132 [24.08.2010 17:46:17]

#

Tätä:
elementti = document.getElementById(paikka);
elementti.textContent += kirjain;

Mihin tuohon asetetaan formin nimi ja mihin siinä asennetaan textarean nimi? Vai laitetaanko niitä edes tuohon? :)

Teuro [24.08.2010 18:00:52]

#

/** Haetaan elementti, jonka id = 'paikka' **/
elementti = document.getElementById(paikka);
/** Lisätään sisältöön uusi kirjain **/
elementti.textContent += kirjain;

Lomake ei kai ole kauhean oleellinen asia, jos tosiaan haluat kirjoitella tekstialueelle. Mutta kokeilepa tällaista.

<html>
<head>
<title>Sivut</title>
<script type="text/javascript">
var teksti = "Juha Teurokoski";
var i = 0;
var aika = 200;
var paikka = "selostus";

function kirjoita(paikka) {
	if (i == teksti.length || teksti.length == 0) {
		return;
	}

	kirjain = teksti[i];
	elementti = document.getElementById(paikka);
	elementti.textContent += kirjain;
	++i;
	setTimeout('kirjoita(paikka)', aika);
}

function tyhjenna(paikka) {
	elementti = document.getElementById(paikka);
	elementti.textContent = "";
}

function aloita(time, data, place) {
	i = 0;
	aika = time;
	teksti = data;
	paikka = place;
	tyhjenna(paikka);
	kirjoita(paikka);
}

</script>
</head>
<body>
	<textarea id="selostus" onFocus="aloita(200, 'Juha', 'selostus')" onBlur="tyhjenna('selostus')"></textarea>
</body>
</html>

Funktioita pitää hiukan vielä muutella, jotta se alkaa toimimaan tuon php:n luoman tekstimassan kanssa. Tällä hetkellä siis tekstialueelle tulee teksti 'Juha' pienellä viiveellä, kun hiirellä klikkaa aluetta. Teksti pyyhkiytyy pois, kun hiirelä klikataan alueen ulkopuolella.


Sivun alkuun

Vastaus

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

Tietoa sivustosta