Contrôleur - Vue avec ajaxReload

This is an « educational contribution » which shows, with concrete example, how to develop a new functionality for SPIP.

Le besoin :
Au sein d’une page web, avoir un bloc de sélection qui charge dynamiquement un contenu dans un autre bloc de la même page grâce à Ajax.

Le principe

Voici une représentation de ce que l’on veut obtenir

Cette page est décomposée comme suit

  • Un titre
  • un bloc Contrôleur composé d’une liste d’items
  • un bloc Vue qui va recevoir le contenu sélectionné

La structure de la page HTML

Dans le répertoire squelettes/, on crée une page actualites.html

<html>
<head>
	<title>#NOM_SITE_SPIP</title>
	#INSERT_HEAD
</head>
<body>
	<h1>Journal Blabla</h1>
	<div class="container">
		<INCLURE{fond=inclure/liste_actus, env} />
		<INCLURE{fond=inclure/vue_actu, env, ajax=vue_actu} />
	</div>
</body>
</html>

Explication:

  • Le HTML reprend la découpe en blocs:
    • Chaque bloc correspond à un INCLURE.
    • Le point vraiment remarquable ici est la présence de l’attribut ajax=vue_actu dans le deuxième INCLURE. Explications dans la documentation officielle https://www.spip.net/fr_article3753.html
  • Dans le partie <head> du HTML, on ajoute la balise #INSERT_HEAD pour que SPIP charge les scripts nécessaires à l’Ajax

Le bloc Contrôleur : inclure/liste_actus.html

Il s’agit juste d’une simple boucle SPIP ARTICLES.

