Select2

Select2 est une librairie Javascript / jQuery qui améliore l’usage des sélecteurs (balises <select>) natifs des navigateurs en facilitant entre autres la recherche d’un terme dans la liste. Ce plugin intègre Select2 dans SPIP.

Fonctionnement

Une fois le plugin activé, Select2 est actif dans l’espace privé pour toutes les balises <select> ou <input> ayant la classe CSS .select2.

La configuration (Menu : Squelettes > Select2) permet de compléter les sélecteurs sur lesquels le plugin doit s’appliquer automatiquement.

Il est possible d’activer Select2 sur l’espace public automatiquement aussi, depuis cette configuration.

Important : L’identifiant (l’attribut id) de la balise select ou input doit être unique sur la page ; Select2 ne peut s’activer qu’une fois par identifiant (le dernier appelé).

Tester

Une page de test (en lien depuis la configuration) permet de visualiser quelques exemples de sélecteurs uniques et multiples avec diverses configurations. Son code source est le fichier dans prive/squelettes/contenu/tester_select2.html du plugin.

Capture de la page de test de Select2 en SPIP 4.2

Exemple de HTML / SPIP

#SET{id,u4}
<div class="editer pleine_largeur">
	<label for="demo_#GET{id}">Ajax Search</label>
		<select class="select2" name="demo_#GET{id}" id="demo_#GET{id}"
			data-placeholder="Sélectionnez une ville..."
			data-ajax-url="[(#URL_API{select2_autocomplete,demo/city}|attribut_html)]"
			data-minimum-input-length="1"
		>
			<option value="">Sélectionnez une ville...</option>
		</select>
</div>

Exemple avec Saisies

Cet exemple utilise les plugins Saisies et Pays. Il suffit d’ajouter l’option class=select2 à la balise #SAISIE :

[(#SAISIE{pays, pays, 
	label=<:utilisateurs:label_recherche_pays:>,
	option_intro=<:utilisateurs:option_tous:>,
	multiple=oui,
	class=select2,
})]

Compléter la configuration par défaut

Select2 dispose de 2 manières d’adapter sa configuration, par Javascript, ou par attributs HTML

En appelant directement une méthode javascript

  • soit la fonction jQuery .select2() de la librairie d’origine, et en lui transmettant des options
  • soit la fonction jQuery .spip_select2() qui enrichit la précédente
  • soit SpipSelect2.on_select(select, options), dont la fonction jQuery .spip_select2 est un alias
  • soit SpipSelect2.on_input(input, options)

Par exemple

jQuery("select").select2({"placeholder": "La forme ?"});
jQuery("select").spip_select2({"placeholder": "La forme ?"});
SpipSelect2.on_select(document.querySelector("select"), {"placeholder": "Que dire ?"});
SpipSelect2.on_input(document.querySelector("input.text"));

Via des attributs HTML data-xx

  • soit par les attributs data-xx sur la balise <select> ou <input>, qui prennent alors le pas sur les options transmises à l’initialisation.

Par exemple :

<select class="select2" id="select1" name="demo" data-placeholder="Ça va ?">
    <option></option>
    <option value="oui">Yep!</option>
    <option value="non">Bof.</option>
</select>
jQuery("#select2").select2({"placeholder": "La forme ?"});

La documentation de Select2 sera donc à étudier :)

Addition du plugin SPIP

Des options supplémentaires non présentes dans le Javascript par défaut sont ajoutées au plugin SPIP. Ces options sont disponibles :

  • si vous utilisez les classes CSS prévues sur les <select> (.select2 ou tout autre configurée en plus par vos soins)
  • si vous appelez directement une des fonctions
    • SpipSelect2.on_select()
    • SpipSelect2.on_input()
    • jQuery .spip_select2()

Mais pas si vous appelez directement la méthode jQuery .select2() native.

sortAlpha

-  {sortAlpha: true}
-  ou data-sort-alpha="true".

Si cet attribut est présent, les options de sélection seront triées par ordre alphabétique.

Cela est effectué en interne, en utilisant une fonction sorter ;
En simplifiant cela pourrait ressembler à :

    jQuery('#select3a').spip_select2({sortAlpha: true});
    // est à peu près équivalent à :
    jQuery('#select3b').select2({
        /*'sorter': data => data.sort((a, b) => a.text.localeCompare(b.text))*/
        sorter: function(data) {
            return data.sort(function(a, b) {
                return a.text.localeCompare(b.text);
            })
        }
    });

highlightSearchTerm

-  {highlightSearchTerm: true}
-  ou data-highlight-search-term="true".

Cette option met en évidence le terme de recherche dans la liste des résultats, en appliquant
un span .select2-rendered__match sur le terme recherché, qui est par défaut décoré avec un souligné.

Additions à la librairie javascript Select2

Les options suivantes nécessitent d’avoir chargé le javascript javascript/select2.fork.full.js (ce que fait le plugin d’ailleurs) à la place de lib/select2/js/select2.full.js, si vous chargez vous-même les scripts dans l’espace public sans passer par la configuration du plugin.

Il n’est malheureusement pas possible actuellement d’obtenir ces comportements sans adapter le code source de la librairie.

onEnterSubmit

-  {onEnterSubmit: true}
-  ou data-on-enter-submit="true".

Appuyer la touche Entrée en ayant le focus sur le sélecteur fermé soumet le formulaire (comportement généralement présent sur les navigateurs). Par défaut, Select2 quand à lui ouvre le sélecteur.

Autocomplete Ajax

On peut indiquer une URL de recherche à Select2 afin qu’il obtienne la liste des choix en fonction de la recherche tapée par l’utilisateur. Un exemple est proposé dans le plugin, visible sur la page de test.

Par exemple :

