Frontend

Par défaut

Étape 1 : Formulaire complet de sélection des articles et de coordonnées bancaires

Étape 2 : Suivi des commandes dans l’interface d’administration

On prépare le document : connexion et variables

<?php
$notifications = '';
// CONNEXION
$host = "localhost";
$usr = "root";
$bdd = "form";
$pwd  = "";
$connect=mysqli_connect($host, $usr,$pwd, $bdd) or die('<p class="ko">Connexion serveur/bdd : KO</p>');
$notifications .= '<p class="ok">Connexion serveur/bdd : OK</p>';
mysqli_query($connect,"SET NAMES 'utf8'");
$sql = 'SELECT * FROM panier ORDER BY id DESC';
$exec = mysqli_query($connect,$sql);
$nb_tickets = mysqli_num_rows($exec);
?>

On crée la première partie du formulaire : il y a 2 fieldset pour les tee-shirts, les hoodies. Le montant du panier est dans un <div>.

<form id="basket" name="basket" method="POST" action="05-panier-backoffice.php">
    <fieldset id="produits">
        <legend>Produits</legend>
        <fieldset>
            <legend>T-shirt <span class="prix">20<sup>€</sup></span></legend>
            <p>
                <select id="tee" name="tee" onBlur="Calculer()">
                    <option selected>T-shirt</option>
                    <option value="green" id="tee_green" onBlur="Calculer()">T-shirt vert</option>
                    <option value="red" id="tee_red" onBlur="Calculer()">T-shirt rouge</option>
                </select>
            </p>
            <p>
                <input type="text" value="0" name="q_tee" id="q_tee" onChange="Calculer()">
            </p>
        </fieldset>
        <fieldset>
...
            <select id="hoo" name="hoo" onBlur="Calculer()">
                <option selected>Hoodie</option>
                <option value="blue">Sweat bleu</option>
                <option value="black">Sweat noir</option>
            </select>
...
            <input type="text" name="q_hoo" value="0" id="q_hoodie" onChange="Calculer()">
...
        </fieldset>
        <div id="total_valide">
            <p id="logo"><span>ticket #<?php echo $nb_tickets; ?></span></p>
            <p id="date"></p>
            <p id="calcul">
                <label>Total : </label>
                <input type="text" value="0" id="total" disabled>
            </p>
            <p id="go">
                <input name="valide" type="button" id="submit" onClick="Affiche();" value="Je valide">
            </p>
    </fieldset>

On définit une fonction en Javascript pour réaliser des calculs : on récupère les valeurs value des différents éléments avec getElementById. La fonction Calculer() est appelée dès que les input de produits perdent le focus (onBlur) ou dès qu’il y a un changement dans la quantité (onChange)

function Calculer() {
    var px_tee = document.getElementById("q_tee").value * 20;
    var px_hoo = document.getElementById("q_hoodie").value * 35;
    document.basket.total.value = px_tee + px_hoo;
}

Quand le client valide sa sélection d’articles, on exécute la fonction Affiche() qui va faire apparaitre la deuxième partie du formulaire (coordonnées bancaires). Cette fonction est située dans <head><script>…

function affiche () {
    document.getElementById("paiement").style.display="block";    
}

Il faut également que #paiement soit en display:none;. On termine le formulaire. Voir également la boucle for en PHP pour écrire automatiquement du HTML (ligne 39 pour les mois, et ligne 52 pour les années).

