ugrás a tartalomhoz

JQuery: Autocomplete betöltés probléma

belvaros@freemail.hu · 2012. Szep. 5. (Sze), 01.28
Sziasztok.

Van egy php fájl, ebben pedig egy text input-om, amire rá van húzva a jQuery-s autocomplete települések kiválasztásához.
A dolog nagyon szépen működik amikor az input-ot tartalmazó php fájlt csak önmagában vagy az index.php-ből hívom meg (utóbbi esetben include-ból), beírásra jön az autocomplete-s legördülő menü, ki tudom választani, stb.
A gond akkor van amikor nem include-ból hoznám be, hanem egy div-be tölteném be jQuery-vel:
jQuery(document).ready( function()  {jQuery("#div_felulet").load("div_kereses.php");} );
Ekkor már nem működik az autocomplete, a Chrome ellenőrző eszközében a következőt kapom:
Uncaught TypeError: Object [object Object] has no method 'autocomplete'


Ezt azért nem értem, mert a jQuery-vel kapcsolatos minden szkript a div_kereses.php -ben van meghívva (ezért is fut akkor is ha csak önmagában ezt a php-fájlt hívom meg), de ha div-be töltöm mégis olyan, mintha nem is látná a függvénykönyvtárakat. Bár elvileg nincs rá hatással, de kísérletképpen az index.php-ben is meghívtam a szkript-eket, de ahogy várható volt ennek nincs semmilyen hatása.


Bár csak pár hónapja kezdtem el javascript-tel foglalkozni, eddig minden sikerült amit elterveztem és ha voltak is nehéz pillanataim, idővel bármin átrágtam magam, de itt most nagyon elakadtam. Tud valaki segíteni abban, hogy ilyen esetben mi lenne a megoldás?

Előre is köszönök minden segítséget.
 
1

Relevans

janoszen · 2012. Szep. 5. (Sze), 06.13
Talan masold be a relevans kodot, ahol az autocompletet hozzaadod. :)
2

A kód

belvaros@freemail.hu · 2012. Szep. 5. (Sze), 09.32
Ez lenne a teljes kód:

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">

  <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  <script src="jquery-1.8.1.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

 </head>


<style type="text/css">

.ui-autocomplete
	{
	max-height: 160px;
	overflow-y: auto;
	overflow-x: hidden;
	padding-right: 20px;
	font-size: 13px;
	}

/* ie6 miatt (ott nincs max-height) */
 html .ui-autocomplete	{height: 160px;}

</style>



<? 
//települések beolvasása
$file_telepulesek=fopen("telepulesek_abc.csv","r") or print("<br>No file: telepulesek_abc.csv");
$s=0;
while (!feof($file_telepulesek))
	{
	$buffer = fgets($file_telepulesek, 4096);
	$adatok = explode(";",$buffer);
	if (strlen($adatok[0])>0)
		{
		$telep_lista[$s]=$adatok[0];
		$s++;
		}
	}
fclose($file_telepulesek);
?>



<script type="text/javascript">



function AddToList()
	{
	// $telep_lista php-tömb átalakítása js-tömbbé
	var lista = Array ("<?=implode("\",\"", $telep_lista); ?>");
	elem = document.getElementById('input_telep');

	if (jQuery.inArray(elem.value,lista) != -1) //ha az input_hely értéke egy létezõ település...
		{
		var kivalasztottak = document.getElementById('hd_kivalasztott_helyek').value;
		if (kivalasztottak.search(elem.value+',') >= 0)
			{alert('Ez a település már szerepel a listában.');}
			else
				{
				document.getElementById('span_helylista').innerHTML = elem.value + '<br>' + document.getElementById('span_helylista').innerHTML;
				document.getElementById('hd_kivalasztott_helyek').value = elem.value + ',' + document.getElementById('hd_kivalasztott_helyek').value;
				document.getElementById('hd_kivalasztott_helyek_szama').value = parseInt(document.getElementById('hd_kivalasztott_helyek_szama').value) + 1;

				var helyek_szama = parseInt(document.getElementById('hd_kivalasztott_helyek_szama').value);
				document.getElementById('div_kivalasztott_helyek').style.height = 16 + helyek_szama*16 + 'px';

				elem.value = '';
				elem.focus();
				}
		}
	}


// Enter NULL
function enterOnInput (field, event) {
		var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
		if (keyCode == 13) {
			var i;
			for (i = 0; i < field.form.elements.length; i++)
				if (field == field.form.elements[i])
					break;
			i = (i + 1) % field.form.elements.length;
			field.form.elements[i].focus();

			return false;
		}
		else
			return true;
	}
// Enter NULL vége



$(document).ready(function()
  {
  $('input#input_telep').autocomplete({source: ["<?=implode("\",\"", $telep_lista); ?>"]});
  });
</script>









<div id="div_kereses_sima" style="position:absolute; left:298px; top:40px; width:382px; height:60px; background:#9dacff; padding: 3px 5px; display:block;">
  

	<form name="form_kereses">

		<input type="hidden" name="hd_kivalasztott_helyek" id="hd_kivalasztott_helyek">
		<input type="hidden" name="hd_kivalasztott_helyek_szama" id="hd_kivalasztott_helyek_szama" value="0">

		<input type="text" name="input_telep" id="input_telep"
					style="width:140px; position:absolute; left:30px; top:3px; font-size:13px; font-family:arial; padding:2px 4px;"
					onkeypress="return enterOnInput(this, event)">


		<input type="button" name="button_AddToList" id="button_AddToList" value="&raquo;" onclick="AddToList()"
					style="width:32px; height:28px; position:absolute; left:171px; top:3px; font-size:13px; font-family:arial; padding:0px 4px;">


		<div id="div_kivalasztott_helyek"
         style="position:absolute; width:148px; height:14px; left:204px; top:3px; font-size:12px; font-family:arial; padding:2px 4px; background-color:#dfe4ff; border: #8899ee solid 1px;">
			<div id="div_kivalasztott_helyek_fejlec"
           style="position:relative; width:146px; height:12px; left:-3px; top:-1px; font-size:10px; font-family:verdana; color:#ffffff; padding:1px 3px; background-color:#aabbff; border: #99aaee solid 1px;">
				<b>Helység-lista</b>
			</div>
		
			<span id="span_helylista"></span>
		</div>

	</form>


</div>
Ez így önmagában nagyon szépen működik, de az alábbi kódból meghívva már nem:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2">
  <script src="jquery-1.8.1.min.js"></script>
 </head>


<script type="text/javascript">

function betolt()
	{
  jQuery(document).ready( function()  {jQuery("#div_felulet").load("div_kereses.php");} );
  }

</script>


<body>

<a href="#" style="text-decoration:none;">
  <div id="linkDiv"
       onClick="betolt()"
       style="top:0px; left:0px; height:19px; width:112px;">
    Egyszerû keresés
  </div>
</a>

<div id='div_felulet'></div>

</body>
</html>
Ezt gondolom valami olyasmi okozza aminek a működésére a kezdő js tudásommal még nincs rálátásom, vagy nagyon benéztem valamit... :)
(bocsi a sok külön style-ért, de így most könnyebb volt)
3

Ez így önmagában nagyon

Poetro · 2012. Szep. 5. (Sze), 09.51
Ez így önmagában nagyon szépen működik, de az alábbi kódból meghívva már nem

Milyen alábbi kódból? Ott nincsen sehol autocomplete. És ha már PHP-t használsz, miért implode, miért nem json_encode? Mert akkor az automatikusan elvégezni az escape-elést is.
4

Te vagy a JS szakértő :), így

belvaros@freemail.hu · 2012. Szep. 5. (Sze), 10.34
Te vagy a JS szakértő, így butaság lenne vitába szállnom veled :), de úgy vettem észre, hogy a div-be történő behívást követően az egy kvázi új oldalként kezelődik (pl. újra kell definiálni a használt karakterkészletet és sima változókat sem tudok bejuttatni, csak pl. GET vagy SESSION alapút), ezért nem szükséges a div tartalmát beállító .php-ben előzőleg újra meghívni a szkripteket, ha azok a div-be betöltött .php -ben már benne vannak. Ettől függetlenül - ahogy a bevezetőben is jeleztem - ezt a lehetőséget is kipróbáltam, de hiába, azaz akkor sem működik az autocomplete ha a div tartalmát beállító .php-ben hívom meg a szükséges szkripteket.

Ha jól emlékszem (homályos emlékek betöltése :) ) azért tértem át implode-ra json_encode -ról, mert a json_encode az UTF-8 -at szereti (vagy talán ezt csak összeálmodtam, de ez így most működik és ne menjünk bele abba, hogy UTF-8 vagy 8859-2 :) ). Az biztos, hogy nem emiatt nem megy :)
5

load callback

szabo.b.gabor · 2012. Szep. 5. (Sze), 11.09
szóval autocomplete-et akkor tudsz rárakni valamire, amikor már létezik.

$.load()

itt ugye van egy callback hívási lehetőség, ami akkor hívódik meg, amikor betöltődött a kért tartalom.

definiáld a callback-et és ott rakd rá az autocomplete-et.
8

Összejött, de máshogyan :)

