# Frage zu JQuery Autocomplete



## Tiger2009 (14. März 2011)

Hallo,

ich versuche gerade mit JQuery eine Autocompletefunktion umzusetzen.
Zuerst habe ich das mit Standardwerten gemacht:


```
<html>
<head>		
	<title>
		<div lang=de>Test</div>
		<div lang=en>test</div>
	</title>
  <script src="/prototype/jquery/jquery-latest.js"></script>
  <link rel="stylesheet" href="/prototype/jquery/main.css" type="text/css">
  <link rel="stylesheet" href="/prototype/jquery/jquery.autocomplete.css" type="text/css">
  <script type="text/javascript" src="/prototype/jquery/jquery.bgiframe.min.js"></script>
  <script type="text/javascript" src="/prototype/jquery/jquery.dimensions.js"></script>
  <script type="text/javascript" src="/prototype/jquery/jquery.autocomplete.js"></script>
  
  <script type="text/javascript">
    $(document).ready(function(){
       var data = "München Mailand Berlin".split(" ");
       $("#example").autocomplete(data);
    });
  </script>
</head>
<body>	
	Test: <input id="example" name="example" type="text" value=""> 
</body>
</html>
```

Das funktionierte so auch problemlos.
Nun hänge ich aber im nächsten Schritt. Die Auswahlmöglichkeiten sollen dynamisch vom Server befüllt werden. Dafür habe ich den JavaScript teil wie folgt angepasst:


```
<script type="text/javascript">
  $(document).ready(function(){
	$("#example").autocomplete("testrequest?ACTION=getValues", {});	
  });  
  </script>
```

Hier hänge ich nun ...
Soviel ich herausgefunden habe muss in die geschweifte Klammer nun ein formatResult und ein parse Befehl.
Leider weiß ich nicht genau wie ich das umsetzen muss:

Der Server schickt auf testrequest eine html template welches wie folgt aufgebaut ist:

```
<div id=results>
"Test1",
"Test2",
"Test3",
"Test4",
</div>
```

Wäre klasse wenn ihr mir bei der Erstellung der formatResult und parse Funktion helfen könntet.

Den aufbau des Requests kann ich selbst bestimmen. Falls es einfacher zu parsne ist kann ich da auch z.B. Wert1, Wert2, Wert3, ... nehmen

Viele Grüße


----------



## CPoly (15. März 2011)

Eigentlich ist es in der Dokumentation sehr gut beschrieben. Dort sind sogar sehr viele Beispiele.


```
$("#example").autocomplete({source: "testrequest?ACTION=getValues"});
```

und die Rückgabe könnte der Einfachheit so aussehen


```
["Test1","Test2","Test3","Test4"]
```

Edit: Handelt es sich überhaupt um das offizielle jQuery UI autocomplete? Falls nicht, müsstest du natürlich schon erwähnen, welches Plugin du verwendest.


----------



## Tiger2009 (15. März 2011)

Hi,

es handelt sich um das hier:
http://docs.jquery.com/Plugins/Autocomplete/autocomplete
Denke das ist schon das offizielle.

Bin auch schon ein wenig weitergekommen.

Wenn ich folgenden Code verwende bekomme ich wenigstens schonmal alle Städte mit A angezeigt.


```
$(document).ready(function(){				
				$("#example").autocomplete("testrequest?ACTION=getValues",                                                                                       {				
					  minChars: 1,
                       extraParams: {
					    'city': 'a'
					  }
         			});				
				
	  });
```

Mein Problem ist nun das es zwar so statisch geht wenn ich als Parameter 'city' : 'a'
 angebe, aber eigentlich will ich hier ja nicht 'a' sondern den Inhalt des Input-Feld.

Eigentlich müsse das ja dann so gehen


```
'city': $("#example").val()
```

Leider geht das nicht. Habt ihr eine Idee?


----------



## CPoly (15. März 2011)

> with a GET parameter named q that contains the current value of the input box



Also benutze auf dem Server "q" und nicht "city".

Und falls du unbedingt "city" willst, dann verweise ich nochmal auf die Dokumentation



> extraParams:
> Extra parameters for the backend. If you were to specify { bar:4 }, the autocompleter would call my_autocomplete_backend.php?q=foo&bar=4 (assuming the input box contains "foo"). The param can be a function that is called to calculate the param before each request.



Besonders der letzte Satz. Daraus folgt:


```
$("#example").autocomplete("testrequest?ACTION=getValues", {              
    minChars: 1,
    extraParams: {
        'city': function() {
            return $("#example").val();
        }
    }
});
```


----------



## Tiger2009 (15. März 2011)

CPoly hat gesagt.:


> Also benutze auf dem Server "q" und nicht "city".
> 
> Und falls du unbedingt "city" willst, dann verweise ich nochmal auf die Dokumentation
> 
> ...



Danke so gehts!

Ich bin sooooooooooo blöd 

Ich habe das schon auch so mit der function versucht aber anstatt von .val() habe ich .value() verwendet


----------