<fieldset id="paiement" style="display: none;">
        <legend>Informations bancaires</legend>
        <fieldset id="carte" class="clearfix">
            <p>
                <input type="radio" name="carte" value="mastercard" id="mastercard" required>
                <label for="mastercard">MasterCard</label>
            </p>
            <p>
                <input type="radio" name="carte" value="visa" id="visa">
                <label for="visa">VISA</label>
            </p>
            <p>
                <input type="radio" name="carte" value="amex" id="amex">
                <label for="amex">AMEX</label>
            </p>
        </fieldset>
        <fieldset id="acheteur">
            <p>
                <label for="titulaire">Titulaire</label>
                <input type="text" id="titulaire" name="titulaire" placeholder="Nom inscrit sur la carte">
            </p>
            <p>
                <label for="numero">Numéro</label>
                <input type="text" pattern="[0-9]{13,16}" name="numero" id="numero" placeholder="XXXX XXXX XXXX XXXX">
                <!-- le pattern pour AMEX est différent : voir sur http://html5pattern.com/Cards -->
            </p>
            <p id="cryptogramme">
                <label for="crypto">Cryptogramme</label>
                <input type="password"  name="crypto" id="crypto" pattern="[0-9]{3}" placeholder="XXX">
            </p>
        </fieldset>
        <fieldset id="date_carte">
            <legend>Date d'expiration</legend>
            <p>
                <label for="mois">Mois</label>
                <select id="mois" name="mois" required>
                    <?php 
                $mois = array('Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Aout','Septembre','Octobre','Novembre','Décembre');
                for($i=1;$i<13;$i++) {
                    echo '<option value="'.$i.'">'.$i.' - '.$mois[$i-1].'</option>';
                }
            ?>
                </select>
            </p>
            <p>
                <label for="annee">Année</label>
                <select id="annee" name="annee" required>
                    <?php
                $y = date('Y');  
                for($i=$y;$i<$y+21;$i++) {
                    echo '<option value="'.$i.'">'.$i.'</option>';
                }
            ?>
                </select>
            </p>
        </fieldset>
        <button type="submit">Je paye !</button>
    </fieldset>
</form>

Voir la version complète avec du CSS3 et une fonction Javascript pour afficher l’heure du ticket.

Démo : panier

Démo : panier

Étape 2 : Suivi des commandes dans l’interface d’administration

Administration

Par défaut

Étape 1 : on saisit une adresse dans le formulaire

Étape 2 : on enregistre l’adresse dans la base de données

Étape 3 : on gère les adresses saisies (modification/suppression)

On interroge la base de données et on récupère toutes les informations (*)

$sql = "SELECT * FROM newsletter";
$exec = mysqli_query($connect,$sql);

On fait une boucle avec les résultats (fonction while)

while($data=mysqli_fetch_assoc($exec)) {
    echo '<p><strong>'.$data['email'].'</strong> : ';
    echo '<a href="?email='.$data['email'].'&action=delete">delete</a> / ';
    echo '<a href="?old_email='.$data['email'].'&action=update">update</a></p>';
}

En cliquant sur un des deux liens, on transmet un tableau $_GET via l’URL : ?email=test@exemple.fr&action=delete

if(isset($_GET['action'])) {
    if($_GET['action']=='delete') {
        $email = $_GET['email'];
        $sql="DELETE FROM newsletter WHERE email = '$email'";
        $exec = mysqli_query($connect,$sql) or die('<p class="ko">Effacement email : KO</p>');
        $notifications .= '<p>L\'email '.$_GET['email'].' a été supprimé</p><p><a href="03-news-admin.php">Rechargez la page</a></p>'; 
}

Et pour la modification

    elseif($_GET['action']=='update') {?>
<form id="update" method="POST" action="03-news-admin.php">
    <p><label for="new_email">Nouvelle adresse</label>
    <input type="email" id="new_email" name="new_email" placeholder="Veuillez saisir la nouvelle adresse"></p>
    <input type="hidden" name="old_email" value="<?php echo $_GET['old_email']?>">
    <input type="submit" value="Je modifie">
</form>
        <?php
    }
}

On envoie de nouvelles informations via $_POST

if(isset($_POST['new_email'])) {
    $sql="UPDATE newsletter SET email='".$_POST['new_email']."' WHERE email = '".$_POST['old_email']."'";
    if(!mysqli_query($connect,$sql)) echo('<p class="ko">Modification email : KO<br/>'.$sql.'</p>');
    $notifications .= '<p class="ok">L\'email '.$_POST['new_email'].' a été modifié';     
}

Il faut maintenant assembler les différentes étapes : VERSION COMPLETE

<article>
<h1>ADMIN NEWSLETTER</h1>
<?php
// 1, CONNEXION
$host = "localhost";
$usr = "root";
$bdd = "form";
$pwd  = "";
$notifications = '';
$connect=mysqli_connect($host, $usr,$pwd, $bdd) or die('<p class="ko">Connexion serveur/bdd : KO</p>');
$notifications .= '<p class="ok">Connexion serveur/bdd : OK</p>';
mysqli_query($connect,"SET NAMES 'utf8'");

// 2, ON EXECUTE les INSTRUCTIONS GET
if(isset($_GET['action'])) {
    if($_GET['action']=='delete') {
// 2a, DELETE
        $email = $_GET['email'];
        $sql="DELETE FROM newsletter WHERE email = '$email'";
        $exec = mysqli_query($connect,$sql) or die('<p class="ko">Effacement email : KO</p>');
        $notifications .= '<p>L\'email '.$_GET['email'].' a été supprimé</p><p><a href="03-news-admin.php">Rechargez la page</a></p>'; 
    }
// 2b, FORM UPDATE
    elseif($_GET['action']=='update') {
        ?>
            <form id="update" method="POST" action="03-news-admin.php">
                <p><label for="new_email">Nouvelle adresse</label><input type="email" id="new_email" name="new_email" placeholder="Veuillez saisir la nouvelle adresse"></p>
                <input type="hidden" name="old_email" value="<?php echo $_GET['old_email']?>">
<input type="submit" value="Je modifie">
            </form>
        <?php
    }
}

// 2c,     ON EXECUTE LES INSTRUCTIONS POST SI ON RECOIT UNE MODIFICATION D'ADRESSE
if(isset($_POST['new_email'])) {
    $sql="UPDATE newsletter SET email='".$_POST['new_email']."' WHERE email = '".$_POST['old_email']."'";
    if(!mysqli_query($connect,$sql)) echo('<p class="ko">Modification email : KO<br/>'.$sql.'</p>');
    $notifications .= '<p class="ok">L\'email '.$_POST['new_email'].' a été modifié';     
}
// 3, SINON, ON INTERROGE la BDD DANS SON ENSEMBLE
    $sql = "SELECT * FROM newsletter";
    $exec = mysqli_query($connect,$sql);
    
// 3, ON AFFICHE les RESULTATS
    while($data=mysqli_fetch_assoc($exec)) {
        echo '<p><strong>'.$data['email'].'</strong> : <a href="?email='.$data['email'].'&action=delete">delete</a> / <a href="?old_email='.$data['email'].'&action=update">update</a></p>';
    }
    echo $notifications;

?></article>

Les technologies du web

Par défaut

Démarrage

  • Le starter kit : tout savoir avant de créer une page web
  • La toolbox : tous les outils pour créer une page web

Le document hypertexte

  • HTML : Hypertext Markup Language = langage de description de contenu = document structuré
  • Liste complète des balises HTML4
  • Brève présentation de CSS : le contenu/l’apparence (et le comportement avec Javascript)

Anatomie d’une balise : orthographe & syntaxe

  • <balise attribut= »valeur« >élément</balise>
<a title="description" href="URL" rel="relation">élément cliquable</a>
  • Balises imbriquées
<div>
	<p>bla bla bla</p>
</div>
  • balises de bloc et balises en ligne : positionnement dans le flux, espace occupé et enfants autorisés
  • Liste complète des attributs HTML4

Exercice : du txt au web

Exercice : du mauvais web au bon web

  • Corrigez le document d’origine (source : la quiche aux cèpes de Marmitton) et récrivez en appliquant les standards et les bonnes pratiques du web :
    • téléchargez le document
    • éliminez tout ce qui précède <div class="contourMilieu hrecipe"> et tout ce qui suit <div class="boutonBas">. Enregistrez et regardez le poids du fichier
    • corrigez l’ensemble du code : refaites l’indentation, ajoutez des commentaires, supprimez le balisage inutile, transformez les <table> en <div>
    • Enregistrez et regardez le poids du fichier

De HTML 4 à HTML 5

  • de la logique de flux à la logique de contenu (Metadata, Flux, Section, Titraille, Phrases, Contenu embarqué, Contenu interactif).
HTML5 (image provenant de chez Mammouthland)

HTML5 (image provenant de chez Mammouthland)

Le prologue

Le Document Type Declaration

  • Reconnaissance de la nature du fichier par le navigateur (document HTML, CSS, PHP / Applications)
  • Application des règles de traitement (syntaxe), définies dans l’URL
  • HTML 4.01 strict, XHTML 1.0 strict et HTML 5
  • mais aussi transitional et frameset…

HTML 4.01 Strict

  • Pas de <a target>, pas d’<iframe>
  • Casse, fermeture et attributs des balises assez libres
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

XHTML 1.0 strict

  • Balises fermées, minuscules et non minimalisées
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

HTML 5

<!DOCTYPE html>

La validation

A lire ailleurs

Le texte

Les titres

  • de <h1> à <h6>

Les paragraphes

  • <p>
  • <br /> pour les sauts de ligne
  • <hr /> pour les lignes horizontales (avec clear: both;)

Autres balises de texte

  • abbr, acronym : abbréviations et acronymes
  • code, kbd, pre, var : code, clavier, texte préformaté et variable
  • dfn : définition
  • em et strong : emphase et superemphase
  • ins et del : insérer et suppression
  • span : étiquette
  • sub et sup : indice et exposant

A lire ailleurs

Le lien

L’hypertexte

  • le rôle du lien et l’hypertextualité
  • la balise <a> : ancre
  • lien interne/lien externe (alsa) : ancre pointant vers une id ou un name dans le document (navigation)

Avec <div id= »sommaire »>…</div>, on peut construire un lien <a href= »#sommaire »>…</a>

  • relatif/absolu (alsa) : écrire le href en fonction de la racine du document ou avec l’l’URL complète.
<a href="frere.html">si l'on veut afficher un frère</a>
<a href="soeur/enfant.html">si l'on veut afficher un neveu</a>
<a href="../père.html">si l'on veut afficher un parent</a>
<a href="../../papi.html">si l'on veut afficher le parent d'un parent</a>
La famille

La famille

  • Écrivez les liens relatifs de père.html pour atteindre tous les autres documents de la famille
  • Depuis neveu.html, pointez vers tonton.html (en fait le grand-oncle !)
  • texte/une image

Anatomie complète de la balise <a>

<a href="" lang="" hreflang="" title="" rel="" accesskey="" type="" id="" name="" style="" class="" on...="" tabindex="">élément</a>
  • href=URL
  • lang=langue de l’ancre
  • hreflang=langue du document en URL
  • title=descripteur du document en URL
  • rel=relation entre ce document et celui de l’URL
  • accesskey=accessibilité clavier
  • tabindex=position de l’ancre dans la séquence de tabulation
  • type=mimetype du document en URL
  • id=identificateur unique de l’ancre dans le document
  • name=nom de l’ancre pour les liens internes
  • style=règle CSS embarquée dans l’ancre
  • on…=événement javascript
  • élément : texte ou image

A lire ailleurs

Listes

<ul>, <ol>

  • liste non ordonnée (unordered) : liste avec type= »disc/square/circle »
  • liste ordonnée (numérotée) : avec pour attributs type= »1/A/a/i/I »
  • enfant : <li>
  • listes imbriquées :
<ul>
	<li>bla bla bla</li>
	<li>bla bla bla
		<ul>
			<li>bla bla bla</li>
		</ul>
	</li>
	<li>bla bla bla</li>
	<li>bla bla bla</li>
</ul>

<dl>

  • liste de définitions, avec pour enfants <dt> définition term et <dd> définition data
<dl>
	<dt>bla</dt>
	<dd>bla bla bla</dd>
	<dt>bla</dt>
	<dd>bla bla bla</dd>
</dl>

A lire ailleurs

Tableaux

La structure

  • <thead> En-tête, <tbody> corps et <tfoot> pied-de-page + <caption> légende
  • <th> en-têtes de ligne et de colonne
légende/titre
A B C
A B C
X
Y
Z
<table width="100%" border="0" cellspacing="0" cellpadding="0" summary="résumé">
	<caption>
		légende/titre
	</caption>
	<thead>
	<tr>
		<th>...</th>
		<th>A</th>
		<th>B</th>
		<th>C</th>
	</tr>
	</thead>
	<tfoot>
	<tr>
		<th>...</th>
		<th>A</th>
		<th>B</th>
		<th>C</th>
	</tr>
	</tfoot>
	<tbody>
	<tr>
		<th scope="col">X</th>
		<td>...</td>
		<td>...</td>
		<td>...</td>
	</tr>
	<tr>
		<th scope="col">Y</th>
		<td>...</td>
		<td>...</td>
		<td>...</td>
	</tr>
		<tr>
		<th scope="col">Z</th>
		<td>...</td>
		<td>...</td>
		<td>...</td>
	</tr>
</table>

Un exemple

dev.multiformat.fr/demos/tableau.php

Voir aussi

Citations

et cite

<blockquote>

Pour les blocs de citation (citation longue)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi hendrerit commodo orci. Aliquam erat volutpat. Praesent egestas dapibus nunc quis imperdiet. Maecenas nec orci non sapien iaculis euismod vehicula at metus. Donec condimentum sapien id enim porttitor ac ornare eros commodo. Pellentesque ligula metus, varius a aliquet et, dictum eget eros. In hac habitasse platea dictumst. Pellentesque consequat malesuada libero, id sodales ipsum egestas vehicula. Donec ornare ullamcorper gravida. Ut suscipit sapien et ante mollis condimentum. Proin non arcu libero, ut euismod sapien.

q

Pour les citations courtes : Lorem ipsum dolor sit amet.

cite

Pour la référence de la citation : Cicéron
Attention, cite est aussi un attribut de q.

<q cite="Cicéron">Lorem ipsum dolor sit amet</q>

Mise en forme

  • Typographie française
Noms français (et anglais) du caractère à générer entités HTML Résultat
Espace insécable
&nbsp;
Guillemet à chevrons ouvrant &laquo; «
Guillemet à chevrons fermant &raquo; »
Double guillemet ouvrant &ldquo;
Double guillemet fermant &rdquo;
  • code CSS pour la balise <q>
q {Quotes: "«" "»" '"' '"';}
q:before {content: open-quote; }
q:after {content: close-quote; }

Exercice

A lire ailleurs

Une bonne page 404

Par défaut

Joindre l’identité du site et le caractère pratique de cette page indispensable

Les ingrédients

Qu’est-ce qu’il faut pour faire une bonne page 404 ?

  • Maintenir l’identité du site : ne faites pas une page trop originale. Le visiteur (surtout s’il provient de l’extérieur) doit toujours savoir où il est, chez qui il est. Une page d’erreur doit être hospitalière et engager le visiteur vers le reste du site web.
  • Expliquez de quoi il s’agit : une définition, un lien vers la page wikipédia. Soyez pédagogique !
  • Rassurez le visiteur. Expliquez les raisons possibles : faute de frappe, mauvais lien entrant, erreur côté serveur. Marketing de service : indiquez que l’administrateur du site a été prévenu de l’erreur
  • Rappelez d’où l’on vient : indiquez l’URL réclamée via php
    $_SERVER['HTTP_REFERER'])
  • Montrez comment on peut ressortir de là : formulaire de recherche, plan du site, bouton marche arrière, retour sur la page d’accueil, liste des articles les plus populaires, les plus récents, au hasard, etc., liste des catégories, des mots-clés. Bref toutes les facettes pour accéder au contenu.

Quelques ressources :

On n’oublie pas le .htaccess

ErrorDocument 404 /404.php

On peut rajouter les autres types d’erreur, et du coup les ranger dans un dossier spécial.

ErrorDocument 403 /_/errors/403.php

CSS-Tricks donne une astuce pour générer automatiquement l’en-tête et la titraille

On prévient le webmaster

La page 404, en PHP, peut envoyer un mail à l’administrateur pour lui indiquer qu’une mauvaise URL a été réclamée. Il y a un bon tuto sur Alsacreations pour faire une 404 sous WordPress.

Si vous utilisez Google Analytics, les pages d’erreur peuvent également donner lieu à un suivi. On trouvera des explications sur le blog officiel et sur le site 1ère-position. Google donne aussi quelques conseils dans les Webmaster Tools (chez Bing aussi).

Façon Top Chef

Par défaut

On revisite les grands classiques du webdesign : page 404, formulaire de contact, panier d’achat, calendrier, tableau, etc.

Mise à jour à fréquence très irrégulière !

Image

Par défaut

L’image en HTML

  • Balise autofermante en DocType Strict
  • Balise en ligne (i.e. caractère de texte)
<img src="URL relative ou absolue" alt="texte de remplacement" title="Texte d'information" width="en pixel" height="facultatif" />
  • Balise <img> pour les documents iconographiques (référencement nécessaire) et en background: url() pour les éléments décoratifs.

L’image en CSS

  • Reset CSS de l’image

img {border: none;}
a img, :lik img, :visited img {text-decoration: none; border: none;}

  • Il est recommandé de transformer la balise <img> en bloc. Voire de lui construire un style visuel spécifique
img {
 display: block;
 padding: 1em;
 border: 1px solid black;
 background: #eee;
 margin: 1em;
 }

Construire un arrière-plan

Sur un sélecteur (avec ou sans class ou id), utiliser la propriété background :

h1 a {background: url(relative | absolue) no-repeat fixed X Y;}

A lire ailleurs…

Formulaires (HTML5)

Par défaut

Exercice Katadyn

Gestion d’un fonds documentaire d’entreprise

Vous travaillez pour l’entreprise Katadyn (équipement outdoor), qui a décidé de mettre en ligne un ensemble de vidéos réalisés par ses clients en situation.
www.katadyn.com

Architecture générale du site

  • Le projet WebSem doit s’intégrer dans la maquette du site (bandeau)
  • L’adoption du projet correspond à la volonté de l’entreprise de migrer son site vers HTML5 pour le rendre plus accessible (plateforme, agents logiciels)
  • Le projet s’inscrit aussi dans la volonté de profiter de l’engouement des réseaux socionumériques (cet aspect n’est pas à travailler)
  • les vidéos doivent correspondre à la nomenclature produits

Design du projet

  • Modélisation sémantique du projet (i.e. Ontologies) : produit – vidéo – client et autres
  • Back-office : formulaire enrichi de dépôt des vidéos
  • Front-office : page-type de présentation d’une vidéo

Éléments techniques

  • HTML5 : nouvelle sémantique, custom data attribute, rôle, API video
  • microformats et microdonnées

A lire ailleurs

Navigation

Par défaut
  • 1 clic pour retourner à l’accueil
  • 3 clics pour traverser le site : la largeur (changement de rubrique)
  • 7 clics pour fouiller : la profondeur (dossier et sous-dossier)

Les modèles pour le site ou pour la page

  • Menu de contenu vs. menu de navigation : les rubriques vs. les outils
  • Le fil d’Ariane : profondeur de contenu
  • Le nuage de mots-clés : richesse et focus de la thématique
  • Le menu déroulant horizontal ou vertical
  • Le sommaire ou Table of Contents : structure et sections de la page
    • les métadonnées : date, auteur, rubrique, mots-clés
    • La webographie et les notes de bas de page

    Vidéo

    Par défaut
    <video width="400" height="222" controls="controls">
    <source src="video.mp4" type="video/mp4" />
    <source src="video.webm" type="video/webm" />
    <source src="video.ogv" type="video/ogg" />
     Ici l'alternative à la vidéo : un lien de téléchargement, un message, etc.
    </video>

    La source MP4 est à mettre en premier pour être lue par iOS.

    Plus d’infos sur xul.fr et WHATWG.

    Dans le cadre du projet Katadyn (enrichissement sémantique d’un fonds documentaire vidéo par formulaire et upload), la balise <video> va servir à afficher les films.
    pour la géolocalisation, voir la page d’Alsacréations