Vous n'êtes pas connecté. Connexion
|
|
Partie 1: Application PictionnaryDe $1Table des matières
ObjectifsNous allons survoler les bases du développement d'une application HTML5, et développer une application similaire à l'application Draw Something, compatible avec le web mobile. Cette partie va durer 3 séances de 3h. L'application complète sera rendue et vaudra 20% de la note finale du cours. Concepts abordés:
Technologies utilisées: PHP, MySQL, HTML5, CSS3, javascript Prenez l'habitude d'utiliser les outils de développement de votre navigateur pour étudier le DOM, les échanges réseau, le javascript, le CSS, ... Mise en routeDiscussion: Qu'est-ce que le HTML 5 ? On va aborder un ensemble de concepts nouveau dans le HTML5. A faire: Survoler la liste sur le site http://html5test.com/. Dans la partie 1 du cours on va se concentrer sur:
Discussion: Quels autres points de la liste connaissez vous ? vous intriguent ?
Soyez curieux, demandez, ou cherchez sur le net. Parsing Rules, headers, balises metaA faire: Validez chacun de ces documents html dans le validateur du w3c: http://validator.w3.org/#validate_by_input Corrigez les erreurs. Prenez l'habitude de valider vos documents HTML. HTML 4.01 <!doctype html public "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="fr"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>My first HTML document</title> <meta name="description" content="Exemple de description"> <link rel="stylesheet" type="text/css" href="monStyle.css"> <script type="text/javascript" src="monSript.js"></script> </head> <body> <div>...</div> </body> </html> HTML5
<!doctype html> <html lang="fr"> <head> <meta charset="UTF-8"> <title>My first HTML document</title> <meta name="description" content="Exemple de description"> <link rel="stylesheet" href="monStyle.css"/> <script src="monSript.js"></script> </head> <body> <div>...</div> </body> </html> Discussion: Commentaires ? Des différences importantes ?
Cours: Dans le document à l'url http://www.slow-lab.com/guide-balises-meta.php, lisez les sections suivantes:
Ne vous attardez pas trop dans les détails, en particulier pour les balises meta de partage Facebook: on y reviendra en détail plus tard...
Discussion: Commentaires ? Une idée de ce que peut bien être le web sémantique ?
ElementsA faire: Téléchargez le projet demoHTML5 ci-joint. Exécutez et étudier les sources de chaque fichier HTML. 1_customNonVisibleData: Etudiez le document à l'url http://www.alsacreations.com/article/lire/1397-html5-attribut-data-dataset.html 2_SectionElements: Etudiez le document à l'url http://www.alsacreations.com/article/lire/1376-html5-section-article-nav-header-footer-aside.html 3_textLevelElements: Comprenez l'utilité:
4_InteractiveElements: Etudiez le document à l'url http://www.alsacreations.com/article...s-summary.html TP FormulairesOn va créer un projet PHP avec base de données MySQL pour faire une page d'inscription, et une de connexion pour notre site. Cours: Pour les formulaires HTML5, une introduction peut être lue à la page suivante: http://standardista.com/forms/. Vous vous inspirerez ensuite des documents suivants
page inscription.htmlLe formulaire d'inscription doit comporter les champs suivants:
Prenez comme base le code suivant. Comme vous pouvez le voir,
Etudiez le code, répondez aux questions, complétez le code comme demandé. Puis, ajoutez les champs simples tels que nom, prénom, ville, taille, couleur, etc.
Ces champs font l'objet des trois sections suivantes. <!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>Pictionnary - Inscription</title> </head> <body> <h2>Inscrivez-vous</h2> <form class="inscription" action="req_inscription.php" method="post" name="inscription"> <!-- c'est quoi les attributs action et method ? --> <!-- qu'y a-t-il d'autre comme possiblité que post pour l'attribut method ? --> <span class="required_notification">Les champs obligatoires sont indiqués par *</span> <ul> </li> <li> <label for="email">E-mail :</label> <input type="email" name="email" id="email"/> <!-- ajouter à input l'attribut qui lui donne le focus automatiquement --> <!-- ajouter à input l'attribut qui dit que c'est un champs obligatoire --> <!-- quelle est la différence entre les attributs name et id ? --> <!-- c'est lequel qui doit être égal à l'attribut for du label ? --> <span class="form_hint">Format attendu "name@something.com"</span> </li> <li> <label for="prenom">Prénom :</label> <input type="text" name="prenom" id="prenom"/> <!-- ajouter à input l'attribut qui dit que c'est un champs obligatoire --> <!-- ajouter à input l'attribut qui donne une indication grisée (placeholder) --> </li> <li> <input type="submit" value="Soumettre Formulaire"> </li> </ul> </form> </body> </html> Validation des mots de passeUtilisez le code suivant pour les deux champs mot de passe. Etudiez le code, répondez aux questions, complétez le code. En particulier:
<li> <label for="mdp1">Mot de passe :</label> <input type="password" name="password" id="mdp1" pattern="regex" onkeyup="validateMdp2()" title = "Le mot de passe doit contenir de 6 à 8 caractères alphanumériques."> <!-- ajouter à input l'attribut qui dit que c'est un champs obligatoire --> <!-- ajouter à input l'attribut qui donne une indication grisée (placeholder) --> <!-- spécifiez l'expression régulière: le mot de passe doit être composé de 6 à 8 caractères alphanumériques --> <!-- quels sont les deux scénarios où l'attribut title sera affiché ? --> <!-- encore une fois, quelle est la différence entre name et id pour un input ? --> <span class="form_hint">De 6 à 8 caractères alphanumériques.</span> </li> <li> <label for="mdp2">Confirmez mot de passe :</label> <input type="password" id="mdp2" required onkeyup="validateMdp2()"> <!-- ajouter à input l'attribut qui dit que c'est un champs obligatoire --> <!-- ajouter à input l'attribut qui donne une indication grisée (placeholder) --> <!-- pourquoi est-ce qu'on a pas mis un attribut name ici ? --> <!-- quel scénario justifie qu'on ait ajouté l'écouter validateMdp2() à l'évènement onkeyup de l'input mdp1 ? --> <span class="form_hint">Les mots de passes doivent être égaux.</span> <script> validateMdp2 = function(e) { var mdp1 = document.getElementById('mdp1'); var mdp2 = document.getElementById('mdp2'); if (/* est-ce que mdp1 est valide ? */ && /* est-ce que mdp1 et mdp2 ont la même valeur ? */) { // ici on supprime le message d'erreur personnalisé, et du coup mdp2 devient valide. document.getElementById('mdp2').setCustomValidity(''); } else { // ici on ajoute un message d'erreur personnalisé, et du coup mdp2 devient invalide. document.getElementById('mdp2').setCustomValidity('Les mots de passes doivent être égaux.'); } } </script> Calcul de l'âgeOn veut parser la valeur du champs birthdate en date, comparer avec la date d'aujourd'hui, et récupérer un nombre d'années écoulées.
<li> <label for="birthdate">Date de naissance:</label> <input type="date" name="birthdate" id="birthdate" placeholder="JJ/MM/AAAA" required onchange="computeAge()"/> <script> computeAge = function(e) { try{ // j'affiche dans la console quelques objets javascript, ce qui devrait vous aider. console.log(Date.now()); console.log(document.getElementById("birthdate")); console.log(document.getElementById("birthdate").valueAsDate); console.log(Date.parse(document.getElementById("birthdate").valueAsDate)); console.log(new Date(0).getYear()); console.log(new Date(65572346585).getYear()); // modifier ici la valeur de l'élément age } catch(e) { // supprimez ici la valeur de l'élément age } } </script> <span class="form_hint">Format attendu "JJ/MM/AAAA"</span> </li> <li> <label for="age">Age:</label> <input type="number" name="age" id="age" disabled/> <!-- à quoi sert l'attribut disabled ? --> </li>
Photo de profilPour la photo de profil, on décide de charger l'image, de la redimensionner pour éviter de trop envoyer au serveur, et de stocker l'image dans le formulaire sous la forme d'une data url. Si vous ne savez pas ce qu'est une data url, survolez le document suivant: http://www.alsacreations.com/article/lire/1439-data-uri-schema.html Utilisez le code suivant pour le champs file. Etudiez le code, les explications, et écrivez le bout de code demandé. <li> <label for="profilepicfile">Photo de profil:</label> <input type="file" id="profilepicfile" onchange="loadProfilePic(this)"/> <!-- l'input profilepic va contenir le chemin vers l'image sur l'ordinateur du client --> <!-- on ne veut pas envoyer cette info avec le formulaire, donc il n'y a pas d'attribut name --> <span class="form_hint">Choisissez une image.</span> <input type="hidden" name="profilepic" id="profilepic"/> <!-- l'input profilepic va contenir l'image redimensionnée sous forme d'une data url --> <!-- c'est cet input qui sera envoyé avec le formulaire, sous le nom profilepic --> <canvas id="preview" width="0" height="0"></canvas> <!-- le canvas (nouveauté html5), c'est ici qu'on affichera une visualisation de l'image. --> <!-- on pourrait afficher l'image dans un élément img, mais le canvas va nous permettre également de la redimensionner, et de l'enregistrer sous forme d'une data url--> <script> loadProfilePic = function (e) { // on récupère le canvas où on affichera l'image var canvas = document.getElementById("preview"); var ctx = canvas.getContext("2d"); // on réinitialise le canvas: on l'efface, et déclare sa largeur et hauteur à 0 ctx.setFillColor("white"); ctx.fillRect(0,0,canvas.width,canvas.height); canvas.width=0; canvas.height=0; // on récupérer le fichier: le premier (et seul dans ce cas là) de la liste var file = document.getElementById("profilepicfile").files[0]; // l'élément img va servir à stocker l'image temporairement var img = document.createElement("img"); // l'objet de type FileReader nous permet de lire les données du fichier. var reader = new FileReader(); // on prépare la fonction callback qui sera appelée lorsque l'image sera chargée reader.onload = function(e) { //on vérifie qu'on a bien téléchargé une image, grâce au mime type if (!file.type.match(/image.*/)) { // le fichier choisi n'est pas une image: le champs profilepicfile est invalide, et on supprime sa valeur document.getElementById("profilepicfile").setCustomValidity("Il faut télécharger une image."); document.getElementById("profilepicfile").value = ""; } else { // le callback sera appelé par la méthode getAsDataURL, donc le paramètre de callback e est une url qui contient // les données de l'image. On modifie donc la source de l'image pour qu'elle soit égale à cette url // on aurait fait différemment si on appelait une autre méthode que getAsDataURL. img.src = e.target.result; // le champs profilepicfile est valide document.getElementById("profilepicfile").setCustomValidity(""); var MAX_WIDTH = 96; var MAX_HEIGHT = 96; var width = img.width; var height = img.height; // A FAIRE: si on garde les deux lignes suivantes, on rétrécit l'image mais elle sera déformée // Vous devez supprimer ces lignes, et modifier width et height pour: // - garder les proportions, // - et que le maximum de width et height soit égal à 96 var width = MAX_WIDTH; var height = MAX_HEIGHT; canvas.width = width; canvas.height = height; // on dessine l'image dans le canvas à la position 0,0 (en haut à gauche) // et avec une largeur de width et une hauteur de height ctx.drawImage(img, 0, 0, width, height); // on exporte le contenu du canvas (l'image redimensionnée) sous la forme d'une data url var dataurl = canvas.toDataURL("image/png"); // on donne finalement cette dataurl comme valeur au champs profilepic document.getElementById("profilepic").value = dataurl; }; } // on charge l'image pour de vrai, lorsque ce sera terminé le callback loadProfilePic sera appelé. reader.readAsDataURL(file); } </script> </li> Pour plus d'info sur l'API File et l'objet FileReader, ou pour savoir comment on aurait pu faire avec le drag'n drop, référez-vous à ce document (anglais): https://developer.mozilla.org/fr/docs/Using_files_from_web_applications, sections
Style CSS3 et Web mobile(inspiré de http://webdesign.tutsplus.com/tutorials/site-elements/bring-your-forms-up-to-date-with-css3-and-html5-validation/) Ajoutez le dossier css fourni dans le fichier css.zip à votre projet, et ajoutez la ligne suivante dans le header: <link rel="stylesheet" media="screen" href="css/styles.css" > La feuille de style styles.css utilise:
Web MobileCette feuille de style ne s'applique que pour les ordinateurs (media="screen"). D'autres valeurs existent, telles que "handheld" (pour les teminaux mobiles), "print" (lors de l'impression) ou encore "braille" (pour les non-voyants)... Lorsque vous rendrez l'application pictionnary, un gros bonus est offert aux applications qui s'adaptent pour les mobiles (en portrait et en paysage). Vous étudierez pour celà le document http://www.alsacreations.com/article/lire/930-css3-media-queries.html Vous pouvez émuler un terminal mobile à l'aide d'une application ou d'une extension de votre navigateur, ou connecter directement votre serveur et vote smartphone au même réseau wifi et ouvir les ports de connexion. Débrouillez-vous. La base de donnéesOn commence à toucher au serveur. Dans PhpMyAdmin ou dans la console MySQL,
CREATE USER 'test'@'localhost' IDENTIFIED BY 'test'; GRANT USAGE ON * . * TO 'test'@'localhost' IDENTIFIED BY 'test'; GRANT ALL PRIVILEGES ON `pictionnary` . * TO 'test'@'localhost'; Mainteant dans PHPStorm, connectez-vous à la base de données pictionnary avec l'utilisateur test et le mot de passe test: view -> tool windows -> database, puis ajouter datasource mysql, jdbc:mysql://localhost:3306/pictionnary, télécharger le driver si besoin.
Si votre pare-feu s'alarme, débloquez les ports.
DROP TABLE IF EXISTS `users`; CREATE TABLE IF NOT EXISTS `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(65) NOT NULL, `password` varchar(65) NOT NULL, `nom` varchar(65) DEFAULT NULL, `prenom` varchar(65) DEFAULT NULL, `tel` varchar(16) DEFAULT NULL, `website` varchar(65) DEFAULT NULL, `sexe` char(1) DEFAULT NULL, `birthdate` date NOT NULL, `ville` varchar(65) DEFAULT NULL, `taille` smallint(6) DEFAULT NULL, `couleur` char(6) DEFAULT '000000', `profilepic` blob DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
On est maintenant prêt à recevoir une soumission du formulaire "inscription".
Page req_inscription.phpOn souhaite remplir la base lorsqu'un utilisateur soumet le formulaire "inscription". Utilisez le code suivant. php
Page main.phpLa page d'entrée de l'application, avec au moins:
Page req_login.phpLa page req_login.php vérifie si il existe bien une entrée dans la base pour cet email et ce mot de passe. Si un utilisateur est trouvé, on ouvre une session et on redirige vers paint.php. Sinon, on redirige vers login.php avec un message d'erreur en paramètre d'url. Page logout.phpPour se déconnecter, le code php est très simple, il suffit d'ajouter ceci au début de la page: // Put this code in first line of web page. <?php session_start(); session_destroy(); ?> Page paint.phpSi on s'est bien inscrit ou loggé, on doit être redirigé vers la page paint.php. // Check if session is not registered, redirect back to main page. // Put this code in first line of web page. <?php session_start(); if(!session_is_registered(myusername)){ header("location:main.php"); } ?> <html> <body> Vous êtes connecté. On passe à la suite ? </body> </html> Autres extensions possiblesA part l'extension déjà proposée pour le web mobile, voici une liste de points qui vallent un gros bonus pour votre application:
Formulaire de connexionLe formulaire de connexion devra comporter les champs suivants:
http://www.phpeasystep.com/phptu/6.html http://dmouronval.developpez.com/tut...ulaires-html5/ Si vous n'êtes pas au point sur les cookies / sessions en PHP, étudiez le document à l'URL http://www.julp.fr/articles/17-php-cookies-et-sessions.html#utilisation (sections 1 à 2.2.9) Canvasquand on est loggué, on redirige vers une page paint.html, on va créer un paint interactif très simple, avec un peu de javascript. Juste des cercles de différentes tailles, et un sélecteur de couleurs avec summary/details.
http://miageprojet2.unice.fr/Intranet_de_Michel_Buffa/Web_2.0%2F%2FHTML5_Rabat_2012-2013
On veut enregistrer dans le navigateur chaque évènement souris, pour pouvoir l'envoyer au serveur plus tard, et le rejouer ensuite sur un autre appareil. On étudie les solutions de stockage interne dans le navigateur, leur adaptation par les navigateurs existants,
|
||||||||||||||||||||||||||||||||
Powered by MindTouch Deki Open Source Edition v.8.08 |