## Tiger2009 (15. März 2011)

Ein kleines Problem habe ich noch. Mein Response-Template ist wie folgt aufgebaut:

```
<div id="city">Aachen</div>
<div id="city">Augsburg</div>
<div id="city">Amsterdam</div>
...
```

Sobald ich ein Ergebniss auswähle übernimmt er mir jedoch die komplette Zeile in das Inputfeld.
Ich denke hierfür benötige ich nun die formatResult-Option



> formatResult	Function	Default: Assumes either plain data to use as result or uses the same value as provided by formatItem.
> Similar to formatItem, but provides the formatting for the value to be put into the input field. Again three arguments: Data, position (starting with one) and total number of data.



Ich verstehe leider noch nicht genau wie ich die anzuwenden habe.


----------



## CPoly (15. März 2011)

Ich tippe mal so:


```
formatResult: function(data) {
    return data.replace('<div id="city">').replace('</div>');
}
```

Das ist aber sehr unschön. Du solltest es genau umgekehrt machen. Deine Rückgabe sollte auf jegliches HTML verzichten (bei autocomplete kommt es auf jedes byte an) und mittels formatItem dann das HTML hinzufügen. Denn im Moment sendest du bei jeder Eingabe redundant für jedes Element genau das gleiche Markup mit


----------



## Tiger2009 (15. März 2011)

CPoly hat gesagt.:


> Ich tippe mal so:
> 
> 
> ```
> ...


 
Ich kann leider nicht komplett auf HTML Verzichten da ich oben im Template ein Identifikation für die Sprache benötige. Aber das ist denke ich nicht so schlimm mein Response sieht nun wie folgt aus:


```
<div lang="de"></div>
<div lang="en"></div>
["Aachen","Augsburg","Amsterdam"]
```

Das wäre die von dir gewünschte Struktur oder?

Nun muss ich mittles formatItem die Ergebniss definieren oder?


----------



## CPoly (15. März 2011)

Tiger2009 hat gesagt.:


> Das wäre die von dir gewünschte Struktur oder?



Nein, da dachte ich noch, du würdest das jQuery UI autocomplete benutzen. Das hat meiner Meinung nach eine wesentlich bessere API als dieses Plugin. Ich hab nichtmal den Download Link gefunden und hab mir den Code aus dem Beispiel geholt...

Was hat es denn jetzt mit den ersten beiden Zeilen auf sich? Wozu brauchst du dort die lang Attribute? Das verstehe ich nicht ganz.


----------



## Tiger2009 (15. März 2011)

CPoly hat gesagt.:


> Nein, da dachte ich noch, du würdest das jQuery UI autocomplete benutzen. Das hat meiner Meinung nach eine wesentlich bessere API als dieses Plugin. Ich hab nichtmal den Download Link gefunden und hab mir den Code aus dem Beispiel geholt...
> 
> Was hat es denn jetzt mit den ersten beiden Zeilen auf sich? Wozu brauchst du dort die lang Attribute? Das verstehe ich nicht ganz.



Die 2 lang Attribute werden von der Servlet-Engine verwendet um die Templates auszuwerten.
Kenne mich damit leider nicht so gut aus da dieser Teil schon ein paar Jährchen alt ist 
Wie auch immer.

Danke nochmals für die Hilfe. Habe das formatResult noch ein wenig anpassen müssen.
Aber nun funktioniert es wie gewünscht.


```
formatResult: function(data) {    				
  return data.toString().replace('<div id="city">','').replace('</div>','');
}
```


----------



## Tiger2009 (15. März 2011)

Grrrrrrrrrrrr

Ich bin nochmals über ein Problem gestolpert ......... Umlaute.
Bei der Server-Response habe ich keine Probleme, z.B. wenn ich 'Sa' eingebe, dann bekomme ich auch Saarbrücken problemlos zurück und dies wird auch korrekt dargestellt.

Mein Problem ist nun der Request. Wenn ich z.B. 'Mü' eingebe bekomme ich keine Serverantwort.
Ich habe auch schon versucht ü in &uuml; per replace umzuwandeln. Aber das &uuml; ist ja glaube ich nur die HTML-Darstellung. Ich weiß jetzt leider nicht in was ich die Umlaute umwandeln muss.


Wenn ich "testrequest?ACTION=getValues&city=mü" direkt in den Browser eingebe, wandelt er es in
"testrequest?ACTION=getValues&city=m%FC" um und ich bekomme die korrekten Ergebnisse.

Einzigst per Ajax will es nicht klappen.

Jemand ne Idee?


----------



## Maniac (15. März 2011)

Ich würde mal sagen das dir hier entweder "unescape()" oder "encodeUri()" weiterhelfen könnte.


----------



## CPoly (15. März 2011)

Funktioniert es so?


```
extraParams: {
        'city': function() {
            return encodeURIComponent($("#example").val());
        }
    }
```

Aber eigentlich sollte das von sebst funktionieren, denn das autocomplete Plugin verwendet intern auch nur $.ajax, und $.ajax wiederrum verwendet intern encodeURIComponent.


----------



## Tiger2009 (15. März 2011)

Danke euch beiden.
Hat leider beides nicht geholfen.


----------



## Tiger2009 (15. März 2011)

Noch jemand ne Idee zum encoding Problem ?

hab jetzt mal einen break-point in der Serverklasse gesetzt wo ich den Request auswerte und da bekomme ich anstatt von "Mü" "mÃ¼". Nun ist die Frage inwiefern mir das weiterhilft


----------



## Maniac (16. März 2011)

Ist deine Datei denn UTF8 Codiert?


----------



## Tiger2009 (16. März 2011)

Maniac_81 hat gesagt.:


> Ist deine Datei denn UTF8 Codiert?


 
Gute Frage 

Ich habe im Html-Header folgendes angegeben:


```
<html>
<head>
	<meta http-equiv="content-type" content="text/html"; charset="UTF-8">	
	<title>
```

das müsste doch langen damit die Datei UTF-8 codiert ist oder ?


----------



## Tiger2009 (16. März 2011)

Habe mal eine neue Testseite gemacht wo nur das wichtigste drin ist, vielleicht hab ich da schon einen Fehler 


```
<html>
	<head>
		<meta http-equiv="content-type" content="text/html"; charset="UTF-8">	
		<title>
			<div lang=de></div>
			<div lang=en></div>
		</title>		
		<script src="/prototype/scriptaculous190/lib/prototype.js" type="text/javascript"></script>	
		<script src="/jquery/jquery-latest.js"></script	 
	  
		<script type="text/javascript">				
		jQuery.noConflict(); 		  	
  		try {	  			
                        jQuery.ajax({ type: "GET",   
         		url: "testrequest?ACTION=getValues&city=mü",            		
         		contentType: "charset=UTF-8",
        		async: false,
        		success : function(text) {
                            alert(text);
       		        }
			}); 				  			
  		} catch(err) {
  			alert('Error ' + err);
  		}
		</script>
	</head>	  		
	<body>
		test
	</body>
</html>
```


----------



## Maniac (16. März 2011)

Ich dachte eher wie dein Dokument abgespeichert ist. Speichern unter -> datei typ/codierung "utf8" und nicht ansi/asci


----------



## Tiger2009 (16. März 2011)

Habe es als UTF-8 gespeichert. Im UltraEdit steht unten U8-Dos


----------



## Tiger2009 (16. März 2011)

Hm 

Wenn ich folgendes verwende liefert er mir die korrekten Werte zurück.


```
jQuery.ajax({ type: "GET",   
    url: "testrequest?ACTION=getValues&city=m%FC",            		
    contentType: "charset=UTF-8",
    async: false,
    success : function(text) {
       alert(text);
     }
});
```

Eigentlich müsste ich doch nun "nur einen Parser" schreiben der mit die Umlaute in die entsprechenden URL ASCII set umwandelt oder gibt es da bessere Lösungen ?

Müsste dann so etwa aussehen:


```
jQuery("#example").autocomplete("testrequest?ACTION=getValues", {
  minChars: 2,
  max: 1000,
  extraParams: {												
	'city': function() {	            
	  return jQuery("#example").val().toString().replace('ü', "%FC");
  	}  		      
  },
  formatResult: function(data) {    								
    return data.toString().replace('<div id="city">','').replace('</div>','');
  }
});
```

Nun habe ich nur das Problem das er mir das als String anhängt 
Beim Server kommt also %FC raus und kein ü


----------



## Tiger2009 (16. März 2011)

Wenn ich es wie folgt hart in die URL codiere funktioniert es auch beim Autocomplete.
Das Pronlem entsteht also bei den extraParams.


```
jQuery("#example").autocomplete("testrequest?ACTION=getValues&city=m%FC", {
    contentType: "charset=UTF-8",	
    minChars: 2,
    max: 1000,
    /*
    extraParams: {												
      'city': function() {	            
         return jQuery("#example").val().toString().replace('ü', '%FC');
       }  		      
     },
     */
     formatResult: function(data) {    								
       return data.toString().replace('<div id="city">','').replace('</div>','');
    }
});
```

Jemand ne Idee wie ich das mit extraParams lösen könnte? Wenn ich das richtig erkenne ist das Problem das extraParams einen String an die URL hinzufügt.


----------



## Tiger2009 (17. März 2011)

Puh, ich habe einiges probiert aber es immernoch nicht hinbekommen.

Problem ist einfach wenn ich bei der Autocompletefunktion in der URL Umlaute habe werdem diese problemlos korrekt an den Server übermittelt und vom Server verarbeitet.

Habe ich jedoch in dem Feld extraParams Umlaute so bekomme ich diese nicht korrekt an den Server übermittelt. Leider brauche ich diese dynamischen Werte da der Server ja aufgrund der Eingabe im Textfeld die entsprechenden Werte zurückliefern soll.

Wäre echt klasse wenn hier noch jemand eine Idee hätte.

Vielen Dank


----------