belvaros@freemail.hu · 2012. Szep. 5. (Sze), 12.20
szabo.b.gabor:
Először is köszönöm a segítséget, bár szívtam a fogamat, mert elméletben pedzegettem mire gondolsz, de a gyakorlatba már nem tudtam átültetni (igen, kezdő vagyok, szamárpados :) ), ahhoz meg hirtelen nem volt pofám, hogy csak úgy elkérjem a komplett kódot :).

Ám de... :) Onnan jött a megoldás ahonnan nem vártam: egészen véletlenül arra vetemedtem, hogy a szkript hivatkozásban szereplő ajax.googleapis.com -os jQuery.ui helyett letöltsem a legújabb jQuery.ui -t és közvetlenül a szerverről hívjam meg. Nem gondoltam, hogy ez bármilyen változást hoz, de a legnagyobb meglepetésemre így már a div-be behívva is működik! :)
A miértről persze továbbra sincs fogalmam, ezért őszintén megköszönöm, ha szánsz rám pár percet és elmondod mi lett volna a Te megoldásod.


json_encode: gondolom arra céloztál, hogy Te is ezt tartanád kívánatosnak, de ezzel kapcsolatban azt nem értem, hogy miért használjak egy UTF-8 -as kódolású szövegekkel működő függvényt egy 8859-2 -es adatokra megírt lapon?
7

a div-be történő behívást

Poetro · 2012. Szep. 5. (Sze), 12.20
a div-be történő behívást követően az egy kvázi új oldalként kezelődik

Ez nem igaz. A betöltött tartalom aszinkron kerül be az oldalra, azaz egy külön HTTP kérés indul a szerver felé. Amint a válasz visszaérkezik, akkor az elérhető lesz a JavaScript számára. A szerver oldalról természetesen ez egy oldalletöltésnek számít, mivel egy HTTP kérés történik.

A jQuery az összes JavaScript kódot kiszedi a load-dal betöltött tartalomból. Ezért a load-dal betöltött tartalomba ne rakj JavaScript kódot, hacsak nem akarod azt te kézzel feldolgozni.

Összefoglalva: ne rakj script-et az AJAX-szal betöltött tartalomba, használd a load callback paraméterét, hogy inicializáld a betöltött tartalomra a viselkedést.

Másik dolog: A JavaScript csak UTF-8-at szereti, ezért jobb, ha abban van a JavaScripttel feldolgozandó dolog, hogy ne érjenek meglepetések. A legjobb természetesen, ha az egész oldal UTF-8.
9

Ez nem igaz. A betöltött

belvaros@freemail.hu · 2012. Szep. 5. (Sze), 12.41
Ez nem igaz. A betöltött tartalom aszinkron kerül be az oldalra, azaz egy külön HTTP kérés indul a szerver felé. Amint a válasz visszaérkezik, akkor az elérhető lesz a JavaScript számára. A szerver oldalról természetesen ez egy oldalletöltésnek számít, mivel egy HTTP kérés történik.

Értem és köszönöm, hogy kijavítottál, kezd kisimulni a dolog :)

A jQuery az összes JavaScript kódot kiszedi a load-dal betöltött tartalomból. Ezért a load-dal betöltött tartalomba ne rakj JavaScript kódot, hacsak nem akarod azt te kézzel feldolgozni.

No, ezt már nem értem... a "div_kereses.php" -ben van pl. az AddToList javascript függvény és most a div-be történő load után is úgy működik ahogyan kell, ahogy önmagában (load nélkül) meghívva is. Korábban is használtam már load-on belüli js-t, az első próbálkozástól kezdve minden böngészőn gond nélkül működik...

Összefoglalva: ne rakj script-et az AJAX-szal betöltött tartalomba, használd a load callback paraméterét, hogy inicializáld a betöltött tartalomra a viselkedést.

Ez az amit még sosem csináltam... ööö... nem béna, csak kezdő :)
De a kijelentésed elejét nem értem, mert éppen most sikerült a load-on belül elhelyezett <script> elem átírásával működésre bírni az autocomplete-t...

Másik dolog: A JavaScript csak UTF-8-at szereti, ezért jobb, ha abban van a JavaScripttel feldolgozandó dolog, hogy ne érjenek meglepetések. A legjobb természetesen, ha az egész oldal UTF-8.

Eddig csak sütikezelésnél futottam bele ebbe a problémába, de végül kikerültem úgy hogy nem kellettek a sütik (a mostanában terjengő hírek után nem is bánom). Mindenesetre köszönöm a jó tanácsot és megfontolom, bár eddig még szerencsére (lekopogom) nem volt vele gondom.
6

+1

szabo.b.gabor · 2012. Szep. 5. (Sze), 11.10
json_encode()