# Problem mit jQuery Autocomplete



## Sirakov (6. Oktober 2009)

Morgen,

ich versuche das jQuery-Plugin Autocomplete zu integrieren, leider funktioniert es noch nicht. Hier den Code:


```
$('#input').autocomplete(function(term) {
        var searchUrl = urlBase + 'tagging/autocomplete/?term=' + term;  
	$.getJSON(searchUrl, function(jsonData) {
	    test = jsonData;
            console.log(test);
        });
    });
```

Die Ausgabe von console.log lautet z.B.:


```
["EBE", "EBE1", "EBE2"]
```
Diese Daten werden über PHP mittels


```
echo json_encode($words);
```
ausgegeben. Allerdings wird mir nichts vorgeschlagen. Kann es daran liegen, dass die Daten nicht in der Form

```
{"0" : "EBE", "1" : "EBE1", "2" : "EBE2"}
```
da liegen?


----------



## Sven Mintel (6. Oktober 2009)

Moin,

Der Autocompleter erwartet als 1. Argument entweder einen Array(so, wie du es in deinem Posting notiert hast), oder aber eine URL(das, was du brauchst.)

Du hast jedoch keines von Beidem, sondern eine Funktion ohne Rückgabewert.

Du musst also als 1. Argument nur die URL notieren.

Als Rückgabe wird kein JSON benötigt, sondern eine zeilenweise Auflistung der Einträge, wobei du dort getrennt durch ein *| * 2. Werte übermitteln kannst:

Der 1. ist in jedem Fall das, was in das Input übernommen wird(abgesehen von HTML-Tags zur Formatierung in der Dropdown-Liste)
Der 2. ist optional, dort kannst du einen value angeben, jener ist es, der beim Senden für das Input-Feld übertragen wird.

Wie so eine erwartete Rückgabe aussehen muss, kannst du hier sehen:
http://jquery.bassistance.de/autocomplete/demo/search.php?q=n&limit=10
(in den Quelltext schauen....da steht alles Zeile für Zeile).

Zugegeben...das ist nicht wirklich gut dokumentiert, was dort erwartet wird, und json wäre in der Tat etwas zeitgemässer 

Es bestände auch die Möglichkeit, über einen eigenen Callback-Handler bspw. JSON zu Verarbeiten, soweit ich dort gelesen habe.


----------



## SonMiko (27. August 2010)

Hm ich habs auch so eingebaut wie es im JQuery Kochbuch steht (mal davon abgesehen dass O'Reilly keinen wirklich brauchbaren Hinweis zum Aufbau der PHP Datei  gibt, hab ichs der Logik nachempfunden und eine Abfrage gestrickt). Das Lokale Array führt zum Erfolg wohingegen eine Source URL keine Ausgabe liefert. Auch der String den Du im Beispiel nennst scheint die Funktion nicht zu interessieren...

```
$("input[name=receiver]").autocomplete({
       source: "http://jquery.bassistance.de/autocomplete/demo/search.php"
    });
```

Die Abfrage:

```
_getReceiver.php?q=mi
```
Liefert folgendes Ergebnis:

```
michaela|michaela
miranda|miranda
```

Leider brachte auch dieser Beitrag keine Hilfe:
http://www.pengoworks.com/workshop/jquery/autocomplete_docs.txt

Ideen ?


----------



## rd4eva (27. August 2010)

> ...wohingegen eine Source URL keine Ausgabe liefert...source: "http://jquery.bassistance.de/autocomplete/demo/search.php"


Hinter autocomplete verbirgt sich im Endeffekt auch nur Ajax und diesem ist es nicht gestattet cross-Domain content zu laden.
Stichwort: Same origin Policy



> O'Reilly keinen wirklich brauchbaren Hinweis zum Aufbau der PHP Datei gibt


Da gibts auch nicht viel zu beachten.
Die PHP-Datei nimmt einen Get-Parameter entgegen und durchsucht dann ein Array / Mysql / oder sonstwas und liefert die passenden Ergebnise zurück. Wichtig ist dabei nur das am Ende Jedes Ergebnis in einer eigenen Zeile steht.


----------



## SonMiko (27. August 2010)

Hallo,

ich weiss - ich habe aber leider auch mit der lokalen URL keinen Erfolg.

```
$("input[name=receiver]").autocomplete({
       source:"content/_getReceiver.php"
    });
```
PHP-Datei:

```
while($row = mysql_fetch_assoc($res)){
                    echo $row['value_1']."|".$row['value_2']."\n";
                }
```

Es geht leider nicht...
Hat jemand eine Idee?

By the way: In der Doku zur Methode steht dass sie den Rückgabewert als JSON erwartet - auch wenn mein Büchlein etwas anderes behauptet...

Liebe Grüße,

Mike


----------



## rd4eva (28. August 2010)

> By the way: In der Doku zur Methode steht dass sie den Rückgabewert als JSON erwartet - auch wenn mein Büchlein etwas anderes behauptet...


Wo hast du das denn gelesen? Reden wir von dem selben autocomplete script?!


----------



## SonMiko (28. August 2010)

Nein ich spreche vom JQuery UI Autocomplete 
http://docs.jquery.com/UI/Autocomplete

Any Ideas?


----------



## Sven Mintel (28. August 2010)

Moin,

evtl. habe ich etwas überlesen, aber eingangs beschäftigte sich dieses Thema halt mit 
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/

du aber verwendest http://docs.jquery.com/UI/Autocomplete

Das sind verschiedene Baustellen.
Das von dir verwendete Plugin erwartet die Daten in Array-Form, das hast du schon korrekt festgestellt,...du lieferst die Daten aber nicht in dieser Form, denn dies:

```
while($row = mysql_fetch_assoc($res)){
                    echo $row['value_1']."|".$row['value_2']."\n";
                }
```
...erzeugt Zweifels ohne die Daten in dem Format, wie es das Plugin von bassistance.de erfordert.


----------



## SonMiko (28. August 2010)

Hm das hatte ich befürchtet...
Mit JSON bin ich leider Null vertraut...
Doof nur dass das JQuery Kochbuch (bzw. sein Autor) auf Seite 256 behauptet es seie eine einfache Source Angabe als String möglich und nichts weiter - doch dem scheint wohl leider nicht so zu sein.

Für alle die also mit dem Jquery UI Autocomplete arbeiten möchten und auch festhängen habe ich diese lange Lösung:
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-use-the-jquery-ui-autocomplete-widget/

Wenn jemand doch einen wirklich einfachen Weg kennt der keinen großen Aufwand erfordert bin ich ganz Ohr.

Hier nochmal der Verweis zur Doku:
http://docs.jquery.com/UI/Autocomplete


----------



## Sven Mintel (28. August 2010)

Es sind da diverse Sachen möglich.


			
				http://docs.jquery.com/UI/Autocomplete hat gesagt.:
			
		

> * an Array with local data
> * a String, specifying a URL
> * a Callback
> 
> ...



JSON ist halb so kompliziert.
Da du ja mit PHP arbeitest, brauchst du dort nur einen Array mit allen Strings erstellen, und ihn JSON-kodiert ausgeben. Dies geht sehr bequem per json_encode();


```
$strings=array('foo','bar','foobar');
die(json_encode($strings));
```


----------



## SonMiko (28. August 2010)

Hi,

ja soweit war ich schon:

```
echo json_encode($row['value'])."\n";
```
Auch mit oder ohne Komma - hat beides leider auch nicht funktioniert.
Das Buch sagt:
..."Als Antwort erwartet das Plugin eine Liste mit durch Zeilenumbruch getrennten Werten..."...

Jetzt lass uns das Ding mal ans laufen bringen - kann doch nicht sein dass es seit 2 Tagen nicht klappt . Bin drauf und dran ein Kopfgeld auf die funktionierende Version auszusetzen ...


----------



## Sven Mintel (28. August 2010)

1. Schmeisse dein Buch weg, die aktuellste Beschreibung findest du auf jquery.com
2. du sollst nicht jeden einzelnen Wert JSON-kodieren, sondern alle Werte in einem PHP-Array ablegen und diesen dann zum Schluss per json_encode() ausgeben


----------



## SonMiko (28. August 2010)

Das Buch ist super  - auch wenns dem schnellen Entwicklungsprozess von JQuery UI nicht standhalten kann sind die anderen Dinge sehr wohl brauchbar - ich empfehle es jedem der mit JQuery arbeiten möchte und wie ich auch den haptischen Aspekt beim lesen eines Buches wichtig findet - soviel dazu ...

Ja - habe ich auch versucht:

```
$array = array();
while($row = mysql_fetch_assoc($res)){
                    $array[] = $row['value'];
                }
                echo json_encode($array);
```
So wird das array korrekt dargestellt:
["michaela","miranda"] beim Aufruf: _getReceiver.php?q=mi
Allerdings funktioniert es immer noch nicht...

```
$("input[name=receiver]").autocomplete({
       source: "content/_getReceiver.php",
       minLength: 2,
       delay: 0
    });
```
... so schaut der JQuery Code aus...


----------



## Sven Mintel (28. August 2010)

Ich hab mal bei deinem Beitrag auf "zitieren" geklickt, und siehe, da erscheint das Problem



SonMiko hat gesagt.:


> So wird das array korrekt dargestellt:
> *&#65279;*["michaela","miranda"] beim Aufruf: _getReceiver.php?q=mi



Das rot markierte dort, das ist eine BOM.
Man sieht sie nicht, sie ist aber da, und verursacht den Fehler 

Lösung: Speichere die _getReceiver.php ohne BOM(solltest du in deinem Editor einstellen können)


----------



## SonMiko (28. August 2010)

Jetzt verstehe ich nichts mehr - hab kaum verstanden was ein BOM sein soll (http://de.wikipedia.org/wiki/Byte_Order_Mark).

Wenn du dir sicher bist, dann bitte schreib einmal auf wie es aussehen soll bevor wir den Beitrag auf 5 Seiten verlängern müssen und die Datenbank ärgern - das wäre super hilfreich.

Was soll ich nun tun? Einen header setzen und eine Kodierung vorgeben? Und bitte was soll nun dieser BOM sein? Aus der Wikipedia Definition werde ich nicht wirklich schlau.

(Ich bin sicher wenn wir das Problem hier mit Lösung ausschreiben, werden andere Menschen die durch Google oder die Forensuche auf diesen Thread aufmerksam werden, auch zufrieden sein wenn sie beispielsweise dasselbe Problem haben).

Für alle die auch nicht wissen was ein BOM ist:


> Als Byte Order Mark (BOM, dt. „Bytereihenfolge-Markierung“) wird das Unicode-Zeichen U+FEFF (zero-width non-breaking space) am Anfang eines Datenstroms bezeichnet, wo es als Signatur zur Definition der Byte-Reihenfolge und Kodierungsform in UCS/Unicode-Zeichenketten verwendet wird. http://de.wikipedia.org/wiki/Byte_Order_Mark



Und wie wird man es los ?

Liebe Grüße


----------



## Sven Mintel (28. August 2010)

Das hier:

*&#65279;*

Das ist die HTML-Notation für eine BOM.

...klicke bei deinem Beitrag http://www.tutorials.de/javascript-ajax/348327-problem-mit-jquery-autocomplete-2.html#post1893812 auf "zitieren", es steht da. Ich habs nicht dahin gepackt, und es hat da auch nichts zu suchen.


----------



## SonMiko (28. August 2010)

Also schreibe ich quasi eine Regex oder filtere aus dem Array schlichtweg den Wert (oder nicht Wert) "" raus und es sollte gehen?...
Leider nein - wenn ich das Produkt als String übergebe und diesen durchsuche werde ich nicht fündig - bzw. der Falschbytewert ist nicht auffindbar. Was kann ich nun tun?
Wie kann ich den ekligen Zusatz los werden?


----------



## SonMiko (28. August 2010)

Ist doch totaler Mist...  - egal was ich tue, dieses Bytezeugs bleibt da - hat PHP keine Funktionen dafür oder JQuery bzw. JavaScript?


----------



## Sven Mintel (28. August 2010)

Das ist keine Frage von PHP oder Javascript, die Ursache musst du in deinem Editor suchen, mit dem du die Datei erstellst/bearbeitest.


----------



## SonMiko (28. August 2010)

Wie kann ich es finden/ sehen/ erkennen?
Was muss ich beachten? Ich weiss dass ich die Datei als UTF8, ANSI oder sonst was speichern kann - was sei hierbei gewählt? Ich nutze eigentlich immer UTF 8...
Ich habe alles durchsucht und habe keine Ahnung wie ich diese Bytes vermeiden kann - das ist deprimierend weil ich nach etwas suche das mit partout nicht angezeigt wird.
Ich habe den Code nun ver-hässlicht und sämtliche Leerzeichen oder Tabs vermieden, alles ist nun unübersichtlich am Rand...
Trotzdem kein Erfolg.


----------



## Sven Mintel (28. August 2010)

Wie du das abstellen kannst, wäre einfacher zu Beantworten, wenn du verrätst, welchen Editor du nutzt.


----------



## SonMiko (28. August 2010)

PHPDesigner nutze ich, und/ oder auch Notepad. Ich kann auch gerne Notepad++ nutzen...


----------



## Sven Mintel (28. August 2010)

SonMiko hat gesagt.:


> das ist deprimierend weil ich nach etwas suche das mit partout nicht angezeigt wird.



Erstelle dir ein weiteres PHP-Skript 

```
<?php
echo htmlentities(file_get_contents('http://server.tld/content/_getReceiver.php?term=a'));
?>
```
(Beachte den Pfad, die URL muss unbedingt per HTTP angefordert werden )

Dieses Skript rufe im Browser auf. Vor dem eigentlichen Array solltest du komische Zeichen sehen, diese sind das Übel...wenn sie weg sind, sollte alles wie gewünscht gehen.

Von deinen Editoren nutze ich keinen, ein kurze Googelei hat aber bspw. für den PHPDesigner ergeben, dass man diese Einstellung im Files/Preferences Menu vornehmen kann.

Damit die Änderungen auch sichtbaren Erfolg zeigen, nehme vorrübergehend folgende Änderung am Aufruf vor:

```
$("input[name=receiver]").autocomplete({
       source: "content/_getReceiver.php?t="+new Date().getTime(),
       minLength: 2,
       delay: 0
    });
```


----------



## SonMiko (28. August 2010)

Ah - der Hinweis mit der PHP Datei ist sehr brauchbar - danke vielmals******
Ich kann das Dateiformat auf Windows, Unix oder MAC stellen (Windows ist ausgewählt).
Die Enkodierungsoptionen sind ANSI, darunter UTF-8, UTF-16 LE, UTF-16 BE.
Darunter gibts dann noch die Option "speichere mit BOM" - klicke ich diese an, beschwert sich PHP das die Session nicht erneut gestartet werden kann


> session_start() [function.session-start]: Cannot send session cache limiter - headers already sent



Dein Aufruf mit dem t Parameter funktioniert leider auch nicht wirklich ...

Ich will aber irgendwie auch nicht nerven mit dem Thema - vielen Dank Dir für die viele Mühe und die vielen Antworten.


----------



## SonMiko (28. August 2010)

Das Script läuft nun nach langer Zeit endlich wie es soll:
Ich hatte in dem aufzurufenden Script Dateien "included" welche wohl für den BOM verantwortlich waren. Das umgehe ich nun indem ich die Daten direkt in die Datei schreibe.
Dann habe ich durch Firebug erkannt das der GET String nicht "q" sondern "term" lautet.

Ich habe natürlich versucht den part mit dem Include zu belassen und dachte es läge nur an dem falschen Get-Namen, aber es war tatsächlich auch der BOM schuld.

Nun funktioniert das Script so wie es soll und ich bin sehr zufrieden.

Vielen Dank für die Hilfe und besten Gruß,

Euer Mike


----------