<select class="select2" id="chiens" name="chiens[]" 
    data-placeholder="Quelle race de chien ?"
    data-ajax-url="[(#URL_API{select2_autocomplete,demo/dogs}|attribut_html)]"
    data-minimum-input-length="1"
>
</select>

L’API doit retourner un format spécifique (cf action/select2_autocomplete.php) pour fonctionner par défaut, mais du javascript supplémentaire peut servir pour adapter des apis déjà existantes. Cf. documentation Ajax de Select2.

onAjaxLoad ...

Attention avec l’autocomplètion. Si vous appelez directement .select2() (ce n’est pas le cas pour .spip_select2() utilisé par le plugin cependant), chaque requête ajax pour obtenir la liste des éléments recherchés va déclencher la fonction SPIP onAjaxLoad. Votre code ne doit pas redémarrer l’initialisation des <select> déjà gérés par Select2 dans ce cas (sinon vous verrez le sélecteur se refermer aussitôt !).

Remplacer le plugin Chosen

Ce plugin peut remplacer le plugin Chosen.

Pour cela il faut

  • soit déclarer la classe CSS .chosen dans la configuration du plugin Select2 pour qu’il s’applique dessus,
  • soit modifier son code HTML (remplacer la classe chosen par select2)
  • soit appeler directement Select2 dans son propre code javascript, tel que :
jQuery('select.chosen').select2();
// ou
jQuery('select.chosen').spip_select2();

Il faudra également adapter les styles CSS spécifiques si vous en utilisiez, par exemple en fournissant css/select2_public.css (corollaire de css/chosen_public.css)

Intégration publique uniquement sur certaines pages

Si vous souhaitez charger Select2 uniquement sur certaines pages publiques (donc sans cocher la configuration qui ajoute Select2 partout dans l’espace public), voici un petit moyen :

Créer un squelette pour insérer les éléments nécessaires, tel que inclure/select2_loader.html :

[<link href="(#CHEMIN{lib/select2/css/select2.css}|timestamp)" rel="stylesheet" />]
[<link href="(#CSS{css/select2_public.css}|timestamp)" rel="stylesheet" />]
[<script type="text/javascript" src="(#CHEMIN{javascript/select2.fork.full.js}|timestamp)"></script>]
[<script type="text/javascript" src="(#CHEMIN{lib/select2/js/i18n/#LANG.js}|timestamp)"></script>]
[<script type="text/javascript" src="(#CHEMIN{javascript/SpipSelect2.js}|timestamp)"></script>]
[<script type="text/javascript" src="(#CHEMIN{javascript/SpipSelect2Loader.js}|timestamp)"></script>]
#FILTRE{compacte_head}

Et l’appeler, simplement où vous le souhaitez :

<INCLURE{fond=inclure/select2_loader} />

Surcharge de la librairie native

Notons que nous avons remplacé la librairie native, qui s’appellerait ainsi :

[<script type="text/javascript" src="(#CHEMIN{lib/select2/js/select2.full.js}|timestamp)"></script>]

Par une surcharge :

[<script type="text/javascript" src="(#CHEMIN{javascript/select2.fork.full.js}|timestamp)"></script>]

La surcharge permet simplement de faire fonctionner l’option onEnterSubmit.

Historique

Version 2

  • Compatible SPIP 4.2 minimum
  • Permet l’utilisation de Select2 sur des champs de type input[type=text]
  • Changement de signature de #URL_API
    • Avant (déprécié) : #URL_API{nom/chemin, params} tel que #URL_API{toto/truc/muche, id_toto=3}
    • Après : #URL_API{nom, chemin, params} tel que #URL_API{toto, truc/muche, id_toto=3}

Discussion

4 discussions

  • 1

    Bonjour,

    J’utilise Select2 dans un formulaire sur l’espace public avec #FORMULAIRE_EDITER_ARTICLE.

    Sur cette même page j’ai un autre formulaire en Ajax avec #FORMULAIRE_EDITER_LIENS, mais quand celui-ci est modifié, les champs de l’autre formulaire avec Select2 (editer_article) ne fonctionne plus.

    Faut-il recharger le script ? Comment je fais ?

    Merci d’avance.

    Répondre à ce message

  • Bonjour,

    Pour info la version du tags v1.1.0 ne prend pas en compte la correction javascript de :
    https://git.spip.net/spip-contrib-extensions/select2/commit/09951a019fb53c138decdd847a6a2f07bcf2be55

    Sinon : merci pour le plugin !

    Répondre à ce message

  • 2

    Hop,

    Quand plusieurs <select> ont le même name (ce qui n’est pas recommandé mais parfaitement valable), le script ne s’active que sur le dernier.

    Exemple :

    [(#SAISIE{selection, glop, class=select2, label="Glop mais sans select2 :c"})]
    [(#SAISIE{selection, glop, class=select2, label="Glop avec un beau select2"})]

    Je ne sais pas si le bug est dans l’implémentation du plugin ou directement dans la lib, pas encore vu de trace de ce bug dans leur tracker.

    Dans chosen, pas ce problème.

    • C’est clairement indiqué dans la documentation, en tout cas dans le readme :

      Important : L’identifiant (l’attribut id) de la balise select doit être unique sur la page ; Select2 ne peut s’activer qu’une fois par identifiant (le dernier appelé).

      C’est pas le name le problème, mais l’ID.

    • Aaaah ok, my bad.
      Donc en donnant un id unique en param de la saisie, tout rentre dans l’ordre.
      Merci :)

    Répondre à ce message

  • Bonjour,

    Je dirais : enfin !

    J’utilise select2 quand chosen ne convient ou ne suffit pas depuis pas mal de temps et ça fait plaisir de le voir porter en plugin pour Spip.

    Donc merci Marcimat !

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom