Valider c420ccd5 rédigé par rastapopoulos@spip.org's avatar rastapopoulos@spip.org
Parcourir les fichiers

Un premier jet à tester pour rendre le sélecteur générique *vraiment*...

Un premier jet à tester pour rendre le sélecteur générique *vraiment* générique, c'est-à-dire sans recoder un JS personnalisé à chaque fois.

Le principe est de déclarer le sélecteur à utiliser pour une autocomplétion directement dans le HTML avec un attribut personnalisé.

<input name="truc" data-selecteur="bidule" />
activera l'autocomplétion sur ce champ en utilisant le squelette "selecteurs/bidule.html".

Les sélecteurs utilisés avec ce système doivent renvoyer un tableau JSON comme l'indique la doc de UI.autocomplete : la liste contient des chaînes simples ou des tableaux avec les clés "label" et "value".

En sus, il est possible de gérer une liste multiple dans le champ texte en ajoutant l'attribut "multiple" au HTML : dans ce cas seul le dernier terme après la dernière virgule sera envoyé au sélecteur pour la recherche :
<input name="tags" data-selecteur="mes_tags" multiple="multiple" />

En sus de sus, il est possible de personnaliser le comportement qui s'activera lors de la sélection d'un élément dans la liste : il suffit alors de déclarer le nom de la fonction JS à appeler dans le HTML :
<input name="truc" data-selecteur="bidule" data-select-callback="ma_fonction_de_selection" />

Cette fonction reçoit les arguments (event, ui) et le tableau décrivant le résultat sélectionné se trouve dans "ui.item".
parent 0bc9bf02
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+1 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
* text=auto !eol
action/api_selecteur.php -text
exec/selecteur_generique.php -text
javascript/jquery.ui.autocomplete.html.js -text
javascript/selecteur_generique_functions.js -text
+37 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

// Sécurité
if (!defined('_ECRIRE_INC_VERSION')) return;

/*
 * Retourner un JSON listant les résultats d'une recherche de chaîne pour une autocomplétion
 *
 * Le format a retourner est décrit ici : http://jqueryui.com/demos/autocomplete/
 * Liste de résultats où chacun peut être soit une chaîne soit un tableau.
 * Si c'est un tableau alors la clé "label" correspond à ce qui est affiché dans le sélecteur, tandis que la clé "value" correspond à ce qui sera placé dans le champ.
 * Si c'est une chaîne, la même chose sera affiché dans le sélecteur et inséré dans le champ.
 * array('machin', 'truc', array('label' => 'Un mot', value => 123))
 */
function action_api_selecteur_dist() {
	// Il faut au moins le sélecteur dans l'argument sinon rien
	if (!$selecteur = _request('arg')){
		header('Status: 404 Not Found');
		exit;
	}
	
	// On cherche le JSON en passant les params de l'URL
	if ($json = recuperer_fond("selecteurs/$selecteur", $_GET)){
		// On renvoie une ressource JSON
		header('Status: 200 OK');
		header("Content-type: application/json; charset=utf-8");
		echo $json;
		exit;
	}
	// Si on ne trouve rien c'est que ça n'existe pas
	else{
		header('Status: 404 Not Found');
		exit;
	}
}

?>
+88 −4
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -21,10 +21,94 @@ var selecteur_format = function(data){
	return parsed;
}

function split_multiple(val){
	return val.split( /;\s*/ );
/*
 * Découper une chaine en tableau suivant un séparateur
 *
 * @param string val Chaîne de caractère à découper
 * @param string sep Chaîne considérée comme le séparateur de la liste (par défaut ";" pour garder la compatibilité)
 * return array Retourne une liste de chaînes, sans espaces autour
 */
function split_multiple(val, sep){
	if (!sep){ var sep = ';' }
	sep = '\\s*' + sep + '\\s*';
	//console.log(sep);
	return val.split(new RegExp(sep));
}

/*
 * Renvoie le dernier terme d'une liste caractérisée par un séparateur
 *
 * @param string list Chaîne de caractères constituée d'une liste de termes séparés par un séparateur quelconque
 * @param string sep Chaîne considérée comme le séparateur de la liste
 * @return string Retourne le dernier terme de la liste
 */
function extractLast(list, sep) {
	return split_multiple(list, sep).pop();
}

/*
 * Chercher et appliquer l'autocomplétion sur les champs déclarés comme tel
 */
(function($){
	// Comportement par défaut lors de la sélection dans l'autocomplétion
	var selecteurgenerique_select_callback_dist = function(event, ui){
		// Si le champ est déclaré comme "multiple" on ne remplace que la fin
		if ($(this).attr('multiple')){
			// On récupère la liste des termes séparés par une VIRGULE (cas le plus courant)
			var terms = split_multiple(this.value, ',');
			// On supprime le terme qui était en train d'être tapé
			terms.pop();
			// On ajoute à la fin ce qui a été sélectionné
			terms.push(ui.item.value);
			// On ajoute une entrée vide pour avoir le séparateur lors de la jointure
			terms.push("");
			// On joint tout les termes
			this.value = terms.join(", ");
		}
		// Sinon on remplace tout
		else{
			this.value = ui.item.value;
		}
		
		return false;
	};
	
	var selecteurgenerique_chercher_selecteurs = function(){
		// chercher tous les inputs déclarés explicitement comme sélecteurs
		var inputs = $('input[data-selecteur][autocomplete!=off]');
		var api = 'selecteur.api/';
		if (selecteurgenerique_test_espace_prive){ api = '../' + api; }
	
function extractLast( term ) {
	return split_multiple( term ).pop();
		inputs.each(function(){
			// L'input en question
			var me = $(this);
			// Quel sélecteur appeler
			var quoi = me.data('selecteur');
			var select_callback = me.data('select-callback');
			if (!select_callback){ select_callback = selecteurgenerique_select_callback_dist; }
			
			me
				// appliquer l'autocomplete dessus
				.autocomplete({
					source: function(request, response) {
						if (me.attr('multiple')){ var term = extractLast(request.term, ','); }
						else { var term = request.term; }
						//console.log('"'+term+'"');
						$.getJSON(api+quoi, {q:term}, response);
					},
					delay: 300,
					html: true,
					select: select_callback,
					focus: function(event, ui){
						// prevent value inserted on focus
						return false;
					}
				});
		});
	};
	
	$(function(){
		selecteurgenerique_chercher_selecteurs();
		onAjaxLoad(selecteurgenerique_chercher_selecteurs);
	});
})(jQuery);
+1 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<paquet
	prefix="selecteurgenerique"
	categorie="outil"
	version="0.7.3"
	version="0.8.0"
	etat="dev"
	compatibilite="[3.0.0;3.0.99]"
	documentation="http://www.spip-contrib.net/Selecteur-generique"
+2 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -5,6 +5,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return;
/**
 * Vérifier la présence des scripts nécessaires au sélecteur générique dans une page
 * @param string $flux Le contenu de la page
 * @return string Retourne une liste de <script> et de <link> à insérer dans le <head> de la page
 */
function selecteurgenerique_verifier_js($flux){
	$contenu = "";
Chargement en cours