none
Auto-complétion javascript et récupération de colonnes multiples (autocomplete / getItemById)

    Question

  • Bonjour,

    Je cherche à améliorer l'expérience utilisateur en proposant, dans le formulaire d'une liste, l'auto-complétion javascript d'un champ via des informations extraites d'une autre liste.

    Objectif : j'ai une liste Etablissements de 70000 lignes avec les colonnes Nom, Adresse et Ville. Dans mon autre liste Interventions, j'ai un champ texte Etablissement. Je souhaiterai que les utilisateurs puissent renseigner l'établissement cible facilement : en tapant une partie du nom, de l'adresse ou de la commune, l'auto-complétion leur présenterait la liste des établissements correspondants sous la forme "Nom - Adresse - Ville".

    Pour ce faire, j'utilise les fonctions autocomplete et getItemById :

    <asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">
    	<SharePoint:DelegateControl runat="server" ControlId="FormCustomRedirectControl" AllowMultipleControls="true"/>
    	<SharePoint:UIVersionedContent UIVersion="4" runat="server"><ContentTemplate>
    		<SharePoint:CssRegistration Name="forms.css" runat="server"/>
    	</ContentTemplate></SharePoint:UIVersionedContent>
    	<SharePoint:ScriptLink Name="sp.js" runat="server" OnDemand="true" LoadAfterUI="true" Localizable="false"/>
    	<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"/>
    	<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
    	<script type="text/javascript" src="https://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
    	<script type="text/javascript" src="/_layouts/15/SP.RequestExecutor.js"></script>
    	<script type="text/javascript">
    		$(document).ready(function () {
                            var Etab_fieldID = '#'+$("[title='NomEtab']").attr("id")
    
    			$(Etab_fieldID).autocomplete({
    		    	minLength: 3,
    		        source: function (request, response) {
    		            var term = request.term.replace(/ /g, "*\",\"*");
    		            var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and(\"*" + term + "*\",path:\"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Etablissements\")'&enablefql=true";
    	    		    var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);
    
    			    executor.executeAsync({
    		    	        url: searchUrl,
    		    	        method: "GET",
    		    	        headers: { "Accept": "application/json; odata=verbose" },
    		    	        success: function (data) {
    		    	        	var jsonObject = JSON.parse(data.body);
    			    		var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
    			    			
    			    		var clientContext = new SP.ClientContext();
    			    		var ListeEtab = clientContext.get_web().get_lists().getByTitle('Etablissements');
    			    		var ItemEtab;
    							functionCall = $.map(
    								results,
    								function (result) {
    									ItemEtab = ListeEtab.getItemById(result.Cells.results[6].Value.split('=').pop());
    									var dfd = $.Deferred();
    									
    									clientContext.load(ItemEtab, 'Title', 'Adresse', 'Commune');
    										
    									clientContext.executeQueryAsync(
    										function () { dfd.resolve(ItemEtab); },
    										function (sender, args) { dfd.reject(args); }
    									);
    									
    									return dfd.promise();
    								}
    							);
    							
    							response(
    								$.when.apply ($, functionCall).done (
    									function() {
    										return {
    											label: ItemEtab.get_item('Title') + ' - ' + ItemEtab.get_item('Adresse') + ' - ' + ItemEtab.get_item('Commune'),
    											value: ItemEtab.get_item('Title')
    										};
    									}	
    								)
    							);
    						}
    		    	    });
    		        }
    			});	
    		});	
    	</script>
    </asp:Content>
    
    

    Le problème est qu'en Javascript, pour récupérer l'item d'une liste, il faut utiliser la fonction asynchrone executeQueryAsync.

    Du coup, si je retourne les valeurs sans deferred, elle sont undefined.

    J'en arrive (enfin !) à ma question : comment attendre que la fonction executeQueryAsync soit terminée pour retourner les valeurs label et value de l'event success de la fonction executeAsync ?

    Merci d'avance pour vos lumières :-)

    -Florent

    samedi 24 février 2018 11:02