Une solution pour trier des données issues de formidable

Une solution pour trier des données issues de formidable [1]

La demande était de pouvoir trier les inscriptions à un tournoi. Initialement il fallait trier sur le elo mais pour le championnat Jeunes organisé par le Comité Départemental des Echecs, j’ai préféré trier sur les noms et les clubs.

Après une première tentative pour créer le tableau de restitution en json, finalement on revient à un plus simple modèle utilisant des boucles SPIP.

On va collecter les données dans un tableau (#ARRAY), définir la possibilité de trier, créer l’entête du tableau, puis afficher les résultats.

Collecter les données

D’abord, il faut déclarer le tableau avant la boucle au moyen d’un #SET. Ce sera écrit ici sous cette forme

[(#ARRAY{}|set{tab})]

https://spip.net/fr_article5694.html#set "Le filtre

 |set{nom} 

affecte la valeur courante à la variable nom. C’est une alternative, parfois plus commode à écrire, à la balise

#SET{nom,valeur}

.

Puis vient la boucle elle même dans laquelle on va insérer les données récoltées que l’on veut afficher :

<BOUCLE_formidable(FORMULAIRES_REPONSES){id_formulaire ?}>
[(#ARRAY{
   categorie,[(#VOIR_REPONSE{selection_2, valeur_uniquement, ""}|textebrut)],
   nom,[(#VOIR_REPONSE{input_2, brut}|strtoupper)],
   prenom,[(#VOIR_REPONSE{input_1, brut})],
   elo,[(#VOIR_REPONSE{input_4, valeur_uniquement, ""}|textebrut)],
   club,[(#VOIR_REPONSE{selection_1, valeur_uniquement, ""}|textebrut)],
   codeffe,[(#VOIR_REPONSE{input_9, valeur_uniquement, ""}|textebrut)],
}
|set{row})]
[(#GET{tab}|push{#GET{row}}|set{tab})]
</BOUCLE_formidable>

Cette boucle remplit le résultat de l’iteration de boucle en cours comme une nouvelle ligne du tableau qui rassemblera tous les résultats
Décomposons ce qu’on vient de faire.
On utilise :
#ARRAY "La balise #ARRAY peut contenir un tableau PHP, c’est-à-dire un ensemble de paires clé/valeur, que l’on veut stocker pour les réutiliser dans la suite du squelette."
#VOIR_REPONSE Une balise de formidable pour afficher les valeurs.
|push https://www.spip.net/fr_article4571.html#push s’applique à une balise contenant un tableau PHP (voir #ARRAY) et y ajoute une nouvelle valeur.

[(#GET{tab}|push{#GET{row}}|set{tab})] 

J’ai toujours des soucis pour comprendre ce genre de code avec des #SET et des #GET imbriqués.

En fait le premier #GET{tab} appelle le tableau qui est vide et dans le quel on pousse les données recueillies dans row par push{#GET{row}} et on finit par le #SETtab final |set{tab} qui définit le tableau.

<thead>
        <tr>
            <th>Catégorie</th>
            <th>Nom</th>
            <th>Prénom</th>
            <th>Elo</th>
            <th>Club</th>
            <th>Code FFE</th>
        </tr>
 </thead>

permettre le tri

Il faut donc ensuite insérer le code qui permet de trier proprement dit. On remplace la valeur, par exemple ici de Club par ce code

<a class="ajax nohistory [on(#ENV{tri}|=={club}|oui) [(#ENV{sens}|=={1}|?{desc,asc})] ]"
                href="[(#SELF|parametre_url{tri,club}|parametre_url{sens,#GET{sens}})]">Club</a>

La possibilité de trier, ci-dessus

#GET{sens} 

avait été définie préalablement par cette ligne

[(#ENV{sens}|=={0}|?{#SET{sens,1},#SET{sens,0}})]

Trier les catégories

L’ordre logique est du plus petit au plus grand, ou l’inverse. Ca se fait dans la liste des catégories en insérant les numéros 01, 02 etc. puis le filtre supprimer numéro dans le modèle

Afficher les données

C’est une boucle DATA qui permet de récupérer les données

<BOUCLE_elo(DATA)
{source table, #GET{tab} }
{par #ENV{tri,categorie}}
{inverse #ENV{sens,1}}
>

Dans le modèle pour afficher le résultat on insérera le filtre supprimer_numéro pour masquer les numéros triant les catégories

<tr [class='row-(#COMPTEUR_BOUCLE|alterner{even,odd})']>
<td>[(#CATEGORIE|supprimer_numero)]</td>
<td>#NOM</td>
<td>#PRENOM</td>
<td>#ELO</td>
<td>#CLUB</td>
<td>#CODEFFE</td>
</tr>

L’affichage des résultats en ajax

Le modèle proprement est dans squelettes/inclure et il est appelé par dans modèles squelettes/modeles

<INCLURE{fond=inclure/jeunes_hg, env,ajax}>

Ne pas être géné par le cache

Dans mes_fonctions.php on va déclarer une fonction perso pour invalider le cache à la saisie du formulaire.

function perso_formidable_traiter($flux) {

        // concernera tous les formulaires formidable
        if ($flux['args']['form'] == 'formidable') {

                        // invalider la cache à la sousmission
                        include_spip('inc/invalideur');
                        // NB : il n'y a pas de référence explicite id_article dans l'env
                        suivre_invalideur(true);

                        spip_log( 'cache invalidé suite à traitement de '. $flux['data']['_formidable']['identifiant'], 'test_formulaire_charger' . _LOG_INFO);
       
        }
        return $flux;
}

Et cette fonction d’invalidation du cache doit être déclarée dans mes_options.php

//Déclarer une fonction supplémentaire pour le pipeline traiter

$GLOBALS['spip_pipeline']['formulaire_traiter'] = '|perso_formidable_traiter';

le résultat

https://cde31.echecs-occitanie.fr/Championnat-Jeunes-Haute-Garonne-2017-2018

Il est important de souligner que sans l’aide précieuse de Placido je ne serais pas arrivé à ce résultat ^^ Et que j’ai beaucoup appris aussi en rédigeant ces commentaires :)

Ensuite ?

Todo… ce serait bien de faire un petit plugin de personnalisation. Mais difficile de proposer ça tel quel c’est trop spécifique.

Peut-être que ce serait tout de même plus simple à gérer dans le cadre d’un petit plugin perso ?