Créer une "application web " avec Meteor - Brouillon v230714

 
Créer une "application web " avec Meteor - Brouillon v230714
Créer une «application web »
            avec
           Meteor
                   v230714
                  Brouillon
    David Roche, lycée G Fichet Bonneville

                                             1
Créer une "application web " avec Meteor - Brouillon v230714
Ce texte est sous licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International. Pour
accéder à une copie de cette licence, merci de vous rendre à l'adresse suivante http://creativecommons.org/licenses/by-
sa/4.0/ ou envoyez un courrier à Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041,
USA.

Le titulaire des droits autorise toute utilisation de l’œuvre originale (y compris à des fins commerciales) ainsi que la
création d’œuvres dérivées, à condition qu’elles soient distribuées sous une licence identique à celle qui régit l’œuvre
originale.

                                                                                                                       2
Créer une "application web " avec Meteor - Brouillon v230714
Notes de l'auteur
Ce document est à l'origine destiné aux élèves de seconde, du lycée G Fichet de Bonneville (Haute-Savoie), qui ont
choisi de suivre l'enseignement d'exploration PSN (Pratique Scientifique et Numérique). Plus généralement il est
utilisable par toutes personnes désirant apprendre à développer des applications web.
Des connaissances en JavaScript, HTML et CSS sont indispensables avant d'aborder Meteor (voir, par exemple, les 18
activités « JavaScript, HTML et CSS » que j'ai rédigées pour les élèves). De plus, des connaissances "de base" sur la
librairie jQuery seront un plus, mais ne sont pas indispensables.
Vous trouverez en annexe une digression quelque peu "théorique" sur la notion de client-serveur. Je conseille aux
personnes étant totalement novices en la matière de lire cette annexe avant de commencer les activités.
L'annexe 2 est consacrée au CSS (à la mise en page plus exactement)
Ce document n'a pas la prétention d'être la « bible » de Meteor (n'oubliez pas qu'il s'adresse à des élèves ayant une
pratique limitée de la programmation), il a été conçu pour travailler « en collaboration » avec l'enseignant (certaines
parties ne sont pas détaillées, les enseignants devront adapter leurs explications en fonction des contraintes locales (OS
installé, possibilité d'installer des logiciels sur les machines......)).

David Roche

                                                                                                                             3
Créer une "application web " avec Meteor - Brouillon v230714
Activité 1
                                     Présentation et installation de Meteor
Mais qu'est-ce que Meteor ?
Meteor est une plateforme open-source qui permet de développer très rapidement des applications web complètes (site
officiel : https://www.meteor.com/). Meteor gère à la fois le côté client et le côté serveur, y compris le stockage des
données dans une base de données (si ces notions de client-serveur et de base de données vous sont inconnues, consulter
l'annexe 1 de ce document). Meteor s'appuie sur nodeJS et mongoDB (pour en savoir plus sur nodeJS et mongoDB
voir, là aussi, l'annexe 1)

Installation

Au moment où ces lignes sont écrites, Meteor n'est pas supporté par Windows officiellement. Si vous n'avez pas la
possibilité d'installer un environnement GNU/linux, je vous conseille d'utiliser une machine virtuelle. L'installation
d'une telle machine sortant du cadre de ce document, je vous laisse faire les recherches nécessaires sur internet.

Voici la procédure à suivre sur un système de type "Ubuntu" ou "Mint" :

À faire vous-même

Commencer par installer curl (si nécessaire) en tapant dans une console :
sudo apt-get install curl

Une fois curl installé, toujours dans une console tapez :
curl https://install.meteor.com/ | sh

Après une attente plus au moins longue, Meteor devrait maintenant être installé sur votre ordinateur. Avant de
commencer à utiliser Meteor, nous allons installer Meteorite. Meteorite vous permettra d'installer très simplement des
extensions qui fonctionneront avec Meteor :

Installer tout d'abord nodejs :
sudo apt-get install nodejs-legacy

Si nécessaire, installer npm :
sudo apt-get install npm

Enfin, vous pouvez installer Meteorite :
sudo -H npm install -g meteorite

Première Application

À faire vous-même

Vous êtes prêt à créer votre première application Meteor :
Dans votre répertoire personnel, toujours à l'aide de la console, créer un nouveau répertoire (ce répertoire vous servira
de répertoire de travail) :
mkdir mesAppMeteor

Placez-vous dans ce répertoire :
cd mesAppMeteor

et créer votre première application :
mrt create monApp_1

                                                                                                                            4
Créer une "application web " avec Meteor - Brouillon v230714
Pour vérifier que tout à bien fonctionné :
placez-vous dans le répertoire qui vient d'être créé :
cd monApp_1

et taper :
mrt

Vous devriez avoir à l'écran :

Sans fermer la console, ouvrir un navigateur et taper dans la barre d'adresse :
http://localhost:3000/

Si tout a fonctionné, vous devriez avoir dans votre navigateur le résultat suivant :

http://localhost:3000/ ?

Dans l'annexe 1 de ce document, j'insiste sur le fait que la consultation d'un site internet est un échange de données
entre 2 ordinateurs distants (un client et un serveur), or, ici, nous n'utilisons qu'un ordinateur ?
Dans toute la phase de développement, il est tout à fait possible d'utiliser un seul ordinateur qui jouera à la fois (et en
même temps) le rôle du client et le rôle serveur.
L'exécution, dans la console, de la commande mrt « démarre » le serveur, une fois le serveur démarré il « attend » les
requêtes HTTP en provenance d'un client. Le navigateur web va envoyer ces requêtes au serveur.
Mais comment entrer en communication avec le serveur ?
Il suffit d'utiliser une adresse un peu spéciale : localhost (localhost indique au navigateur web que le serveur se trouve
sur la même machine que lui).
Le ": 3000" définie le port utilisé par le serveur. Plusieurs applications peuvent utiliser la même connexion réseau à
condition de ne pas utiliser le même port (on parle aussi de socket). Ici notre serveur « écoute » et « attend » une requête
HTTP sur le port 3000.

Mettre son application en ligne

Il est possible de rendre son application disponible sur internet (publier son application). Il suffira, depuis la console (et
depuis le répertoire de l'application que vous voulez publier de taper : "mrt deploy monApp.meteor.com" (remplacez

                                                                                                                                 5
Créer une "application web " avec Meteor - Brouillon v230714
"monApp" par le nom de votre choix). Le système vous demandera votre adresse email, et c'est tout...(vous aurez aussi
à vous connecter pour configurer votre compte).

Votre application sera disponible en tapant depuis un navigateur : "http://monApp.meteor.com".
Pour effacer une application : placez-vous dans la console et tapez "mrt deploy - -delete monApp.meteor.com"
(toujours, évidemment, en remplaçant "monApp" par le nom de votre application).
Attention, cet hébergement est gratuit, mais il n'est pas prévu pour héberger des applications "en production" (des
applications qui verront plusieurs dizaines de connexions par minute). Ce système est proposé juste à des fins de test.
Il existe d'autres solutions pour mettre votre application en ligne (souvent payantes), mais cela sort du cadre de ces
activités.

                                                                                                                          6
Créer une "application web " avec Meteor - Brouillon v230714
Activité 2
                          Création des dossiers et structure d'une application
Si vous parcourez le dossier monApp_1, vous allez trouver plusieurs fichiers dont monApp_1.css, monApp_1.html et
monApp_1.js. Ces fichiers ont été générés automatiquement lors de la création de l'application (utilisation de la
commande mrt create monApp_1). Pour différentes raisons que je ne détaillerai pas maintenant, nous n'allons pas
utiliser ces fichiers, vous pouvez donc les effacer (attention de ne pas effacer le fichier smart.json et éventuellement le
fichier smart.lock. Sachez aussi que le dossier monApp_1 contient un dossier caché .meteor : vous ne devez jamais
"toucher" à ce dossier sous peine d'un dysfonctionnement définitif de votre application).

À faire vous-même

Nous allons créer une structure un peu plus complexe. Toujours en vous plaçant dans le dossier monApp_1, créez les
dossiers suivants :
- client
- server
- public

Quelques explications sur la création de ces dossiers :
Meteor gère à la fois le côté client et le côté serveur, tous les fichiers se trouvant dans le dossier "client" ne seront
"exécutés" que par le client, de la même manière, tous les fichiers se trouvant dans le dossier "server" ne pourront être
utilisé que du côté serveur. Tous les autres fichiers, c'est-à-dire ceux qui ne se trouvent ni dans le répertoire "client", ni
dans le répertoire "server", pourront à la fois être utilisés côté client et côté serveur.
Je précise quand même, pour que les choses soient bien claires dans votre esprit, qu’au départ (juste avant la 1ère
requête effectuée par le client), tous les fichiers se trouvent sur le serveur, mais les fichiers se trouvant dans le répertoire
client sont destinés à être envoyé au client (au moyen de requêtes HTTP), le serveur ne les exécutera jamais. En
revanche les fichiers se trouvant dans le répertoire "server" ne feront jamais le "voyage" jusqu'au client, ils sont
strictement réservés au serveur.

À faire vous-même

Placez-vous dans le répertoire client et créez les dossiers suivants :
- css
- JavaScript
- templates

Toujours dans le répertoire "client", créez un fichier main.html
De la même façon, créez un fichier main.css dans le dossier "css" et un fichier main.js dans le dossier "JavaScript".

Structure à mettre en place pour toute nouvelle application Meteor

Voilà, la structure de base de notre application est maintenant à place. Pour chaque nouvelle application Meteor, il vous
faudra suivre la même démarche :
    • Création de l'application à l'aide de la commande mrt create monApp (si vous avez choisi monApp comme
          nom pour votre application).
    • Effacer les fichiers monApp.js, monApp.html et monApp.css créés par défaut par meteor dans le répertoire
          monApp (toujours si vous avez choisi monApp comme nom pour votre application !).
    • Créer les répertoires "client", "server" et "public" dans le répertoire monApp
    • Créer les répertoires "css", "JavaScript" et "template" ainsi que le fichier main.html dans le répertoire client
    • Créer un fichier main.js dans le répertoire "JavaScript" et un fichier main.css dans le répertoire "css"

                                                                                                                               7
Activité 3
          Première application, première approche de la "philosophie" de Meteor
À faire vous-même

Créez une application nommée app_01 et mettez en place la structure vue ci-dessus.

Éditez le fichier main.html

       App01

       App01
       Bonjour et bienvenu dans Meteor

Éditez le fichier main.js

alert('Le JavaScript fonctionne aussi !')

Éditez le fichier main.css

h1{
         text-align: center;
}

Lancez cette application en ouvrant la console, en vous plaçant dans le dossier app_01 et en tapant mrt au niveau de
l'invite de commande.

Tout fonctionne : le HTML (notre page s'affiche bien), le JavaScript (nous avons bien apparition de la "boite alert") et le
CSS (notre titre h1 se trouve bien au centre de l'écran). Pourtant, "logiquement" tout cela ne devrait pas fonctionner :
    • le fichier HTML n'est pas complet (il manque le doctype, la balise meta et la balise html)
    • on ne trouve aucune référence au fichier main.js dans le html
        (par exemple un "")
    • toujours dans le html, on ne trouve aucune référence au fichier main.css
        (par exemple un "")

Et pourtant tout cela fonctionne : c'est la "magie" de Meteor (et vous n’êtes pas au bout de vos surprises !)

                                                                                                                          8
Activité 4
                                          Introduction aux templates
À faire vous-même

Créez une nouvelle application app_02

main.html

       App02

       App02
       Bonjour vous allez voir ci-dessous un template
       {{>monTemplate}}
       Avez-vous vu le template ?

main.css reste inchangé par rapport à l'application précédente et main.js doit être vide.

Créez un fichier que vous nommerez templates.html et placez-le dans le répertoire template (le répertoire template se
trouve dans le dossier client).

templates.html

       Voici le template

Testez cette application, vous devriez obtenir ceci :

Vous avez, je pense, compris la notion de template :
Dans Meteor, la gestion des templates est basée sur le moteur de template handlebars (http://handlebarsjs.com/). Au
moment de l'affichage de la page "{{>monTemplate}} " sera remplacé par ce qui se trouve dans la balise
"à". La balise template ( ) peut se trouver
dans le même fichier que la double accolade ({{>monTemplate}}) ou, comme dans notre exemple dans 2 fichiers
différents (le fichier main.html et le fichier templates.html).
Vous pouvez choisir le nom que vous voulez pour le template : par exemple, nous pourrons avoir "{{>toto}} " et
" ". Il est possible d'avoir plusieurs templates dans une même page.

À faire vous-même

Créez une application app_03. Le fichier main.html devra contenir 2 templates. Le code de ces 2 templates devra se
trouver dans le fichier templates.html.

Pour l'instant, l'intérêt des templates ne saute pas aux yeux, pourtant, comme nous allons le voir dans la suite de ce
document, ce sont des outils extrêmement puissants.

                                                                                                                         9
Activité 5
                                         les templates et les contrôleurs
Un template est très souvent couplé avec contrôleur. Un contrôleur est une méthode JavaScript associée à un template.
Les contrôleurs vont permettre de rendre les templates dynamiques. Voici un premier exemple :
À faire vous-même

Créez une application app_04
Complétez les différents fichiers comme suit :

main.html

       App04

       App04
       {{>monTemplate}}

template.html (fichier se trouvant dans le dossier templates)

       Voici mon nom : {{nom}}

controller.js (créez ce fichier dans le répertoire JavaScript)

Template.monTemplate.helpers({
       nom:function(){
              return "toto";
       }
});

Par ailleurs, pour cet exemple et pour tous les exemples suivants :
    • vous pourrez supprimer le fichier main.js
    • le fichier main.css restera inchangé (sauf précision contraire).

Voici le résultat que vous devriez obtenir :

Le fichier main.html ne comporte aucune nouveauté, intéressons-nous donc au fichier template.html et controller.js :
Le fichier template.html comporte une nouveauté le "{{nom}}" : vous reconnaissez les doubles accolades déjà vues
précédemment, mais notez cette fois-ci, l'absence du signe > (comme dans "{{>monTemplate}).
"{{nom}}" représente une variable, meteor nous permet donc d'introduire des variables dans les templates HTML (vous
commencez à comprendre l’intérêt des templates par rapport à du HTML "classique").

Mais où définit-on la valeur contenue dans cette variable ?

Pour répondre à cette question, il va falloir nous intéresser au contenu du fichier controller.js :

 "Template.monTemplate.helpers" d'un point de vue "purement JavaScript" nous avons ici affaire à une méthode
(la méthode "helpers" appartient à l'objet "monTemplate" qui est lui-même un attribut de l'objet "Template"). C'est
cette méthode qui nous permettra d'interagir avec le template "monTemplate" (de rendre ce template dynamique) :
cette méthode sera le contrôleur du template "monTemplate".
La méthode "helpers" prend en paramètre un objet JavaScript : "{nom:function(){return "toto";}". Dans
notre exemple, cet objet n'a qu'un seul attribut, l'attribut "nom". Cet attribut est une fonction (donc en faite une méthode
puisque c'est une fonction associée à un objet), qui ne fait qu'une seule, renvoyer la chaîne de caractère " toto". Le
"{nom:function(){return "toto}";" est donc équivalent à un "{nom:"toto";}" (nous avons vu dans les
activités consacrées à l'apprentissage de la programmation avec JavaScript qu'il suffit de remplacer la fonction par la

                                                                                                                           10
valeur qu'elle retourne (grâce au mot clé return) pour avoir une idée du résultat de l'exécution de cette fonction). Vous
devez savoir que nous aurions très bien pu écrire directement "{nom:"toto";}", cela aurait aussi bien fonctionné.
Mais par anticipation de ce que nous verrons plus loin dans ce document, j'ai choisi de tout de suite vous présenter la
version "{nom:function(){return "toto";}".
Pour résumer, nous avons attribué la valeur "toto" à la variable nom (dans le fichier controller.js grâce à la méthode
"Template.monTemplate.helpers", puis nous avons utilisé cette variable dans le template "monTemplate" (fichier
template.html) avec le "{{nom}}").
Notez que vous pourrez aussi rencontrer une écriture un peu différente :

Template.monTemplate.nom=function(){return "toto";};

Cette seconde façon d'écrire la méthode "helpers" est totalement équivalente à celle que nous avons vu plus haut, c'est
juste un "raccourci".

À faire vous-même

En vous basant sur l'application app_05 créez une application app_06 qui permettra d'afficher :

Voici mon nom : Toto
Voici mon prénom : Titi

Attention les chaînes de caractères Toto et Titi ne devront pas être "codées" directement dans le template (fichier
template.html).

Utilisation des objets JavaScript

Au lieu de renvoyer une simple variable, la méthode "helpers" peut aussi renvoyer un objet JavaScript.

Si vous avez besoin de vous rafraîchir la mémoire à propos des objets en JavaScript, je ne serai trop vous conseiller de
revoir l'activité 14 du document "Activités JavaScript, HTML et CSS".

À faire vous-même

Créez et étudiez cette application (app_06)

main.html

       App06

       App06
       {{>monTemplate}}

template.html

       Voici mon nom : {{monPerso.nom}}
       Voici mon prénom : {{monPerso.prenom}}
       Voici mon âge : {{monPerso.age}}

controller.js

var perso={
       nom:"toto",
       prenom:"titi",
       age:15
}
Template.monTemplate.helpers({
       monPerso:function(){

                                                                                                                           11
return perso;
         }
});

Vous pouvez constater que la méthode "helpers" prend toujours un objet en paramètre ({ monPerso:function()
{ return perso; } ). Mais cette fois l'attribut "monPerso" est une méthode qui ne renvoie pas une "simple"
variable comme dans l'application app_04, mais renvoie un objet JavaScript. Cet objet JavaScript a été défini au début
du fichier controller.js (var perso={ nom:"toto", prenom:"titi", age:15 }).

Dans le fichier template.html on a maintenant "{{monPerso.nom}}" (l'attribut nom de l'objet monPerso) à la place du
simple "{{nom}}" de l'application app_04.

Il est possible de simplifier l'écriture du template comme suit :

template.html

       {{#with monPerso}}
       Voici mon nom : {{nom}}
       Voici mon prénom : {{prenom}}
       Voici mon âge : {{âge}}
       {{/with}}

Toutes les doubles accolades se trouvant entre le "{{#with monPerso}} " et le "{{/with}} " concerneront l'objet
monPerso. Le "Voici mon nom : {{nom}} " correspondra bien à un "Voici mon nom :
{{monPerso.nom}} ".... même chose pour les autres attributs (prenom et âge). Ici aussi, cela permet d'alléger
l'écriture.

À faire vous-même

En partant de l'objet suivant :
var fiche={
       nom : "Dupond",
       prenom : "Michel",
       dateNaissance : "17/06/1998",
       adresse : "45 rue de la monté"
}

et en vous basant sur l'application app_06, créez un application app_07 qui affichera dans votre navigateur les
informations suivantes :
Nom : Dupond
Prénom : Michel
Date de Naissance : 17/06/1998
Adresse : 45 rue de la montée

Vous veillerez à utiliser le couple "{{#with .....}}...{{/with}}".

                                                                                                                         12
Activité 6
                                           Les boucles et les templates
Les boucles et les tableaux d'objets
Imaginons que nous voulions afficher non pas une fiche "d'identité" mais trois. Ces trois fiches qui seront toujours
"stockée" sous forme d'objets JavaScript, pourraient prendre cette forme :

var fiche1={
       nom : "Dupond",
       prenom : "Michel",
       dateNaissance : "17/06/1998"
}

var fiche2={
       nom : "Durand",
       prenom : "Albert",
       dateNaissance : "07/02/1991"
}

var fiche3={
       nom : "Dupuis",
       prenom : "Christelle",
       dateNaissance : "28/02/2001"
}
Par souci de simplification nous allons stocker nos fiches (et donc nos objets JavaScript) dans un tableau :

var tabFiche=[
      {nom : "Dupond",
      prenom : "Michel",
      dateNaissance : "17/06/1998"},
      {nom : "Durand",
      prenom : "Albert",
      dateNaissance : "07/02/1991"},
      {nom : "Dupuis",
      prenom : "Christelle",
      dateNaissance : "28/02/2001"}
]

Prenez bien garde à la position des virgules : il y a des virgules entre les attributs d'un objet (sauf après le dernier
attribut) et des virgules entre les objets (sauf après le dernier objet).

Comment accéder aux objets contenus dans le tableau ?

Les objets stockés dans le tableau tabFiche n'ont plus de nom, nous ne pouvons donc plus écrire "fiche1.nom" (qui est
égal Dupond). Mais le premier objet (la première fiche) est le premier élément du tableau tabFiche, il possède donc
l'indice de position 0, le deuxième objet est le second élément du tableau, il possède donc l'indice de position 1....

Donc à quoi correspond tabFiche[1] ?
Au deuxième objet du tableau !

Et donc, à quoi correspond tabFiche[0].nom ?
tabFiche[0] correspond au premier objet du tableau et donc tabFiche[0].nom est égal à Dupond !

En JavaScript "classique" il est donc relativement facile d'afficher toutes les fiches présentes dans le tableau, il suffit
d'utiliser une boucle for :

for (var i=0 ; i
Les boucles et les templates

Il est très facile de réaliser la même chose avec meteor. La boucle ne sera pas "codée" en JavaScript, mais directement
intégrée au template.
Étudiez et testez cet exemple :

À faire vous-même

Créez et étudiez cette application (app_08)

main.html

       App08

       App08
       {{>monTemplate}}

template.html

       {{#each mesFiches}}
              Nom : {{nom}}
              Prénom : {{prenom}}
              Date de naissance : {{dateNaissance}}
              
       {{/each}}

controller.js
var tabFiche=[
       {nom : "Dupond",
       prenom : "Michel",
       dateNaissance : "17/06/1998"},
       {nom : "Durand",
       prenom : "Albert",
       dateNaissance : "07/02/1991"},
       {nom : "Dupuis",
       prenom : "Christelle",
       dateNaissance : "28/02/2001"}
]
Template.monTemplate.helpers({
       mesFiches:function(){
              return tabFiche;
       }
});

Comme vous pouvez le constater, la méthode "helpers" a pour paramètre un objet qui contient une méthode qui renvoie
le tableau "tabFiche".
Dans le template, tout ce qui se trouve entre "{{#each mesFiches}} " et "{{/each}} " correspond au code qui
sera dupliqué le nombre de fois nécessaire afin de pouvoir "parcourir" l'ensemble des objets contenu dans le tableau.
Vous devez bien comprendre que "{{nom}}" correspond bien à l'attribut nom des objets contenus dans le tableau.

À faire vous-même

Créer une application (app_09) qui permettra d'afficher les informations contenues dans le tableau suivant :

tabVoitures=[
       {marque : "Renault",
        couleur : "rouge",
        annee : "2012"},

                                                                                                                          14
{marque : "Fiat",
          couleur : "verte",
          annee : "2011"},
         {marque : "Peugeot",
          couleur : "jaune",
          annee : "2010"}
]

Vous devrez réinvestir tout ce que nous venons de voir.

Un exemple un peu plus complexe

Il est possible d'imbriquer les templates :

À faire vous-même

Étudiez et testez cette application (app_10) :

main.html

       App10

       App10
       {{>monTemplate}}

template.html

       {{#each mesFruits}}
              {{>monFruit}}
       {{/each}}
       
       {{nom}}

controller.js

var mesFruitsTab=[{nom:"banane"},{nom:"pomme"},{nom:"ananas"},{nom:"pêche"},
{nom:"fraise"}];
Template.monTemplate.helpers({
       mesFruits:function(){
              return mesFruitsTab;
       }
});

"mesFruitsTab" est un tableau d'objets (cela correspond à ce que nous verrons dans la grande majorité des cas par la
suite), chaque objet ne contient qu'un attribut : "nom". Le "helpers" "mesFruits" du template "monTemplate"
renvoie ce tableau d'objets.
Grâce à la structure de type "{{#each...}}", le template "monFruit" est "exécuté" pour chaque objet contenu dans le
tableau. Nous aurons donc ici l’enchaînement de 5 balises "", "{{nom}}" étant successivement remplacé par
banane, pomme, ananas et afin pêche.

Dans la suite, nous privilégierons cette structure "{{#each monHelper}}{{>monTemplate}}{{/each}}" couplée
avec un tableau d'objets JavaScript (qui plus tard, sera issu d'une base de données), il est donc important de bien
assimiler cet exemple.

                                                                                                                  15
Activité 7
                                                  Les événements
Afin de favoriser les interactions entre l'application et les utilisateurs, meteor propose un système de gestion
d'événement. Par exemple, si vous placez sur votre page un bouton destiné à valider un formulaire, meteor vous
permettra de gérer assez facilement les données issues du formulaire. Étudions plus précisément cet exemple.

À faire vous-même

Étudiez et testez cette application (app_11) :

Attention cet exemple utilise la bibliothèque jQuery, vous devez donc l'installez afin de pouvoir l'utiliser avec Meteor.
Dans la console, placez-vous dans le répertoire de votre projet (par exemple ici app_11) et tapez : mrt add jquery

main.html

       App11

       App11
       {{>formulaire}}

template.html

       Nom 
       Prénom 
       
controller.js

Template.formulaire.events({
       'submit #monFormulaire': function(e){
              e.preventDefault();
              nomUser=$('#nom').val();
              prenomUser=$('#prenom').val();
              $('#nom').val('');
              $('#prenom').val('');
              $('#info').append('Bonjour '+prenomUser+' '+nomUser+'')
       }
})
Rien de nouveau pour main.html et template.html (à part le formulaire), concentrons-nous donc sur controller.js :
Pas de "helpers" ici, en revanche nous avons une méthode "events". Cette méthode "events" prend en paramètre un
objet JavaScript. Cet objet possède un attribut : "'submit #monFormulaire'". Cet attribut nous informe qu'en cas de
soumission ("submit") du formulaire ayant pour identifiant "monFormulaire", la fonction "function(e)" devra être
exécutée.
Voici, dans notre exemple, le contenu de cette fonction :
"e.preventDefault();
nomUser=$('#nom').val();
prenomUser=$('#prenom').val();
$('#nom').val('');
$('#prenom').val('');
$('#info').append('Bonjour '+prenomUser+' '+nomUser+'')"

La première ligne ("e.preventDefault()"), empêche la soumission "classique" du formulaire, je ne vais pas
m'étendre sur cette question, mettez cette ligne en début de fonction si vous ne voulez pas avoir de mauvaises
surprises !

                                                                                                                        16
Ensuite, nous utilisons la bibliothèque jQuery :
"nomUser=$('#nom').val(); " : permet de récupérer le contenu du champ du formulaire ayant l'id nom et range ce
contenu dans la variable nomUser.
"prenomUser=$('#prenom').val(); " : même chose que ci-dessus, mais avec le prénom
"$('#nom').val(''); " : vide le champ du formulaire ayant pour id nom
"$('#prenom').val(''); " : même chose que ci-dessus, mais pour le prénom
"$('#info').append('Bonjour '+prenomUser+' '+nomUser+'')" : permet d'ajouter une balise p
dans la balise div ayant pour id info (voir le template). Cette balise p aura pour contenu "Bonjour
'+prenomUser+' '+nomUser+'" où "prenomUser" et "nomUser" auront été remplacé par leurs valeurs. Je ne
m'attarde pas plus sur cette ligne, car dans un avenir très proche nous n'aurons plus à utiliser la méthode "append" de
jQuery, nous utiliserons plutôt la méthode "helpers" de meteor.

                                                                                                                     17
Activité 8
                                                   Les collections
Nous allons ici aborder, sans doute, la partie la plus importante de cette série d'activité : les collections.
La notion de collection est, dans meteor, directement lié aux bases de données, donc au stockage des informations.
En effet, jusqu'à présent, un simple redémarrage du serveur faisait perdre les données saisies par l'utilisateur (par
exemple dans l'application "app_11").
Les collections vont nous permettre de stocker les données et de pouvoir les réutiliser.
Qui dit base de données, dit requête, mais qu'est-ce qu’une requête ?
Les requêtes sont, en quelque sorte, des "ordres" donnés à la base de données. Les requêtes peuvent avoir trois buts : la
lecture des informations stockées dans la base de données, l'écriture d'informations dans la base de données ou encore la
suppression d'informations stockées dans la base de données.

Mais sous quelles formes sont stockées les informations dans la base de données ?
Quand vous allez effectuer une requête pour ajouter des données à une collection (donc, écrire dans une base de
données), vous allez devoir envoyer les données sous forme d'objet JavaScript.
Si par exemple vous désirez stocker une fiche de renseignement qui comporte un nom (Toto) et un prénom (Titi), vous
devrez tout d'abord créer l'objet JavaScript suivant : fiche = {nom : 'Toto', prenom : 'Titi'}.
Partons maintenant du principe que nous voulons stocker cette fiche de renseignement dans un collection ayant pour
nom Fiches (une collection peut accueillir un très grand nombre de fiches), il nous faudra écrire la requête suivante :
"Fiches.insert(fiche)".
Si maintenant nous désirons "récupérer" toutes les fiches contenues dans la collection "Fiches", il nous suffira d'écrire la
requête suivante :
"Fiches.find()"
Qu'est-ce qui est renvoyé par la base de données ?
La base de données renvoie un tableau d'objet JavaScript (dans le cas d'une requête "Fiches.find()", ce tableau
contiendra tous les objets JavaScript contenus dans la collection "Fiches"). Pour traiter ce tableau d'objet, il suffira
d'appliquer les méthodes déjà vues dans l'exemple "app_10".
N.B : Il est tout à fait possible d'effectuer des requêtes plus complexes, par exemple : "récupérer les fiches des
personnes ayant pour prénom Titi", mais nous reviendrons sur ces requêtes complexes un peu plus tard, contentons-nous
pour l'instant de récupérer toutes les fiches.

À faire vous-même

Afin d'initier la création de la collection "Fiches" (et donc de la base de données qui va avec), il est nécessaire de créer
un nouveau dossier "collections". Ce dossier devra se trouver "à côté" des dossiers existants ("client", "public" et
"server").
Vous remarquerez sans doute que ce dossier "collections" ne se trouvant ni dans le dossier "server" ni dans le dossier
"client" sera à la fois accessible du côté client et du côté serveur. Ceci est indispensable, car, sans vouloir trop rentrer
dans le fonctionnement interne de meteor, il faut que vous sachiez que si la base de données "principale" se trouve bien
côté serveur, chaque client possède une "copie" de cette base de données afin de rendre les interactions "client-base de
données" beaucoup plus "rapide". Toute la "magie" de meteor se trouvant dans le fait que ces copies côté client sont, en
permanence, mises à jour par le serveur.

À faire vous-même

Créez un fichier "mesFiches.js" et placez-le dans le dossier "collections"

À faire vous-même

Nous allons maintenant créer une application (app_12) qui utilisera une collection. Avant de nous intéresser au code de
cette application, quelques mots sur son principe :
L'utilisateur aura à sa disposition un formulaire pour saisir un nom et un prénom (une nouvelle fiche). La validation de
ce formulaire entraînera une série d’événements :
création d'un objet JavaScript "perso" qui contiendra le nom et le prénom saisis par l'utilisateur.
Cet objet "perso" sera placé dans la collection "Fiches".

En vous aidant des informations fournies ci-dessus, étudiez et testez cette application (app_12)

                                                                                                                          18
main.html

       App12

       App12
       {{>formulaire}}
       {{>liste}}

template.html

              Nom 
              Prénom 
              
       {{#each mesFiches}}
              {{>fiche}}
       {{/each}}

       {{#if nomUser}}
              Nom : {{nomUser}}
              Prénom : {{prenomUser}}
              
       {{/if}}

controller.js

Template.formulaire.events({
       'submit #monFormulaire': function(e){
              e.preventDefault();
              var perso={nomUser:$('#nom').val(),prenomUser:$('#prenom').val()}
              $('#nom').val('');
              $('#prenom').val('');
              Meteor.call('ficheCollIns',perso);
       }
});
Template.liste.helpers({
       mesFiches : function(){
              var mesFi=Fiches.find();
              return mesFi;
       }
});

mesFiches.js (dans le dossier collections)

Fiches = new Meteor.Collection('fiches');
Meteor.methods({
       ficheCollIns:function(p){
              Fiches.insert(p)
       }

});

Quelques explications :
    • Petite nouveauté dans le fichier "template.html" : la présence de "{{#if nomUser}}" et de "{{/if}}". Vous
        aurez peut-être compris par vous-même que ce qui se trouve entre le "{{#if nomUser}}" et le "{{/if}}" ne
        sera affiché que si "nomUser" existe.
    • La variable "mesFi" du fichier "controller.js" contient le tableau contenant lui même tous les objets de la

                                                                                                               19
collection "Fiches". Nous renvoyons donc avec le "return mesFi; " un tableau d'objet, comme dans
         l'exemple 10 (app_10) (il aurait été possible d'écrire directement "return Fiches.find(); "). Le
         traitement au niveau du template (fichier "template.html") a aussi été étudié dans l'exemple 10.
    •    Attardons-nous sur la méthode "Template.formulaire.events" : cette méthode ressemble beaucoup à ce
         que l'on a déjà vu dans l'exemple 11 (app_11) (gestion des données saisies dans le formulaire, création d'un
         objet JavaScript "perso"....). Seule la fin diffère un peu avec le
         "Meteor.call('ficheCollIns',perso);". Cette méthode "Meteor.call" prend 2 paramètres : le nom
         d'une méthode à exécuter (ici "'ficheCollIns'") et le paramètre à faire passer (ici l'objet "perso" qui vient
         d'être "créé" juste au-dessus).
         Mais où se trouve cette méthode "ficheCollIns" qui doit être exécutée ?
         De façon générale, toutes les méthodes appelées par la méthode "Meteor.call" devront se trouver dans la
         méthode "Meteor.methods" (vous trouverez cette méthode dans le fichier "mesFiches.js"). La méthode
         "Meteor.methods" prend un unique paramètre : un objet JavaScript. C'est dans cet objet JavaScript que nous
         avons "placé" la méthode "ficheCollIns". Dans notre exemple, la méthode "ficheCollIns" a pour
         paramètre "fiche". Vous avez peut-être déjà compris que "fiche" correspond au deuxième paramètre de la
         méthode "Meteor.call", c'est-à-dire à l'objet JavaScript placé dans "perso". Le
         "Fiches.insert(fiche)" que l'on trouve dans la méthode "ficheCollIns" permet donc de ranger la
         nouvelle fiche, qui vient d'être saisie par l'utilisateur par l'intermédiaire du formulaire, dans la collection
         "Fiches".
    •    Dans le fichier "mesFiches.js" j'attire votre attention sur la ligne
         "Fiches = new Meteor.Collection('fiches');". C'est cette ligne qui permet d'initialiser la collection
         "Fiches", il est donc très important de ne pas l'oublier.
    •    Vous avez sans doute remarqué qu'une nouvelle fiche qui vient d'être saisie par l'intermédiaire du formulaire se
         retrouve immédiatement affichée. La collection est donc "surveillée" en permanence et le moindre changement
         est immédiatement répercuté au niveau de tous les éléments qui utilisent cette collection (dans notre cas le
         template "fiches"

Tout cela doit vous paraître bien complexe, n'hésitez donc pas à poser des questions.

À faire vous-même

Lancez l'application "app_12" et ouvrez 2 fenêtres de votre navigateur préféré.

Vous pouvez constater qu'une nouvelle fiche saisie dans une des 2 fenêtres est immédiatement affichée dans les 2
fenêtres. Ce qui est vrai, en local, dans nos 2 fenêtres serait évidemment vrai, pour tous les clients connectés à notre
application, même s'ils se trouvent à des milliers de kilomètres les un des autres.

Il est possible d'effacer tout le contenu des collections utilisées dans votre application avec une simple ligne de
commande dans la console : "mrt reset"

                                                                                                                           20
À faire vous-même

Toujours en utilisant l'exemple 12 (app_12), supprimer toutes les données contenues dans la collection " Fiches" en
utilisant la ligne de commande "mrt reset".

À faire vous-même

Vous allez créer une nouvelle application (app_13) en vous basant sur l'exemple 12 (app_12). Cette nouvelle application
devra proposer à l'utilisateur de saisir un nom, un prénom et le nom d'un fichier "photo". Chaque fiche devra contenir
les informations saisies par l'utilisateur et afficher la photo (voir la capture d'écran ci-dessous).
Les photos seront placées dans le répertoire "public" de votre application meteor. Aucun système d'upload (client vers
serveur) des photos n'est demandé ici. Si aucun nom de photo n'a été saisi pour une fiche donnée, une photo "par
défaut" devra tout de même être affichée.

                                                                                                                      21
Activité 9
                                     Construire un menu avec Bootstrap

Cette activité ne sera pas directement consacrée à meteor (même si nous allons tout de même l'utiliser). En effet nous
allons nous intéresser au style et à la mise en page d'une application web. Vous devez sans doute déjà savoir que le style
et la mise en page d'un site internet se gèrent grâce au CSS (voir l'annexe 2 pour plus d'information sur le CSS), mais il
est, pour des non-spécialistes, parfois difficile de créer le style et la mise en page d'un site en partant de zéro. C'est pour
cela que Bootstrap existe !

D'après Wikipedia :
Bootstrap est une collection d'outils utile à la création de sites web et applications web. C'est un ensemble
qui contient des codes HTML et CSS, des formulaires, boutons, outils de navigation et autres éléments
interactifs, ainsi que des extensions JavaScript en option.

Nous n'allons, dans cette activité, explorer toutes les possibilités offertes par Bootstrap, nous allons juste apprendre à
réaliser un menu. Mais je vous invite très fortement à visiter le site http://getbootstrap.com/ afin de vous familiariser
avec ce magnifique outil qui vous sera très utile si vous ne voulez construire de "belles" applications web sans trop
"vous prendre la tête" avec le CSS.
Attention : si vous recherchez des ressources pour apprendre à utiliser Bootstrap sur internet, il faut bien que vous
recherchiez des tutoriaux sur Bootstrap 3 (la version 2 est incompatible avec la version 3).

À faire vous-même

Créez une nouvelle application meteor (app_14). Installez Bootstrap grâce à meteorite à l'aide de la console, en vous
plaçant dans le répertoire app_14 qui vient d'être créé et en tapant :
mrt add bootstrap-3

À faire vous-même

Saisissez, étudiez et testez les codes suivants (app_14)

main.html

       App14

       {{>menu}}

template.html

              App 14
              
                Accueil
                Page 1
                Page 2
              
Pas de fichier JavaScript pour cette application 14

Rien à ajouter sur cet exemple qui était juste là pour vous montrer qu'il est très facile de créer un menu en utilisant
Bootstrap. Notez tout de même que pour l'instant les liens pointent "dans le vide" (" href="#""). Encore une fois,
n'hésitez pas à vous renseigner sur les possibilités offertes par Bootstrap. Pour vous "obliger" à travailler sur Bootstrap,
je continuerai à l'utiliser dans les prochaines activités.

                                                                                                                             22
Activité 10
                           Créer une application multipage avec iron-router
Dans l'activité 9 nous avons créé un menu, dans cette activité nous allons utiliser ce menu afin de mettre en place un
système de navigation. Nous partirons donc du principe que notre site (ou application) web est composé de plusieurs
pages.

À faire vous-même

Créez une nouvelle application (app_15). Installez iron-router grâce à meteorite à l'aide de la console, en vous plaçant
dans le répertoire app_15 qui vient d'être créé et en tapant :
mrt add iron-router
Installez aussi bootstrap 3 comme vu dans l'activité 9.

Imaginons un site composé de 3 pages HTML "Accueil", "Page 1" et "Page 2" quasiment identiques. Les 3 pages
comportent un menu permettant de passer d'une page à l'autre (voir ci-dessous)
L'utilisateur ayant terminé sa consultation de la page "Accueil", il désire passer à la page "Page 1", il clique donc sur le
lien du menu qui lui permet d'afficher "Page 1". La page "Page 1" devra être entièrement chargée, comme si la page
"Page 1" n'avait aucun point commun avec la page "Accueil" (alors que vous pouvez constater que le menu est
identique pour les 2 pages).

La page "Accueil"

La page "Page 1"

Il paraît est peu "ridicule" de charger entièrement la page "Page 1" (menu compris), l'idéal serait de charger uniquement
ce qui a été modifié. C'est là qu'iron-router entre en jeu.

Avec iron-router vous allez définir le "squelette" de votre page (ce qui ne changera pas), par convention, nous
l’appellerons "layout". Dans le cas vu ci-dessus, le "layout" comportera uniquement le menu.

 À faire vous-même
Dans le fichier "template.html" de l'application 15 (app_15), codez un template dénommé "layout", ce template devra
afficher le menu décrit ci-dessus (pour l'instant, les attributs "src" des balises  pourront rester vides).

 À faire vous-même
Toujours dans le fichier "template.html" de l'application 15, codez un template que vous nommerez "accueil", ce
template devra afficher le texte suivant : "Ceci est la page d’accueil". Faire la même chose pour le template "page1" qui
affichera "Ceci est la page 2" et le template "page2" qui affichera "Ceci est la page 2".

Tous les acteurs sont en places, il nous faut maintenant les relier.

                                                                                                                           23
À faire vous-même
Créez un fichier "router.js" et le placez dans le dossier javascript (côté client).
Saisissez le code suivant dans ce fichier :

Router.configure({
  layoutTemplate: 'layout'
});
Router.map(function() {
  this.route('accueil', {path: '/'});
  this.route('page1', {path: '/page1'});
  this.route('page2', {path: '/page2'});
});

La première ligne "Router.configure({ layoutTemplate: 'layout' }); " permet de définir le template qui
jouera le rôle de "layout" (partie qui ne sera pas modifiée quand l'utilisateur passera d'une page à l'autre). Par souci de
simplicité, je vous rappelle que nous avons nommé ce template "layout" (mais vous pouvez choisir le nom qui vous
conviendra).
La deuxième partie du code, permet d'associer un template et une url (si cette notion d'url ne vous dit plus rien, n'hésitez
pas à revoir la 1re partie de ce document) :
"this.route('accueil', {path: '/'});" : permet d'associer la racine du site "/" au template que nous avons
nommé "accueil". Cela signifie que l'utilisateur qui "arrivera" sur le site verra ceci (avec en local, l'adresse
"localhoste:3000" dans la barre de navigation du navigateur puisque "localhoste:3000" est équivalent à
""localhoste:3000/") :

"this.route('page1', {path: '/page1'}); " : si l'utilisateur clique sur "Page 1" du menu (balise Page 1) ou s'il tape directement "localhost:3000/page1" dans la barre de navigation du navigateur, il
verra la page suivante s'afficher :

Je pense que vous n'avez pas besoin de moi pour comprendre l'utilité de la ligne "this.route('page2', {path:
'/page2'});".

À faire vous-même

Maintenant que vous connaissez les valeurs à attribuer aux attributs "src" (je vous avais demandé de les laisser vides
dans un "À faire vous-même" ci-dessus), modifiez le fichier template.html en conséquence.

Si vous testez l'application 15 maintenant, cela ne va pas fonctionner, pourquoi ? Nous n'avons pas encore spécifié
"l'endroit" où devra s'afficher la partie "variable" du site (l'endroit où devra s'afficher le template correspondant à l'url).

À faire vous-même

Modifiez le fichier "template.html" comme suit (vous pourrez vérifier en même temps que ce que vous aviez déjà écrit
est correct).

                                                                                                                              24
template.html

                     App 15
                     
                       Accueil
                       Page 1
                       Page 2
                     
              {{>yield}}
       
       Ceci est la page d'accueil

       Ceci est la page 1

       Ceci est la page 2

Vous avez sans doute remarqué le "{{>yield}} " se trouvant juste en dessous de la balise fermante nav dans le
template "layout". C'est exactement à l'endroit où se trouve ce "{{>yield}} " que viendront s’insérer les différents
templates définis dans le fichier "router.js".
Par défaut (localhost:3000), nous aurons le template "accueil" qui prendra la place de "{{>yield}} ". Si l'utilisateur
clique sur le "Page 1" du menu, le template "page1" prendra le relais du template "accueil"...

Et que devient le fichier "main.html" dans tout ça ?

Pas grand-chose, il est quasiment "vidé" de toute sa "substance".

À faire vous-même

Modifiez le fichier "main.html" puis testez l'application 15 (si cela ne fonctionne pas, reprenez les étapes une par une, si
cela ne fonctionne toujours, n'hésitez pas à poser des questions)

main.html

       App15

À faire vous-même

Créez une nouvelle application (app_16). Reprenez l'application 13 (dernier "À faire vous-même" de l'activité 8) afin
que le formulaire de saisi et l'affichage des fiches ne se trouvent plus sur la même page. Les fiches seront affichées sur
la page d’accueil (si aucune fiche n'a été saisie, un message du type "Aucune fiche saisie" devra être affiché sur cette
même page d'accueil). Un menu devra permettre à l'utilisateur de se diriger vers une page dédiée à la saisie d'une
nouvelle fiche. Ce même menu devra aussi proposer à l'utilisateur de retourner à l'accueil.
De plus vous utiliserez bootstrap 3 afin de proposer un formulaire un peu plus "beau" que celui proposé dans
l'application 13 (n'hésitez pas à consulter la documentation). Enfin, la gestion des photos n'est pas demandée dans cette
nouvelle application.

Pour vous aider :
    • Si votre collection se nomme "Fiches", un "Fiches.find().count()" sera égal aux nombres d'entrées dans
        la collection. Si "Fiches.find().count()" est égal à zéro, cela signifie que votre collection "Fiches" est
        vide.

                                                                                                                          25
•   Il est possible, dans un template, d'utiliser la structure suivante :
    {{#if condition}}
     A
    {{else}}
     B
    {{/if}}
    Si "condition" est true, le template affichera A, si "condition" est false le template affichera B

                                                                                                         26
Vous pouvez aussi lire
DIAPOSITIVES SUIVANTES ... Annuler