<div class="liste_actus">
	<h2>Derniers numéros</h2>
	<B_actu_controleur>
	<div class="liste_actus_inner">
	<BOUCLE_actu_controleur(ARTICLES){0,10}{!par date}>
		<a href="#URL_ARTICLE" class="liste_actus_item" data-id="#ID_ARTICLE">
			<h3>#TITRE</h3>
			[<div class="liste_actus_intro">
			(#INTRODUCTION|couper{25})
			</div>]
		</a>
	</BOUCLE_actu_controleur>
	</div>
	</B_actu_controleur>
</div>

Dans cet exemple, nous listons les 10 derniers articles.

Pour nous faciliter la programmation javascript, sur le lien vers des articles, on ajoute un attribut data-id qui contient l’id_article

Le bloc Vue : inclure/vue_actu.html

Le bloc Vue doit afficher un seul article.
Le critère de la boucle ARTICLES à utiliser est donc {id_article}

<BOUCLE_actu_vue(ARTICLES){id_article}>
<div class="vue_actu">
	[<div class="vue_actu_surtitre">(#SURTITRE)</div>]
	[<h1 class="vue_actu_titre">(#TITRE)</h1>]
	#LOGO_ARTICLE
	[<div class="vue_actu_texte">(#TEXTE)</div>]
</div>
</BOUCLE_actu_vue>

Ajouter l’habillage et l’interactivité

La structure HTML est en place !
Nous pouvons l’appeler par l’adresse
http://monsite.org/spip.php?page=actualites

Nous allons maintenant ajouter une feuille de style pour habiller la page et un javascript pour gérer l’appel des blocs.

Complétons le <head> de la page squelettes/actualites.html

<head>
	<title>#NOM_SITE_SPIP</title>
	[<link href="(#CHEMIN{css/actu.css})" rel="stylesheet" type="text/css">]
	#INSERT_HEAD
	<script src="#CHEMIN{js/actu.js}" type='text/javascript'></script>
</head>>

Le javascript

Voici le javascript, js/actu.js

// lancer le js quand le DOM est prêt
$(document).ready(function(){
 
	// detecter les clics sur les articles
	$('.liste_actus_item').on('click', function(event){
 
		// ne pas propager l'evenement javascript
		event.preventDefault();
 
		// on recupere l'id de l'article grace à l'attribut data-id
		var id_article_current = $(this).attr("data-id");
 
		// on ajoute une classe "active" sur le bloc en cours
		$('.liste_actus_item.active').removeClass('active');
		$(this).toggleClass('active');
 
		// on appelle le fonction ajaxReload
		// pour rafraichir le bloc "vue actu" avec comme argument id_article
		$(".debug").html("Appel de l'article: " + id_article_current);
		ajaxReload('vue_actu', {
			args:{id_article:id_article_current},
			callback:function(){
				$(".debug").html("Article " + id_article_current + " chargé !");
			},
		});
	});
});

Tester chez soi

Voici un zip avec l’exemple complet.

Ajaxload par l’exemple

Placer ses fichiers dans le répertoire squelettes/ de votre site SPIP et appelez la page démo:
http://monsite.org/spip.php?page=actualites

Voir aussi

Rechargement télécommandé de blocs ajax

updated on 2 October 2019

Discussion

7 discussions

  • Bonjour,

    j’ai testé le code sur mon site et lorsque je charge la page actualités, le script me dit qu’aucun article chargé

    j’ai essayé en y ajoutant un id_rubrique via une rubrique de mon site et toujours rien

    une explication ?
    faut-il parametrer kke chose en spip pour que l’ajax fonctionne ? car ce n’est pas la 1ere fois que j’essaye d’utiliser de l’ajax et je me suis toujours pris un mur

    Reply to this message

  • 1

    Après des jours ... d’essai
    J’essaie de faire afficher les mots-clés par groupe (qui contiennent un article lié) du côté du contrôleur et les titres cliquables des articles liés du côté de la vue
    Voici ce que j’ai mis du coté du controleur:

    <BOUCLE_groupes(GROUPES_MOTS){par titre}{tout}>
    <h1>#TITRE</h1>
    <BOUCLE_actu(MOTS){id_groupe}{par titre}>
    <ul><li><a href="#URL_ARTICLE">#TITRE</a></li></ul>
    <BOUCLE_articles(ARTICLES){id_mot}{id_rubrique}>
    #TITRE
    </BOUCLE_articles>   
    </BOUCLE_actu>
    </BOUCLE_groupes>
    • J’ai trouvé la réponse grâce à la liste et je la partage ici car cela peut en aider d’autres
      Pour le contrôleur:

      <BOUCLE_groupes(GROUPES_MOTS){par titre}{tout}>
      <B_mots>
      <h3>#TITRE</h3>
      <ul>
        <BOUCLE_mots(MOTS mots_liens){objet=article}{id_groupe}>
        <li><a href="[(#SELF|parametre_url{id_mot,#ID_MOT})]">#TITRE</a></li>
        </BOUCLE_mots>
      </ul>
      </B_mots>
      </BOUCLE_groupes> 

      Pour la vue:

      <BOUCLE_actu(ARTICLES){id_mot}>
      <ul><li><a href="#URL_ARTICLE">#TITRE </a></li></ul>
      </BOUCLE_actu>

      Merci
      SPIP c’est génial!

    Reply to this message

  • Bravo pour ton explication. Tout fonctionne !
    Par contre, j’aimerai remplacer le div “ajax-id-vue_actu” par un div fullscreen slide. On peut voir ici l’effet : https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_overlay
    Quand j’ajoute onclick=“closeNav()” de cette façon :

    1. <a href="#URL_ARTICLE" onclick="closeNav()" class="liste_actus_item" data-id="#ID_ARTICLE">Lire</a>

    Et bien, ça ne fonctionne pas...
    Des idées ?

    Reply to this message

  • Bravo pour ton explication. Tout fonctionne !
    Par contre, j’aimerai remplacer le div “ajax-id-vue_actu” par un div fullscreen slide. On peut voir ici l’effet : https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_overlay
    Quand j’ajoute onclick=“closeNav()” de cette façon :

    1. <a href="#URL_ARTICLE" onclick="closeNav()" class="liste_actus_item" data-id="#ID_ARTICLE">Lire</a>

    Et bien, ça ne fonctionne pas...
    Des idées ?

    Reply to this message

  • Bravo pour ton explication. Tout fonctionne !
    Par contre, j’aimerai remplacer le div “ajax-id-vue_actu” par un div fullscreen slide. On peut voir ici l’effet.

    Pour cela, il faut ajouter dans le JS

    .style.width = “100%”

    ...
    Mais comment faire ?

    Des idées ?

    Reply to this message

  • Bonjour,
    Bravo pour ton explication. Tout fonctionne !
    Par contre, j’aimerai remplacer le div “ajax-id-vue_actu” par un div fullscreen slide. On peut voir icil’effet.
    Quand j’ajoute onclick=“closeNav()” de cette façon :

    1. <a href="#URL_ARTICLE" onclick="closeNav()" class="liste_actus_item" data-id="#ID_ARTICLE">Lire</a>

    L’overlay avec l’article apparaît mais se ferme de suite.
    Dans le JS, j’ai changé :

    1. return true;

    Et ajouté :

    function openNav() {
      document.getElementById("myNav").style.width = "100%";
    }

    Et dans vue_actu :

    1. <div id="myNav" class="overlay vue_actu">

    Des idées ?

    Reply to this message

  • 1

    Petite question. Comment pousser une valeur par défaut (sans clique) à la fois dans le contrôleur (classe active) et dans la vue Ajaxée ? Et ainsi avoir le dernière article en date au chargement de la page. Merci.

    • Hello,

      tu ne pourras pas “pousser” une valeur par défaut. C’est ta vue qui doit intégrer une valeur par défaut.

      Une solution serait de calculer la valeur par défaut de l’id_article au chargement initial de la vue (dans dans inclure/vue_actu.html donc)

      Par exemple, récupèrer le dernier article de ta rubrique Actus :

      <BOUCLE_derniere_actu(ARTICLES){id_rubrique=9}{!par date}{0,1}>#SET{id_last_actu,#ID_ARTICLE}</BOUCLE_derniere_acu>
       
      <BOUCLE_actu_vue(ARTICLES){id_article=#ENV{id_article,#GET{id_last_actu}}>

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom