AutoComplete et KeyValuePair - associer une clé lors de l'utilisation du toolkit AutoCompleteExtender
Le toolkit AutoComplete des ajax toolkits permet d'étendre une textbox afin de lui apporter l'autocomplétion.
Dans la plupart des cas, on aimerait bien pouvoir récuperer un identifiant plutôt que de refaire une requête couteuse qui cherche l'identifiant à partir du nom.
Prenons un exemple : j'ai besoin de saisir une ville. Pour faciliter la vie à l'utilisateur je lui propose une textbox avec autocomplétion. Avec les anciennes versions des toolkits, on devait refaire une requête couteuse pour récupérer l'id de la commune. A partir de la version 1.0.10920.0, l'autoComplete permet d'associer une paire de clé / valeur.
Cela se passe en 2 temps : tout d'abord il vous faut concaténer les 2 valeurs avec la méthode AutoCompleteExtender.CreateAutoCompleteItem(value, key);
[WebMethod]
public String[] GetCities(string prefixText, int count)
{
List<String> cities = new List<string>();
using (SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using (SqlCommand command = new SqlCommand(String.Format(@"
SELECT TOP {0}
INSEECode,
NCCENR
FROM comsimp2007
WHERE NCCENR like @CityName + '%'", count), conn))
{
command.Parameters.Add("@CityName", System.Data.SqlDbType.NVarChar).Value = prefixText;
conn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
cities.Add(AutoCompleteExtender.CreateAutoCompleteItem(
(String)reader["NCCENR"], (String)reader["INSEECode"]));
}
}
conn.Close();
}
return cities.ToArray();
}
Puis dans l'extender s'abonner à un nouvel événement côté client : OnClientItemSelected. Cet événement permettra de récupérer la clé en JavaScript, libre à nous d'enregistrer cette clé dans un champ caché pour pouvoir y acceder lors du prochain PostBack.
<asp:TextBox runat="server" ID="tbCity" Width="300" />
<asp:HiddenField runat="server" ID="hfInseeCode" />
<ajaxToolkit:AutoCompleteExtender
runat="server"
BehaviorID="AutoCompleteEx"
ID="autoComplete1"
TargetControlID="tbCity"
ServicePath="AutoComplete.asmx"
ServiceMethod="GetCities"
OnClientItemSelected="tbCity_ClientItemSelected"
MinimumPrefixLength="2"
CompletionInterval="1000"
EnableCaching="true"
CompletionSetCount="20"
CompletionListCssClass="autocomplete_completionListElement"
CompletionListItemCssClass="autocomplete_listItem"
CompletionListHighlightedItemCssClass="autocomplete_highlightedListItem"
DelimiterCharacters=";, :">
</ajaxToolkit:AutoCompleteExtender>
<script type="text/javascript">
var tbCity_ClientItemSelected = function(sender, e){
$get('<%=hfInseeCode.ClientID %>').value = e.get_value();
}
</script>
Lors du postback, hfInseeCode contiendra le code INSEE de la ville sélectionné.
Attention tout de même puisque l'utilisateur peut toujours modifier la valeur du textbox sans passer par l'autocomplétion, pour contourner ce problème on peut s'abonner à l'événement keypress de la textbox et vider le champ caché.
$addHandler($get('<%=tbCity.ClientID%>'), 'keypress', function(){
$get('<%=hfInseeCode.ClientID %>').value = '';
});
Coté serveur il faudra d'abord tenter de récupérer l'id de la ville grâce au champ caché et s'il est vide alors on fera une recherche couteuse.
Il y a également d'autres nouveautés au menu de l'autoCompleteExtender, comme par exemple l'ajout d'événements pour les animations et la possibilité de personnaliser plus facilement la liste de suggestion.
PS : Merci à Christian pour avoir bloggé comment récuperer la liste des villes française ;-)