IT
Hello (test)
Windows
Pour changer le PATH dans windows sans droit administrateur
Start Menu -> Panneau de configuration -> Comptes utilisateur
Modifier vos variables d’environment
Path et rajouter le chemin en séprant avec un point virgule (si déjà des paths présents)
fermer la session et la ré-ouvrir
Faire un print-screen
Pour faire un PrintScreen uniquement sur un écran, placer le curseur sur le bon écran et faire :
M-PrintScreen
Si un seul écran, alors pas besoin de presser la touche Alt.
Impression à l’échelle d’un pdf
Pour effacer un répertoire sous dos
rmdir /s
MINGW32
Pour envoyer un message avec Outlook
start Outlook //c ipm.note //m "mailto:johndoe@domain.com^&subject=Hello"
start Outlook //c ipm.note //m
"mailto:johndoe@domain.com;paul.traveri@gmail.com^&cc=are@gmail.com^&subject=Hello^&body=aslfdsff%0A%0Ajsdfjklé%0Aasdfjé"
Le %0A est pour insérer un retour à la ligne
emacs
Insatallation
Installer MiKTteX (développer…)
Installer emacs
Prendre la dernière version du site officiel (le .zip)
Dézipper
M-x package-install
choisir auctex
C-x C-f ~/.emacs (cela créera le .emacs au bon endroit)
copier ses lignes préférées dans celui-ci
.emacs
Le nom de ce fichier n’a pas de préfixe, il a juste un suffixe
(extension) qui est .emacs Il faut le copier dans home/yd
Pour éditer le .emacs ou le créer au bon emplacement
C-x-f ~/.emacs
Contenu du .emacs
(set-language-environment 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
(prefer-coding-system 'utf-8)
;; Pour envoyer les choses deletée à la poubelle
(setq delete-by-moving-to-trash t)
;; Changement de thème
(load-theme 'misterioso)
;; Langue par défaut et caractères accentués
(setq current-language-environment "French")
;; Position et mise en forme de la fenêtre
(setq default-frame-alist'
((top . 00)
(left . 00)
(width . 85)
(height . 48)))
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
;; Répondre 'y' plutôt que 'yes'.
(defalias 'yes-or-no-p 'y-or-n-p)
;; Pour que le curseur ne clignote plus
(blink-cursor-mode 0)
;; Langue par défaut et caractère accentués
(setq current-language-environment "French")
;; coupe les lignes au 72 ieme caractère
(add-hook 'text-mode-hook 'turn-on-auto-fill)
(defun auto-fill-hook ()
auto-fill-mode 1)
(setq fill-column 72)
;pas de beeep
(setq visible-bell 't)
;pas de message au démarrage
(setq inhibit-startup-message t)
;; Recherche non case-sensitive
(setq case-fold-search t)
;; Afficher la parenthèse correspondante
(require 'paren)
(show-paren-mode t)
;; affiche date & heure
(display-time)
(setq display-time-24hr-format t)
;; ----------------------------------------------------------------------
;; COMMANDE AucTex / LaTex
;; ----------------------------------------------------------------------
;; correction orthographique
(autoload 'ispell-word "ispell" "Check the spelling of word in buffer." 't)
(autoload 'ispell-region "ispell" "Check the spelling of region." 't)
(autoload 'ispell-buffer "ispell" "Check the spelling of buffer." t)
(global-set-key (read-kbd-macro "M-$") 'ispell-word)
(setq ispell-dictionary "francais"
ispell-skip-sgml t)
(autoload 'flyspell-mode "flyspell" "On-the-fly spelling checking" t)
(setq flyspell-default-dictionary "francais")
;; appelle de flyspell par f7 et f8 ispell-buffer
(global-set-key [f7] 'flyspell-mode)
(global-set-key [f8] 'ispell-buffer)
;; Sauvegarde des fichiers récemment ouverts + création d'un raccourci
;(add-to-list 'load-path "~/.emacs.d/lisp/recent")
;(require 'recentf)
;(recentf-mode 1)
;(defun recentf-open-files-compl ()
; (interactive)
; (let* ((all-files recentf-list)
; (tocpl (mapcar (function
; (lambda (x) (cons (file-name-nondirectory x) x))) all-files))
; (prompt (append '("File name: ") tocpl))
; (fname (completing-read (car prompt) (cdr prompt) nil nil)))
; (find-file (cdr (assoc-ignore-representation fname tocpl)))))
;(global-set-key "\C-x\C-l" 'recentf-open-files-compl)
;(require 'ido)
;(ido-mode t)
;; -----------------------------------------------------
;; CORRECTEUR ISPELL
;; -----------------------------------------------------
;: Dictionnaire francais
;(setq-default ispell-program-name "aspell")
;(setq ispell-dictionary-alist
; (cons
; '("fr_FR-lrg" "[A-Za-zÀÂÆÇÈÉÊËÎÏÔÙÛÜàâçèéêëîïôùûü]"
; "[^A-Za-zÀÂÆÇÈÉÊËÎÏÔÙÛÜàâçèéêëîïôùûü]" "[-']" t nil "~list"
; iso-8859-1)
; ispell-dictionary-alist))
;; Empèche Ispell de vérifier le contenu de certaines commandes
;(setq ispell-tex-skip-alists
; (list
; (append (car ispell-tex-skip-alists)
; '(("\\\\cite" ispell-tex-arg-end)
; ("\\\\nocite" ispell-tex-arg-end)
; ("\\\\includegraphics" ispell-tex-arg-end)
; ("\\\\figScale" ispell-tex-arg-end)
; ("\\\\author" ispell-tex-arg-end)
; ("\\\\ref" ispell-tex-arg-end)
; ("\\\\eqref" ispell-tex-arg-end)
; ("\\\\label" ispell-tex-arg-end)
; ))
; (cadr ispell-tex-skip-alists)))
;; Empèche Ispell de vérifier le contenu des citation natbib
;(eval-after-load "ispell"
; '(let ((list (car ispell-tex-skip-alists)))
; (add-to-list 'list '("\\\\cite[tp]" ispell-tex-arg-end))
; (setcar ispell-tex-skip-alists list)))
;; -----------------------------------------------------
;; COMMANDES AucTeX / LaTeX
;; -----------------------------------------------------
;; Choix des programmes de visualition selon le fichier de sortie
;(setq TeX-output-view-style (quote (("^dvi$" "^pstricks$\\|^pst-\\|^psfrag$" "dvips %d -o && start %f") ("^dvi$" "." "xdvi %dS %d") ("^pdf$" "." "xpdf %o") ("^html?$" "." "start %o"))))
;(setq TeX-view-style (quote (("^epsf$" "start %f") ("." "xdvi %dS %d"))))
;; Pour voir les les équations compilées directes dans emacs
;(load "preview-latex.el" nil t t)
;; Quelques commandes additionnelles du mode LaTeX
;(add-hook 'LaTeX-mode-hook
; (function
; (lambda ()
; (add-to-list 'TeX-command-list
; (list "PDFLaTeX" "pdflatex %s.tex"
; 'TeX-run-command nil t))
; (add-to-list 'TeX-command-list
; (list "Acroread" "acroread %s.pdf"
; 'TeX-run-command nil t))
; (add-to-list 'TeX-command-list
; (list "XPDF" "xpdf %s.pdf"
; 'TeX-run-command nil t))
; (add-to-list 'TeX-command-list
; (list "DVIPS" "dvips -o %s.ps %s.dvi"
; 'TeX-run-command nil t))
; (add-to-list 'TeX-command-list
; (list "Clean" "rm %s.log %s.aux %s.out %s.idx"
; 'TeX-run-command nil t))
; (add-to-list 'TeX-command-list
; (list "KghostView" "kghostview %s.pdf"
; 'TeX-run-command nil t))
; (TeX-PDF-mode)
; ;gestion de la table matière et autre...
; (reftex-mode)
; ;; Corrrection à la volée syntaxique
; (flyspell-mode)
; ;; dictionnaire évitant les erreurs d'accents
; (ispell-change-dictionary "francais")
;)))
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(package-selected-packages '(auctex)))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
Pour envoyer les choses deletée à la poubelle de windows
Cela permet de récupérer les fichiers ou répertoire effacés par mégarde.
(setq delete-by-moving-to-trash t)
Pour ne pas être embêté par l’affichage des accents
Je préfère encoder en UTF-8. Pour cela j’insère ce bloc de code
dans le .emacs
(set-language-environment 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
(prefer-coding-system 'utf-8)
Si le défaut persiste, on peut essayer les méthodes suivantes pour enlever remettre les accents.
Méthode 1
renommer le fichier en .txt
rouvrir ce dernier avec
Emacscopier tout le contenu
couper dans un nouveau fichier .tex
à la demande d’
Emacssi demande il y’a, ne pas l’enregistrer en UTF8, mais taper tab et choisir latin1
Remarque : Dans un pdf, si les accents sont bien présents dans emacs
et pas dans le pdf. Il faut alors faire le racourci clavier suivant~:
C-x RET f codage RET et choisir latin-1.
Méthode 2
M-x revert-buffer-with-coding-system
choisir utf-8 ou latin-1
Méthode 3
Si des accents s’affichent dans TeXworks malgré tous les packages et l’encodage UTF-8 réglés correctement (cela m’est arrivé lors d’un copier-coller du contenu de Outlook dans emacs.)
copier le contenu du fichier.tex dans un bloc note
enregistrer sous encodage UTF-8
Cela devrait fonctionner.
Méthode 4
You can also mark the entire file with C-x h and then try M-x recode-region. It will ask you for Text was really in and But was interpreted as. For the first file in your question, it looks like it should be latin-1 and utf-8, and for the second example it should probably be the other way around, utf-8 and latin-1.
After you got it right, you can choose which coding system to save the file with using M-x set-buffer-file-coding-system (or C-x C-m f for short).
copier/coller sans toujours à répondre à la même question du coding
Pour pouvoir copier/coller depuis windows et pour pas que emacs demande à chaque fois le format du coding, insérer la ligne suivante dans fichier .emacs.
(setq selection-coding-system 'compound-text-with-extensions)
Pour que les fichiers effacés en mode dired aillent dans la Corbeille de Windows
Placer ce code dans le .emacs :
(setq delete-by-moving-to-trash t)
Raccourcis clavier
Ci-dessous quelques raccourcis utiles pour l’utilisation de Emacs et LaTeX. La plupart de ces raccourcis ont été trouvés à l’addresse suivante https://loquehumaine.wordpress.com/2010/04/01/mes-raccourcis-emacs/ Un grand Merci donc à cette personne.
Général
Raccourcis |
Descriptions |
|---|---|
F7 |
mode flyspell correcteur orthographique) |
F8 |
appelle Ispell buffer |
C-h a |
propos |
C-h k |
recherche de ce que fait un raccourci |
C-g g |
annuler |
C-u 5 - |
répète 5 fois |
C-u 5 BackSpace |
efface les 5 derniers caractères |
M-/ |
complétion avec les mots des buffers ouverts |
M-x load-buffer |
charger un .emacs |
M-x xxx-mode |
mode xxx (latex,html,python,…) |
M-$ |
ispell sur le mot |
M-! |
exécuter une commande bash |
C-u- M-! |
insérer le résultat d’une commande bash |
M-x |
écrire des commandes en ligne de commande |
M-x menu-bar-mode |
pour afficher / enlever la barre d’outils |
M-x cua-mode |
copier-coller d’une autre applications |
C-x C-c |
quitte Emacs |
C-z |
minimise Emacs |
C-x u |
pour annuler (undo) |
C-x C-s |
enregistre le buffer courant |
Pour se déplacer
Raccourcis |
Descriptions |
|---|---|
C-a |
aller au début de la ligne |
M-a |
aller au début de la phrase |
C-e |
aller à la fin de la ligne |
M-e |
aller à la fin de la phrase |
C-f |
se déplacer au caractère suivant |
M-f |
se déplacer au mot suivant |
C-b |
se déplacer au caractère précédent |
M-b |
se déplacer au mot |
C-p |
se déplacer à ligne précédente |
C-n |
se déplacer à ligne suivante |
C-v |
écran suivant |
M-v |
écran précédent |
C-M-v |
écran suivant dans l’autre buffer |
C-l |
mettre la ligne active au milieu du buffer |
C-x l chiffres |
aller à la ligne chiffres |
M-< |
aller au début du buffer |
M-S-< |
aller à la fin du buffer |
C-u 0 C-l |
met la ligne courante en première ligne du buffer |
Marques
Raccourcis |
Descriptions |
|---|---|
C-SPC |
faire une marque (donc le début d une région/rectangle) |
C-@ |
faire une marque (donc le début d une région/rectangle) |
M-@ |
marquer le mot (C-u 4 M-@ marquer 4 mots) |
C-x C-x |
échanger le point et la marque |
C-u C-SPC |
revenir en arrière sur les marques |
M-h |
sélectionner le paragraphe |
C-x h |
sélectionner tout le buffer |
Editer, couper, copier, coller
Raccourcis |
Descriptions |
|---|---|
C-d |
tuer la prochaine lettre |
M-d |
tuer le prochain mot |
BackSpace |
tuer la lettre présédente |
M-BackSpc |
tuer le mot précédent |
C-k |
tuer la fin de la ligne |
C-w |
tuer la région |
C-y |
coller le dernier truc tué |
M-y |
revenir plus en arrière dans la liste des |
trucs tués (après C-y donc) |
|
C-t |
échanger 2 lettres |
M-t |
échanger 2 mots |
C-x C-t |
échanger 2 lignes |
C-x r r |
copier le rectangle |
C-x r k |
tuer le rectangle |
C-x r y |
coller le rectangle |
M-z x |
tuer jusqu’au caractère x |
M-u |
uppercase |
M-l |
lowercase |
M-c |
capital |
C-x C-u |
uppercase de la région |
C-x C-l |
lowercase de la région |
Rechercher et remplacer
Raccourcis |
Descriptions |
|---|---|
C-s |
chercher |
C-r |
chercher en arrière |
M-% |
chercher / remplacer (! pour tous, C-q C-j |
pour insérer un saut de ligne, haut bas pour |
|
naviguer dans l’historique des trucs |
|
recherchés) |
|
C-M-s |
chercer avec regexp en arrière |
C-M-% |
chercher / remplacer avec regexp |
M-x replace-string |
recherche / remplacer (permet de remplacer |
par un mot commençant par un \ ) |
Fenêtres / buffers
Raccourcis |
Descriptions |
|---|---|
C-x 1 |
le buffer courant devient le seul buffer |
C-x 2 |
splitter horizontalement |
C-x 3 |
splitter verticalement |
C-x 0 |
la fenêtre du buffer courant est fermé |
C-x k |
tuer le buffer |
C-x droite/gauche |
naviguer dans la liste des buffers |
C-x o |
passe l’autre fenêtre |
C-x b |
ouvrir parmi les buffers |
C-x i |
insérer un fichier |
Mode Dired
Raccourcis |
Descriptions |
|---|---|
q |
close the file |
c |
copy file |
R |
rename file |
D |
Delete file |
+ |
create a new dir |
z |
compress / decompress |
m |
mark a file |
u |
unmark |
U |
unmark all marked |
&m |
mark by file name extension |
%m |
mark by pattern (regex) |
g |
refresh |
x |
applique les changements |
^ |
go to parent dir |
dired-do-copy |
copier le répertoire ou fichier |
Mode LaTeX
Raccourcis |
Descriptions |
|---|---|
C-c C-s |
nouvelle section (défaut : section, sinon la |
plus petite sous-section courante) |
|
C-c C-e |
nouvel environnement (défaut : itemize) |
C-c C-j |
nouvel \item |
C-u C-c C-e |
changer l’environnement |
C-c C-f C-c |
textsc |
C-c C-f C-e |
emph |
C-c C-f C-i |
textit |
C-c C-f C-b |
textbf |
C-c C-c C-t |
texttt |
C-c C-f C-r |
textrm |
si entre & & |
mathrm, … |
C-c C-f C-d |
enlever le textxx |
C-u C-c C-f C-? |
remplacer le textxx par text?? |
C-c ; |
commente la région |
C-c % |
commente le paragraphe |
Formatage
Raccourcis |
Descriptions |
|---|---|
C-M-\ |
formater la région |
M-q |
formater le paragraphe |
C-c C-q C-e |
formater l’environnement |
C-c C-q C-s |
formater la section |
C-c . |
marquer l’environnement |
C-c * |
marquer la section |
C-M-a |
début d’environnement |
C-M-e |
fin d’environnement |
Pour supprimer les ^M en fin de ligne
Faire la séquence suivante :
M-< C-q C-M Enter C-q C-j Enter !
Explications :
M-<on se place au début du documentM-%on active le mode de remplacement de caractèresC-q C-Mon va remplacer les ^MC-q C-jon va y mettre à la place des retours à la ligne!on applique ces modifications à toutes les occurences rencontrées dans le fichier
Débugger emacs
C-c apostrophe espace
Changer le thème (couleur de fond,…)
J’utilise le thème misterioso (il en existe bien sûr d’autres)
(load-theme 'misterioso)
à placer dans le .emacs
Compilation
Compilation avec XeLaTeX depuis emacs
J’utilise souvent cette méthode pour compiler une figure dessinée par psTricks qui produit directement un pdf.
afficher le menu :
M-x menu bar-mode
Command -> TeXing Options -> Use XeTeX engine
ou simplement :
C-c-c tab et sélectionner xelatex
LaTeX
Installation LaTex, Emacs et auxtex sous Linux
télécharger la dernière version de
tex-livesur le site officieltélécharger le .iso
copier les dossiers sur le bureau
écrire dans un terminal :
perl install-tl
I
etc/environement, modifier le fichier pour que ça ressemble à ceci :PATH="/usr/local/texlive/2016/bin/i386-linux:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" MANPATH="/usr/local/texlive/2016/texmf/doc/man" INFOPATH="/usr/local/texlive/2016/texmf/doc/info"
Note
changer si nécessaire 2016
installer emacs avec le synaptique
installer auxtec avec le synap
copier .emacs dans yd
pour que auxtex et emac communique entre eux, il faut rajouter ces lignes dans le .emacs (si pas déjà fait)~:
(require 'tex-site) (add-hook 'LaTeX-mode-hook 'turn-on-reftex) (setq reftex-plug-into-AUCTex t) (global-font-lock-mode t)
Tout ceci est tirer du site https:\www.math.purdue.edu/~dvb/xdvi.html pour que le script pour la conversion des Figures PSTicks fonctionne, il faut rajouter (dans le script) -shell-escape après la commande latex. (ex. latex -shell-escape 1.tex)
Fichier modèle Document LaTeX
Warning
Essayer toujours de travailler en encodage utf8, en partant du modèle en utf8.
A compiler avec pdflatex. Comprenant titre, logo et table de matière.
\documentclass[a4paper, 11pt,titlepage]{article}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
\usepackage[utf8]{inputenc} % utf8 sinon essayer avec latin1
\usepackage{longtable}
\usepackage{array}
\usepackage{colortbl} % Pour l'utilisation des couleurs
% dans les tableaux et pour que
% definecolor fonctionne
\usepackage{placeins} % permet d'utiliser la commande FloatBarrier
\usepackage[left=2.3cm, right=1.8cm, top=2cm]{geometry} % See
% geometry.pdf to learn the layout
% options. There are lots.
\geometry{a4paper} % or letterpaper (US) or a5paper or....
%\usepackage[parfill]{parskip} % Activate to begin paragraphs with an
%empty line rather than an indent
\usepackage[pdftex]{graphicx}
\usepackage[pdftex,bookmarksopen=false,pdfauthor=ydu,colorlinks=false,pagebackref,plainpages=false]{hyperref}
\begin{document}
\begin{center}
%pour mettre un titre
%\includegraphics[width=4cm]{figures/Logo}\\[1.5cm]
\Huge
ewrqwru\\
rewtzhj\\
àèààvséjefwh\\[1.5cm]
\texttt{Nom du département}\\[1cm]
%\includegraphics[width=10cm]{figures/1}\\[2cm]
\large
%Auteur~:~\textsc{votre nom}\\
Date~:~\today\\[1cm]
\end{center}
\tableofcontents
\newpage
\section{première section}
...
\end{document}
Figure psTricks
Fichier modèle
Pour faire une figure psTricks. A compiler avec fichier tex2pdf.sh
Warning
Essayer toujours de travailler en encodage utf8, en partant du modèle en utf8.
\documentclass{article}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc} % changer si ça bug en utf8
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{pstricks,pst-node}
\usepackage{xifthen}
\usepackage{longtable}
\usepackage{array}
\usepackage{hyperref}
\begin{document}
\thispagestyle{empty}
\begin{pspicture}
...
\end{pspicture}
\end{document}
Variante A
Copier le fichier tex2pdf.sh dans le même répertoire du fichier .tex de la figure
Dans un prompt Anaconda, par exemple et à condition d’avoir installer MiKTeX et réglé le PATH, tapez:
tex2pdf.sh nom_fichier (sans l'extension .tex)
Explication du fichier tex2pdf.sh
#!/bin/bash
latex -shell-escape $1.tex
dvips -E -o mafigure.eps *.dvi
ps2epsi mafigure.eps mafigure_tmp.eps
mv mafigure_tmp.eps mafigure.eps
mv mafigure.eps $1.eps
epstopdf $1.eps
rm $1.eps
rm $1.aux
rm $1.dvi
rm $1.log
rm $1.out
rm $1.tex~
Ce fichier utilise le schéma suivant pour compiler:
latex -> dvips -> ps2epsi -> epstopdf
ps2epsi sert à enlever le blanc autours de la figure. Ensuite grâce au
rm, il efface les fichiers non désirables.
Variante B
Pour créer des figures pstricks j’utilise emacs pour compiler en xelatex et TeXworks pour voir le résultat compilé en mettant la fenêtre texwork à côté de celle de emacs.
Voir le résultat compilé avec xelatex avec TeXworks)
Cropper automatiquement un pdf
Pour enlever le blanc autours d’une figure, utiliser le service en ligne pdfresizer. Selectionner automatique pour vraiment enlever tout le blanc autours d’une figure. L’inconvénient est qu’il y aura plus de marge entre le texte et la figure, il faudra insérer une ligne vide.
Redessiner sur un pdf :
convertir le pdf en .eps dans une console Unix en tapant :
pdftops -eps fichierpdf.pdf
Note
remarque cette commande marche uniquement sur un pdf d’une page seulement, si le pdf contient plusieurs pages, il faudra au préalable extraire la page qui nous intéresse. Pour ce faire, voir Extraction d’une page d’un document pdf
utiliser le fichier FicViePSTriBox.tex téléchargeable depuis ici
pour créer le pdf directement utiliser XeLaTeX (voir Compilation avec XeLaTeX depuis emacs)
pour visualiser le résultat après un C-c C-c, ouvrir le .tex avec TeXworks et choisir XeLaTeX cela va ouvrir une fenêtre pour voir le pdf créer
rogner le pdf avec Briss (voir BRISS)
Sur un print-screen avec psTricks :
faire un print-screen (voir Faire un print-screen)
ouvrir GIMP
enregistrer sous .eps
utiliser le fichier FicViePSTriBox.tex situé ici
pour créer le pdf directement utiliser XeLaTeX (voir Compilation avec XeLaTeX depuis emacs)
pour visualiser le résultat après un C-c C-c, ouvrir le .tex avec TeXworks et choisir XeLaTeX cela va ouvrir une fenêtre pour voir le pdf créer
rogner le pdf avec Briss (voir BRISS)
Centrer la figure (pour les grosses figures)
Mettre dans le préambule :
\setlength{\topmargin}{-2cm}
\setlength{\evensidemargin}{-1cm}
\setlength{\oddsidemargin}{-3cm}
pour modifier les marges.
Note
Il arrive que cela génère une page blanche avant la figure et la
page comprenant la figure soit numérotée. (malgré d’avoir utilisé
la commande \thispagestyle{empty}) On peut utiliser la commande
suivante :
\usepackage{nopageno}
Diagramme de flux
Pour dessiner un diagramme de flux ou flow chart, j’utilse pasmatrix pour le placement des symboles. Voici les fichiers et répertoire nécessaire pour ce projet.
Le fichier FlowChart.tex a été compilé avec le script tex2pdf.sh dans un prompte Anaconda. La plupart des symboles sont présents, mais d’autres peuvent bien-sûr être rajoutés. (à chercher sur le net)
Voici le résultat:
Et le code source:
\documentclass{article}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc} % changer si ça bug en utf8
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{pstricks,pst-node}
\usepackage{xifthen}
\usepackage{longtable}
\usepackage{array}
\usepackage{hyperref}
\graphicspath{{./symboles/}} %les symboles du flow chart sont à mettre
%dans ce répertoire comme les B.eps,
%BR.eps, ...
\newcommand{\B}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{B.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{B.eps}\Large\raisebox{4pt}#1}}}
\newcommand{\BR}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{BR.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{BR.eps}\Large\raisebox{1pt}#1}}}
\newcommand{\C}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{C.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{C.eps}\Large\raisebox{4pt}#1}}}
\newcommand{\CH}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{CH.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{CH.eps}\Large\raisebox{1pt}#1}}}
\newcommand{\E}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{E.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{E.eps}\Large\raisebox{2pt}#1}}}
\newcommand{\EV}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{EV.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{EV.eps}\Large\raisebox{2pt}#1}}}
\newcommand{\F}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{F.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{F.eps}\Large\raisebox{4pt}#1}}}
\newcommand{\I}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{I.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{I.eps}\Large\raisebox{1pt}#1}}}
\newcommand{\M}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{M.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{M.eps}\Large\raisebox{1pt}#1}}}
\renewcommand{\P}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{P.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{P.eps}\Large\raisebox{1pt}#1}}}
\newcommand{\PM}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{PM.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{PM.eps}\Large\raisebox{1pt}#1}}}
\renewcommand{\S}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{S.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{S.eps}\Large\raisebox{1pt}#1}}}
\newcommand{\HG}[1][]{\ifthenelse{\isempty{#1}}{\fbox{\includegraphics[width=0.5cm]{HG.eps}}}%
{\fbox{\includegraphics[width=0.5cm]{I.eps}\huge\raisebox{1pt}#1}}}
\newcommand{\Z}{[mnode=dot] Z}
\begin{document}
\thispagestyle{empty}
\begin{pspicture}
\small
\rput[lb](-4,-5){
\begin{psmatrix}[mnode=r,colsep=0.8cm,rowsep=0.6cm,nodealign=true]
%1 2 3 4
& \B \\%1
& \Z \\%2
& \I[1] & &\Z \\%3
& \S[1] \\%4
& \S[2] \\%5
& \S[3] \\%6
& \E \\%7
& \I[2] \\%8
\C[1]& &\P \\%9
\Z & &\HG \\%10
\I[3]& \\%11
\C[2] \\%12
&&\Z \\%13
\psset{arrows=->}
% Remarque ci-dessous ce ne sont pas des coordonnées mais la position
% dans la matrice, par exemple {1,2} 1 est la première ligne et 2 la
% deuxième colonnne.
\ncline{1,2}{3,2} % B à I1
\ncline{3,2}{4,2} % I1 à S1
\naput[labelsep=1.5pt]{\textcolor{red}{OUI}}
\ncline{4,2}{5,2} % S1 à S2
\ncline{5,2}{6,2} % S2 à S3
\ncline{6,2}{7,2} % S3 à E
\ncline{7,2}{8,2} % E à I2
\ncangle[angleA=180,angleB=90,arrows=->]{8,2}{9,1} % I2 à C1
\nbput[labelsep=1.5pt,npos=0.35]{\textcolor{red}{NON}}
\ncline{9,1}{11,1} % C1 à I3
\ncline{11,1}{12,1} % I3 à C2
\naput[labelsep=1.5pt]{\textcolor{red}{OUI}}
\ncangle[angleA=0,angleB=90,arrows=->]{8,2}{9,3} % I2 à P
\naput[labelsep=1.5pt,npos=0.35]{\textcolor{red}{OUI}}
\ncline{9,3}{10,3} % P à HG
\ncline{-}{10,3}{13,3} % HG à noeud
\ncangle[angleA=-90,angleB=180,arrows=-]{12,1}{13,3} % C2 à noeud
\ncangle[angleA=0,angleB=-90,arrows=-]{13,3}{3,4} % noeud à noeud
\ncangle[angleA=90,angleB=0,arrows=->]{3,4}{2,2} % noeud à noeud
\ncline{-}{3,2}{3,4} % I1 à noeud
\naput[labelsep=1.5pt,npos=0.25]{\textcolor{red}{NON}}
\ncbar[angleA=0,angleB=0,arm=1,arrows=->]{11,1}{10,1} % I3 à noeud
\naput[labelsep=1.5pt,npos=0.45]{\textcolor{red}{NON}}
\end{psmatrix}}
\rput[lb](4,-5){
\begin{tabular}{>{\centering}m{1cm}m{7cm}} %sert à définir une police
\label{repsd}
\B & Début \\\\
\I[1] & olweolsnkécjas \\\\
\I[1] & ewosxcmklwéo? \\\\
\S[1] & wesege \\\\
\S[2] & wefgfedfvg\\\\
\S[3] & tzjughmozhl\\\\
\E & tziuimbngf\\\\
\I[2] & éàlgfhjhz\\\\
\C[1] & aertéoiudsf.,nw98\\\\
\I[3] & kljrsdmévélj023\\\\
\C[2] & léjwqepr987usdkàretg90è\\\\
\P & léj34p789udsflnjewf\\\\
\HG & léj4pr82éljdfsrnjlmkdsfpo\\
\end{tabular}}
\end{pspicture}
\end{document}
Regex
Java Script
caractère seul
d -> 0-9 D -> pas des chiffres
w -> A-Z a-z 0-9 W -> pas des lettres ni des chifres
s -> espace, tabulation S tout sauf des espaces
. -> n’importe quel caractère
Quantificateur
* -> 0 ou plus
+ -> 1 ou plus
? -> 0 ou un seul
{min,max} -> entre min et max fois
{n} -> n fois
? si appairé avec un quantificateur alors ce ne sera pas gridy. gridy veut dire qui prendre la plus grande correspondance
Exemple pour Gridy :
pour enlever le gridy :
Position
^ -> début de ligne $ -> fin de ligne b -> word boundery
Exemple pour b :
Classe de caractère
[abc] -> soit un a un b ou un c [-.] -> le point n’est pas un charactère meta mais un point litéral (car il est compris dans une classe) on échappera avec si l’on veut un point litéral et qu’il n’est pas dans une classe.
“-” si il est au début de la classe il sera pris commme un trait d’union litéral. Par-contre s’il est au centre de par exemple [a-d] il sera interpréter comme un interval ici a ou b ou c ou d “^” s’il est au début alors ça inverse, par exemple [^a-c] alors tous les autres caractères seront pris sauf a,b,c.
Exemple :
Altération
(net|com) si on veut “net” ou “com”
Groupe
on appellera $1 $2 suivant qu’il y plusieurs groupe $0 représente tout ce qui a été trouvé
Back Reference
Implémentation de Regex dans Java Script
variable string:
var s = “hello”
variable regex :
var r = /hello/
Flags :
g pour global
/d{3}/g
i pour case insensitive
match :
match construit un array avec g, mais si la regex comporte un groupe () alors si le flag g est présent le groupe ne sera pas mis dans l’array
pour que même le groupe soit pris dans l’array, il faut utiliser r.exec(s) et faire une boucle:
var results;
while (results=r.exec(s){
createP(results[1]);
}
D3
Pour arrondir les chiffres
bash
Echo
Afficher des variable système
echo PATH
echo HOME
pour remplir un fichier
echo -e "Qte\tPrix\tTotal\n\n3\t5\t15frs" > fichier
Note
On peut afficher le contenu d’un fichier avec la commande cat
nom_de_fichier. Si l’on veut rajouter des lignes au fichiers on
peut utiliser >> Mais dangereux car on a vite fait d’oublier de
mettre le deuxième >.
Sed and Awk
Les différents moyens d’entrer du code
awk -f nom_du_script fichier_d_entree
En tapant tout le code dans un terminal :
awk '
BEGIN{
print "Hello
World"}
'
Warning
Ne pas oublier l’espace entre awk et '
En tapant le code dans un fichier avec la commande awk insérée dans le fichier :
Si le code contient BEGIN et une expression régulière alors on
entrera :
awk 'BEGIN { print "debut"}
$0 ~ /Drive/ {print "sdfsd"}' nom_du_fichier_d_entree
Si le code contient pas d’expression régulière mais un BEGIN, on
entrera :
awk 'BEGIN { print "debut"}
{print "sdfsd"}' nom_du_fichier_d_entree
Si le code ne contient pas de BEGIN alors on entrera :
awk '{
print "Hello World"
}
' nom_du_fichier_d_entree
Passage des variables
Voici un exemple pour le passage des variables d’entrée d’un programme awk entrer dans un fichier qui s’appelle glitch.
awk 'BEGIN { FS = "\n"; RS = ""; ORS = "\n\n"}
$0 ~ search {print $0}' search=$1 $2
Ici on a mis le séparateur de champ FS à un retour de ligne et le
séparateur d’enregistrement RS à une ligne vide, ceci afin de
pouvoir prendre en compte un fichier à données en bloc appelé
glitch.data dont voici un extrait :
machine Sun 3/75
8 meg memory
Prone to memory glitches
more info
more info
sadlefsdaf siwefo
asdlfa
vmasefsdae
glitche wefsd
sdafsdf
ziweower wwerwe 3234
sdfljkljké
asdfvm78
weojwd
omcvljdoji
En tapant la commande :
glitch glitc glitch.data
cela va donner :
machine Sun 3/75
8 meg memory
Prone to memory glitches
more info
more info
sadlefsdaf siwefo
asdlfa
vmasefsdae
glitche wefsd
sdafsdf
Les fonctions
Emplacement pour déclaration des fonctions
awk '
function insert (STRING, POS, INS) {
before = substr("Hello",1,POS)
after = substr("Hello",POS+1)
return before INS after
}
BEGIN{
print insert($1, 4, "XX")
}'
Divers exemples
Pour inverser les colonnes et les lignes
awk '
BEGIN{FS=";"}
{
for ( i = 1; i <= NF; ++i ){
matrice[NR,i] = $i
gsub(/\r/,"") #\r est le retour de ligne \n ne fonctione pas
}
}
END {
for ( j = 1; j <= NF; ++j ){
for ( i = 1; i <= NR; ++i ){
printf ("%s;",matrice[i,j]) #point virgule aux séparateurs de champs à la sortie
}
if ( j < NF )
print("\r")
}
}' sp.txt > Result
reStructuredText
Installation
installer Anaconda
installer VS code
modifier le path windows pointer les répertoires suivants :
anaconda3/Scripts
anaconda3 (c’est possible qu’il n’est pas nécessaire de pointer sur celui-ci)
Création d’un nouveau document
ouvrir Anaconda Prompt
aller dans le bon répertoire (tapez
d:pour changer de partition)une fois dans le répertoire où l’on veut mettre notre document, tapez :
sphinx-quickstart
aux différentes questions répondre comme ci-dessous :
> Separate source and build directories (y/n) [n]: y> Name prefix for templates and static dir [_]:> Project name: Mon nom de projet> Author name(s): Alpiq AG> Project release []: 1> Project language [en]: fr> Source file suffix [.rst]:> Name of your master document (without suffix) [index]:Sphinx can also add configuration for epub output: > Do you want to use the epub builder (y/n) [n]:Indicate which of the following Sphinx extensions should be enabled:> autodoc: automatically insert docstrings from modules (y/n) [n]:> doctest: automatically test code snippets in doctest blocks (y/n) [n]:> intersphinx: link between Sphinx documentation of different projects (y/n) [n]:> todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: y> coverage: checks for documentation coverage (y/n) [n]:> imgmath: include math, rendered as PNG or SVG images (y/n) [n]: y> mathjax: include math, rendered in the browser by MathJax (y/n) [n]: y> ifconfig: conditional inclusion of content based on config values (y/n) [n]: y> viewcode: include links to the source code of documented Python objects (y/n)[n]:> githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]:> Create Makefile? (y/n) [y]:> Create Windows command file? (y/n) [y]:ajouter la ligne suivante:
master_doc = 'index'sinon ça bug avec Read The Docs aussi ça plante lorsqu’on compile dans un terminal windows (cmd) ça affiche qu’un fichier dénommécontentsest introuvable.tapez dans le terminal :
D:\tmp\sphinxTxt>make html
ouvrir Visual Studio Code
ouvrir le répertoire du projet et non le fichier .rst (File -> Open Folder)
il se peut que l’on soit demandé à selectionner le
conf.py, selectionnez celui qui se trouve dans le répertoire du projetpour ouvrir la prévisualisation cliquer sur le symbole afficher sur la figure ci-dessous. Sinon ouvrir le html dans un explorateur qui se trouve dans le répertoire _build -> html
pour l’édition, j’utilise emacs, ouvrir le fichier
index.rst
Changement de Thèmes
choisir son thème ici. Pour cet exemple, j’ai choisi
sphinx_rtd_themecar il est “mobile friendly”
se connecter à internet (swisscom) et tapez dans une console :
pip install sphinx_rtd_theme
ouvrir le
conf.pyet mettrehtml_theme = 'sphinx_rtd_theme'
Compilation
Dans un Anaconda prompt tapez :
make html
Pour voir la doc dans un navigateur internet. Ceci créera un répertoire
build et y placera deux autres répertoires : html et
doctrees Dans le répertoire html on trouvera le fichier
index.html. En cliquant sur ce dernier cela va ouvrir la doc dans
un navigateur internet.
Le répertoire doctrees sert pour la table des matières.
ou
make latex
ou
make latexpdf
Note
Après la compilation, il se peut que la table des matières ne soit pas dans l’ordre ou que toutes les sections suivantes ne soient affichées. Dans ce cas, il faut supprimer le répertoire build et refaire une compilation.
Traduction
-doc
.git
.gitignore
make.bat
Makefile
-build
-doctrees
-gettext
index.pot
-html
-latex
-sources
-locale
-de
-LC_MESSAGES
index.po
-fr
-LC_MESSAGES
index.po
-dir
-images
-de
-1.png
-fr
-1.png
Les textes à traduire se trouvent dans les fichiers .po
Liens à traduire et problèmes
Pour les liens à traduire qui sont internes au document et qui n’ouvrent pas de nouvelle fenêtre ça fonctionne bien. Par-contre pour les liens qui ouvrent une nouvelle fenêtre comme dans le code suivant:
This is in my .rst:
On ouvre une nouvelle fenêtre |lien|
.. |lien| raw:: html
<a href="http://python.physique.free.fr/aide/_sources/Partie1.txt"
target="_blank">ici</a>
and this is the translated file:
#: ../../source/consigne_indispo/consigne_indispo.rst:4
msgid "On ouvre une nouvelle fenêtre |lien|"
msgstr "Wir öffnen ein neues Fenster |lien|"
The problem is that I want to translate the world "ici" also (should
be translated in "hier", but can't see it in the translated file.
installer sphinx-intl
$ pip install sphinx-intl
rajouter ces lignes dans le conf.py
locale_dirs = ['locale/'] # path is example but recommended. gettext_compact = False # optional. gettext_additional_targets = ['image', 'index', 'literal-block'] # allows images to be translatable. Cette ligne permet de traduire les "alt" ou "les légendes" figure_language_filename = "{path}{language}/{basename}{ext}"
make gettext
génération des fichiers po (dans le cas suivant pour l’allemand et pour le japonais)
sphinx-intl update -p build/gettext -l de -l jasitôt fait, le fichier po se trouve dans le répertoire ./locale/de/LC_MESSAGE`
traduire le fichier po
exemple :
msgid "Available builders" msgstr "<FILL HERE BY TARGET LANGUAGE>"Dans le cas où il y a plusieurs lignes :
msgid "" "These are the built-in Sphinx builders. More builders can be added by " msgstr "" "FILL HERE BY TARGET LANGUAGE FILL HERE BY TARGET LANGUAGE FILL HERE " "BY TARGET LANGUAGE :ref:`EXTENSIONS <extensions>` FILL HERE."
génération du document traduit, saisir dans le Anaconda Powershell Prompt Bien faire dans ce Prompt car dans l’autre la commande
Set...ne fonctionne pas. Ici on veut générer le html pour l’allemend (de)
> Set-Item env:SPHINXOPTS "-D language=de" > .\make.bat html
génération d’une langue supplémentaire : il suffit de remplacer
deparenpar exemplesi l’on a fait des mises à jour, il faudra faire les étapes 3) et 4) pour regnérer le .po. Si les .po ne subissent pas de changement il ne seront pas effacés ni regénérés.
Images différentes pour chaque langue
figure_language_filename = "{path}{language}/{basename}{ext}" à
mettre tel quel dans le fichier conf.py
gettext_additional_targets = ['image', 'index', 'literal-block'] #
allows images to be translatable
cette dernière ligne je ne sais pas encore à quoi elle sert, mais je l’ai mise quand même.
Important
Il est impératif de créer à l’endroit où il y a le fichier .rst un
répertoire se nommant images (et pas figure par exemple sinon
ça marche pas).
créer un répertoire se nommant
imagesà l’intérieur de ce répertoire créer des répertoires pour chaque langue. Par exemple pour le français et l’allemand :
frde
Je ne sais pas si l’abréviation de la langue est importante (fr et de)
dans chacun de ces répertoire l’image bien que différente, doit être nommée à l’identique. ex. dans le répertoire
frune image nommée1.pngse retrouvera aussi dans le répertoiredeavec le même nom1.png.
Pour plus d’information
Mise en forme
Numérotation chapitre, section, etc…
#pour les parties*pour les chapitres=, pour les sections-, pour les sous-sections^, pour les sous-sous-sections", pour les paragraphes
Listes et sous-listes
* une puce "*"
- une sous-liste avec "-"
+ à nouveau une sous-liste avec "+"
- une autre option
1. Liste numérotée "à la main".
2. Deuxième item.
#. Liste numérotée automatiquement.
#. Deuxième item.
Liste numérotée “à la main”.
Deuxième item.
Liste numérotée automatiquement.
Deuxième item.
Les tableaux
+------------------------+------------+----------+
| Header row, column 1 | Header 2 | Header 3 |
+========================+============+==========+
| body row 1, column 1 | column 2 | column 3 |
+------------------------+------------+----------+
| body row 2 | Cells may span |
+------------------------+-----------------------+
==================== ========== ==========
Header row, column 1 Header 2 Header 3
==================== ========== ==========
body row 1, column 1 column 2 column 3
body row 2 Cells may span columns
==================== ======================
donnera :
Header row, column 1
Header 2
Header 3
body row 1, column 1
column 2
column 3
body row 2
Cells may span
Header row, column 1
Header 2
Header 3
body row 1, column 1
column 2
column 3
body row 2
Cells may span columns
Insertion d’une figure
Si le répertoire nommé figures est au même endroit où il y a le
fichier index.rst
.. image:: /figures/IconePrevisualisation_cropped.png
:scale: 80 %
:align: center
Image svg
Pour avoir une image non pixelisée, le format svg peut être utilisé.
J’utilise l’adresse suivante (cliquer ici) pour convertir le format pdf en svg
Insérer une ligne vide
Utile par exemple quand on insère une figure croppée automatiquement (pas de marge blanche autours de la figure). Ainsi le texte ne sera pas trop de la figure.
.. # define a hard line break for HTML
.. |br| raw:: html
<br />
Mettre à l’emplacement où l’on veut avoir une ligne blanche :
|br|
Surbrillance d’un texte
Surbrillance d'un texte
Tapez :
``Surbrillance d'un texte``
Pour afficher un bloc avec du code
POUR AFFICHER CECI (un bloc avec du code)
Tapez :
::
POUR AFFICHER CECI (un bloc avec du code)
Pour créer un lien à l’intérieur d’un document
interne à la page ou à une autre page .rst
Warning
Pour que le lien fonctionne il faut bien effacer le répertoire
build avant (rmdir /s build) et refaire une compilation (make html).
label (à mettre où l’on veut tomber) :
.. _Nom du lien:
Par exemple si on veut que ça tombe vers une section, on le placera une ligne avant la section.
.. _Nom du lien:
reStructuredText
================
ref (à écrire où on veut mettre le lien)
Pour plus d'information veuillez vous référer à :ref:`Nom du lien`.
Ceci donnera :
Pour plus d’information veuillez vous référer à Les fonctions.
Pour créer un lien à une page internet
En cliquant sur le lien, cela va ouvrir une nouvelle fenêtre dans le navigateur.
En cliquant |lien|
.. |lien| raw:: html
<a href="http://python.physique.free.fr/aide/_sources/Partie1.txt"
target="_blank">ici</a>
Warning
Ne pas oublier d’indenter <a href…
On peut très bien écrire directement :
http://home.citycable.ch/windwaver/MesSources/
mais cela ne va pas ouvrir une nouvelle fenêtre dans le navigateur.
Commentaires
Pour commenter une ligne, mettre deux points et un espace.
Pour commenter un bloc, mettre deux points et indenter le bloc en dessous.
Mettre en évidence une chose importante
.. warning::
Mettre ici une chose importante
ce qui donne :
Warning
Mettre ici une chose importante
.. hint::
Une chose moins importante
ce qui donne :
Hint
Une chose moins importante
Commande |
Qui donne |
Couleur |
|---|---|---|
.. warning:: |
‘i’ int32 |
Rouge |
.. note:: |
note |
Grise |
.. tip:: |
Astuce |
Grise |
.. caution:: |
Prudence |
Grise |
.. error:: |
Erreur |
Grise |
.. hint:: |
Indice |
Grise |
Pour insérer du code à partir d’un fichier
Tapez le code suivant :
.. literalinclude:: /IT/sources/exemple_graphique01.py
Ce qui donnera :
# -*- coding: utf-8 -*-
"""
Exemple de plot
"""
from __future__ import division
from scipy import *
from pylab import *
x = linspace(0,10,400)
y = sin(x)*exp(-x/5)
plot(x,y)
show()
Pour insérer une vidéo
Tapez le code suivant :
.. raw:: html
<iframe width="560" height="315"
src="https://www.youtube.com/embed/UaIvrDWrIWM" frameborder="0"
allowfullscreen></iframe>
Ce qui donnera :
Pour insérer des formules mathématiques
Normalement, on peut inclure des maths avec :math:`code LaTeX`
ou alors avec .. math:: code LaTeX sur une seule ligne
.. math::
a^2
Ce qui donne :
Création du document pdf
à l’aide du prompt Anaconda se déplacer dans le répertoire du projet (où il y a le .rst)
tapez
make latexpdfcela va créer un répertoire latex dans le répertoire _buildouvrir le fichier .tex dans le répertoire latex avec emacs
compiler
Divers liens utiles
Visual Studio Code
Configuration
fichier JSON de configuration
Pour les lignes longues on peu mettre dans settings Word Wrap à on.
emmet est installé par défaut. Il permet de ne pas écrire tout la syntaxe balistique. Par exemple si on veut écrie <h1></h1>, il suffit d’appuyer sur h ensuite sur ce qui est proprosé faire une tabulation à droite ou enter.
Extension
Prettier - Code formatter
Permet d’aligner le code à la sauvegarde
Une fois installé, il faut aller dans settings
Il faut peut-être reloader l’extension si demandé.
Taper “format” dans la zone recherche
Cocher Format On Paste et Format On Save
Et maintenant à chaque enregistrement du fichier le texte se formate.
keyboard shortcuts
html
HTML HYPER TEXT MARKUP LANGUAGE
RESPONSIBLE FOR WEBPAGE STRUCTURE
<element>content</element>
<h1>Heading</h1> === Heading Element
<p>Paragraph</p> === Paragraph Element
<img src=”…”> === Image Element
<br /> === Line Break
<!DOCTYPE html>
Pour mettre en entête standard dans index.html on tapera ! et
return emmmet insérera l’entête standard pour le fichier index.html.
Toutes les pages html suivent la même structure. Tout en haut nous avons la déclacration DOCTYPE qui dit au browser en quel version du language html la page est écrite. Ensuite nous avons la balise html qui englobe tout notre code de la page. Celle possède au moin un head et un body. Donc après l’élément html nous avons l’élément head qui contient des informations de la page comme par exemple le titre de la page, les métadatas, et les links vers source extérieures comme les fichiers de style css et les fichiers java script. Le contenu de head ne sera pas visible dans la page. Le body contiendra headings, paragraphes, links.
Maintenant que nous connaissons les bases du contenu d’une page, mettons ceci dans notre première page. En tapant <, VS va nous proposer !DOCTYPEhtml qui est la version 5 de html. Ensuite vient la balise html. Puis body dans lequel on met un h1 avec du texte. Enchaînant avec un paragraph.
Grâce à l’extension live server notre résultat est affiché automatiquement après un save.
En mettant autosave notre résultat sera affiché en live.
Tout le contenu que l’on a tapez précédemment peut être simplifié par
emmet. Tapez simplement ! et enter.
Pour l’instant, on fera attention que pour title et se qui se trouve dans le body.
headings
paragraph
Pour info html is white space collapsing, c’est-à-dire que html ignore les espaces que l’on aurait fait en trop entre deux mots. Si l’on veut vraiment un espace plus grand, on verra ceci plus tard.
Regardons maintenant comment on peut écrire un bout de texte
(n’importe quel paragraphe) rapidement.
Tapez : Lo et choisissez lorem. On peut choisir le nombre de
mots que l’on souhaite afficher en tapant lorem50 pour 50 mots.
Images
Si l’on veut des images quelconques, on peut chercher dans google udemy image.
Tapez img et enter on doit indiquer dans src le chemin où se
trouve l’image sur le disque. et alt est renseigné pour que si l’image
ne peut être trouvée, un texte alternative est affiché à la place de
l’image.
Il est préférable d’utiliser le relative path :
./
On peut très bien pointer sur l’adresse d’une image sur le web: dans
ce cas il faut faire un clique droite sur l’image est faire copier
l'adresse de l'image. L’inconvénient de cette technique est d’avoir
une adresse monstrueuse de l’image. Il existe des sites qui propose
des images sans licences dont l’adresse est plus simple. Comme par
exemple :
Enregistrer l’image dans le dossier.
Modifier la taille
On a prit une grand image et l’affichage est tronqué. Pour ajuster la taille de l’image, on pourrait très bien diminué sa taille avec un logiciel, mais ici nous allons utiliser les attributs d’html pour modifier la taille de l’image.
Pour mettre l’image à la même taille que la première nous allons utiliser Visual Studio Code pour en ouvrant la première image.
et relever la valeur de 246x205 affichée dans le bandeau inférieur. Et pour la plus grande image nous avons 5999x3681
On rajoute un attribut width=”246” et le tour est joué.
Il y a un autre attribut qui est height mais si on met celui-ci
l’image sera déformée, donc garder uniquement width.
Il y a un grand problème encore quand le browser render l’image bien
qu’elle aie diminué en taille elle sera toujours chargée avec un
grande taille d’octets. Ce qui va réduire le user experience. Utiliser
un logiciel libre comme gimp et réduire la taille directement à la
bonne taille et ensuite enlever le width.
path
Créons un dossier images avec les images dedans. Et modifions le chemain des images.
Commentaires
Raccourci clavier : appuyer en même temps sur ctrl alt et “a”
line break
<br>
links
External links
Pour mettre un lien
Pour que la page s’ouvvre dans une autre page
Internal links
Internal links dans la même page
créons un id à l’endroit où l’on veut tomber
Mettre un lien sur une image par exemle
A la place de cliquer sur un texte souligné representant un lien, nous pouvons mettre à la place une image.
Si l’on ne sait pas encore le lien, on peut mettre un # à la place de l’url.
sub and sup
strong
em
Normalement, nous utilisons ces éléments dans le css.
Caractères spéciaux
Copyright
Pour d’autres caractères spéciaux, se référer à google “special html caracter”.
Liste
Liste non numérotée
Exemple d’utilisation des listes non numérotée
Pour faire un menu. Pour l’instant le style n’est pas bon, mais nous verrons plus tard comment l’améliorer.
Liste numérotée
Liste imbriquée
Table
avec:
th pour table head
tr pour table row
td pour table data
Form
Pour l’introduction des formulaires nous ne nous s’occuperons pas de acction=”” ni de method=”” car ces attributs sont pour la collecte de donnée avec par exemple php ou JS.
Pour la collecte de données nous pourrions utilisé https://formspree.io qui nous enverrais les données par email.
action est utlisée pour dire à quel email les données collectées
doivent être envoyée.
method="POST" est utilisée pour envoyer les données sur un
server.
input a plusieurs type comme email, button, checkbox. Le plus courant est le type text, il a deux attributs name et id. name est l’endroit où l’on veut stocker les données. id est utilisé avec label que nous montrerons plus loin.
input type=”text”
Nous voyons le champs dans lequel on peut écrire quelque chose, mais ne se passe.
label
Parlons maintenant du id. id vient avec label. On peut mettre un label à un champs.
input password et email
Regardons maintenant à d’autre input comme password et email.
placeholder
Au lieu de label nous pouvons aussi mettre un paragraphe. Mettons un placeholder qui écrit à l’intérieur du champs ce que l’on veut.
Mettons l’input email. Remarquons que si l’email n’est pas correctememnt formater, il y aura un message d’alerte.
value
Parlons de l’attribut value qui sert à coder en dure. Le champs est directement rempli par value. Aussi on peut mettre type=”submit” value pour afficher un autre texte sur le bouton submit.
textarea, bouton radio
input ne sont pas les seules élément que l’on peut mettre dans un form.
textarea, qui nous permet d’écrire plus de mots. Les attributs cols et rows permettent d’ajuster la taille de textarea.
Nous avons aussi les boutons radio. On mettra value pour travailler la collecte des inputs. Attention de bien écrire name avec le même nom car sinon nous pourrons sélectionner plusieur bouton en même temps.
checkbox
Voici comment implémenter les checkbox:
Il y a aussi un attribut checked pour dire que la case est
cochée par défaut, il est possible de la déchecker.
On remarque que des que l’on appuie sur le submit button les données ne sont envoyées à nulle part, mais on constate que l’adresse (url) se modifie avec les données saisies dans le forulaire.
select
C’est comme un drop down menu.
Documentation
https://www.w3schools.com (plus friendly)
https://developer.mozilla.og chercher “html”
Premier Projet
Etape “Home”
Créons d’abord un répertoire sur le disque local avec le nom du projet. Ici le nom du répertoire sera Coffee;
Dans la première ligne tapez
!et return. Emmet insérera un en-tête standard;Modifions le titre en mettant Coffe Junkie;
Dans le body mettons hello world;
Pour voir notre résultat faisons un clique-droite et sélectionnons Live Server;
Arrangeons un peu les fenêtres. Ouvrons un deuxième instance de Chrome et écrivons l’url de Live Server. Sur un écran, on peut mettre VS prenant un peu plus de la moitié de l’écran et l’autre moitié Chrome. Dans le premier Chrome un mettra la page sur toute sa largeur afin d’avoir une vue total en largeur de la page du site que l’on va créer;
Dans le répertoire Coffee, créons un nouveau répertoire images;
Copions les images dans le répertoire images
pour le logo dans google taper coffe logo backround transparent
pour l’image plus grande on ira la chercher sur pexels.com
Modifions trois images avec Gimp à une taille de 320px de largeur;
Ecrivons le code pour insérer le logo;
Un h3 pour le titre de la page
Un ul pour faire la liste de navigation.
Et voici le code de notre premier étape
Et l’apperçu
Insérons l’image backround la grande et nous voyons qu’elle est trop grand sur la fenêtre à coté VS et trop petite sur la grande fenêtre de Chrome. Normalement nous devons faire cela dans css, mais comme nous n’avons pas encore abordé ce sujet, nous mettrons la commande directement dans le html, avec l’attribut width à 100%
Mettons maintenant un h1 pour Feature Product
Un h2 pour House Blend Coffee
Une image
un paragraphe avec ici une petite spécialité que l’on corrige maintenant mais normalement cela va se faire en css. Le paragraphe s’étire sur toute la largeur de la page en plein écran et c’est pas beau. On fait du inline styling en écrivant <p style=”width:50%”>
un h3 pour un lien vers wikipedia, remarquer l’attribut de target=”_blank” pour que l’utilisge ouvre une nouvelle page et ne quitte notre site
copions ce code pour les deux autres produits et changeons les noms et images.
mettons le copyright avec © pour le caractère spéciale
insrérons quelques br et un lien vers le top ou logo mais étant donné que nous n’avons pas encore de id sur l’image du logo, rajoutons le maintenant
Voici le code pour cette étape:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Coffee Junkie</title>
</head>
<body>
<img src="./images/logo.png" id="logo" alt="coffe logo">
<h3>Coffee Junkie</h3>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="number.html">Number</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
<img src="./images/background.jpeg" width="100%" alt="coffee beans">
<br>
<h1>Feature Product</h1>
<br>
<!-- house blend -->
<h2>House Blend Coffee</h2>
<img src="./images/house-blend.jpeg" alt="house blend">
<p style="width:50%">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod explicabo recusandae consequuntur dolorem accusamus dolorum itaque nisi consectetur, voluptas laudantium? Necessitatibus ducimus aperiam maiores nostrum quas? Fuga omnis possimus commodi? Id vero exercitationem, delectus quas velit optio commodi animi dignissimos repudiandae minima, provident corporis in officia officiis, nostrum distinctio quam.</p>
<h3><a href="https://www.wikipedia.org/" target="_blank">Details</a></h3>
<br>
<br>
<!-- french roast -->
<h2>French Roast</h2>
<img src="./images/french-roast.jpeg" alt="french roast">
<p style="width:50%">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod explicabo recusandae consequuntur
dolorem accusamus dolorum itaque nisi consectetur, voluptas laudantium? Necessitatibus ducimus aperiam maiores nostrum
quas? Fuga omnis possimus commodi? Id vero exercitationem, delectus quas velit optio commodi animi dignissimos
repudiandae minima, provident corporis in officia officiis, nostrum distinctio quam.</p>
<h3><a href="https://www.wikipedia.org/" target="_blank">Details</a></h3>
<br>
<br>
<!-- Columbian Roast -->
<h2>Columbian Roast</h2>
<img src="./images/columbian-roast.jpeg" alt="Columbian Roast">
<p style="width:50%">Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod explicabo recusandae consequuntur
dolorem accusamus dolorum itaque nisi consectetur, voluptas laudantium? Necessitatibus ducimus aperiam maiores nostrum
quas? Fuga omnis possimus commodi? Id vero exercitationem, delectus quas velit optio commodi animi dignissimos
repudiandae minima, provident corporis in officia officiis, nostrum distinctio quam.</p>
<h3><a href="https://www.wikipedia.org/" target="_blank">Details</a></h3>
<br>
<br>
<br>
<br>
<br>
<p>copyright©2021</p>
<h3><a href="#logo">Back To Top</a></h3>
</body>
</html>
Etape “About”
Faisons maintenant la page About, qui a aussi l’image background (la toute grande) normalement on utilise du css pour définir une “background image”. Nous avons plusieurs options pour commencer cette page, soit de copier coller la page Home déjà faite à la première étage, ou soit tout réécrire d’une page blanche. Choisisson la première options.
Changeons le titre en About
La grande image reste et Feature Product est remplacé par About Us
Effacer les 3 produits
Rajoutons un paragraphe avec 500 mots avec Lorem500
Etape “Numbers”
Pour la page Numbers tout reste la même chose (entête, bas-de-page). Donc nous refaisons un copier paste, mais cette fois du contenu de la page About.
Dans le head, on mettra title à Numbers
Dans le body, on mettra en h1 Our Stores
Insérons une table et commentaire pour notre row city avec tr
th pour titre avec les 4 noms des villes et un commentaire disant que c’est la fin de la première row
faisons la même chose pour la ligne mais avec td pour data
comme ce tableau n’a pas fière allure nous lui appliquons du css.
Voici le code pour la page numbers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Numbers</title>
</head>
<body>
<img src="./images/logo.png" id="logo" alt="coffe logo">
<h3>Coffee Junkie</h3>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="numbers.html">Numbers</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
<img src="./images/background.jpeg" width="100%" alt="coffee beans">
<br>
<h1>Our Stores</h1>
<br>
<table style="border:2px solid black; border-spacing:25px">
<!-- city -->
<tr>
<th>City</th>
<th>Chicago</th>
<th>New York</th>
<th>Los Angeles</th>
</tr>
<!-- end of city -->
<!-- orders -->
<tr>
<td>Order</td>
<td>125</td>
<td>250</td>
<td>500</td>
</tr>
<!-- end of orders -->
<!-- profit -->
<tr>
<td>Profit</td>
<td>$ 10,000</td>
<td>$ 20,000</td>
<td>$ 30,000</td>
</tr>
<!-- end of profit -->
</table>
<br>
<br>
<br>
<br>
<br>
<p>copyright©2021</p>
<h3><a href="#logo">Back To Top</a></h3>
</body>
</html>
Etape “Contact”
Encore une fois nous allons copier le contenu.
Voici le code pour la page contact
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact</title>
</head>
<body>
<img src="./images/logo.png" id="logo" alt="coffe logo">
<h3>Coffee Junkie</h3>
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="about.html">About</a></li>
<li><a href="numbers.html">Numbers</a></li>
<li><a href="contact.html">Contact</a></li>
</ul>
<img src="./images/background.jpeg" width="100%" alt="coffee beans">
<br>
<h1>Contact Us</h1>
<br>
<form action="">
<!-- name -->
<label for="name">Name</label>
<input type="text" name="name" id="name">
<br>
<br>
<!-- email -->
<label for="email">Email</label>
<input type="text" name="email" id="email">
<br>
<br>
<!-- description -->
<p>Description</p>
<textarea name="description" id="" cols="30" rows="10" placeholder="Your Description"></textarea>
</form>
<br>
<br>
<br>
<br>
<br>
<p>copyright©2021</p>
<h3><a href="#logo">Back To Top</a></h3>
</body>
</html>
Et le résultat du formulaie
On constate que l’attribut action=”” reste vide car pour l’instant nous n’allons pas envoyer les données ailleurs.
css
https://github.com/amycesal/dataviz-style-guide/blob/master/Sunlight-StyleGuide-DataViz.pdf
Il y trois façon de travailler avec css :
inline css
internal css
external css
inline css
Pour le inline dans la balise on écrira l’attribut style=””
Ajoutons un autre attribut qui est font-size, ne pas oublier de séparer les attributs par un point virgule.
Le désavantage de travailler en inline est que pour chaque élément nous devrons créer un style. Si par exemple nous aurions 500 x h1 alors pour tout changer cela risque de prendre longtemps. Donc le inline styling est quelque chose de très basique.
Internal css
Pour le internal css, on va mettre entre les tags heads un tag style est décrire le style de tous nos éléments par exemple si l’on veut pour l’élément h1 une couleur blue et un font-size de 3rem et un autre style pour h2 on écrira la chose de la manière suivante:
avec cette méthode il sera facile de modifier la couleur de tous les h1 en entrant simplement la couleur désirée à un seul endroit. Ceci va marcher uniquement pour la page où est déclaré style. Admettons qu’il y a 10 pages html. Il faudrait alors dans chaque page insérer style. Au moindre changement de style, il faudra passer au travers de tous les fichiers pour modifié le style donc beaucoup de temps d’édition. Une autre solution consistera a faire un fichier avec une extension .css qui engloberait tous les styles pour toutes les pages. En en vient alors à external css.
External css
Pour ce faire il faut créer un fichier dans le projet nommé xxx.css xxx n’est pas bien important du moment où il y l’extension .css. La convention toutefois est de préciser le nom à style donc un style.css
Pour dire à nos fichiers html d’utiliser ce fichier css, on indiquera dans les fichiers entre les tags head,
Remarque: En général, le fichier styles.css doit ce mettre dans un répertoire nommé css. Nous devons donc modifié le path (ou chemin) de notre fichier.
Priorités entre external/internal/inline css
L’inline vient en première priorité, ensuite internal et l’external vient en dernière priorité.
Commentaires
Se qui vient entre /* et */ est considéré comme un commentaire.
Noms des éléments dans le css
selector c’est par exemple h1, h3
property c’est par exemple color, font-size
value c’est par exemple orange, 4rem
Exemple de fichier styles.css
Créons d’abord un fichier index.html avec h1, h2, et p sur lequel nous allons appliqué différent style avec le fichier styles.css
Le fichier styles.css
Le résultat
Comment faire si l’on veut que tout le texte soit en bleu?
Grouping Selectors
Comment dire que tout soit en rouge sauf h1 et h2 en bleu?
on utilisera le grouping selectors
Remarquer que les différents selectors sont séparés d’une virgule.
ID selectors
Permet d’appliqé différents style sur le même selector
Exemple
Comment peut-on faire si l’on veut appliqué des styles différents à h1 Title heading et à h1 Footer Heading?
On utilisera l’attribut id dans le fichier html à l’intérieur du tag et un dièse avec le nom de l’id dans le fichier styles.css
Fichier index.html
Fichier styles.css
Résultat
Class selectors
Exemple:
Nous aurions pu utiliser id selector, mais nous aurions du faire un id différents pour chaque h3 différents. L’id doit être unique.
Combinaison entre id et class selector
Remarquez quand on on écrit class=”green lowercase” c’est en fait deux class différentes séparée par un espace.
div span
Prenons un exemple un titre suivi d’un paragraphe, et un deuxième titre suivi d’un deuxième paragraph. A l’intérieur du deuxième paragraph mettons “hey i’m uppercase” à deux endroit différent.
Maintenant nous voudrions avoir le premier titre et le premier paragraphe en rouge. Le second titre et le second paragraphe en bleu.
Pour ce faire nous ne pouvons sélectionner h3 ni p car nous aurions les deux de la même couleur. Bien sûr nous pourrions utiliser id, mais il existe une meilleures solution. L’utilisation de div et de span pour grouper.
On va donc faire un premier groupe ou bloc avec div en le mettant avant le premier h3 et le deuxième tag du div à la fin du premier paragraphe.
En mettant ce div rien ne change à l’affichage. Nous allons faire de même pour notre texte que l’on veut afficher en uppercase, mais cette fois nous allons utiliser span pour grouper notre texte.
Dans notre css mettons un selector div et un span
Donc le div est utilisé pour créer un bloc et span est utilisé pour du inline. Un div créera un espace après lui, mais pas span.
Pour mettre une autre couleur à notre deuxième titre et deuxième paragraphe, nous allons utilisé nos class dans les div.
Supprimer dans le styles.css le selector div. et mettons les class appropriées dans les div du fichier index.html
Nous pouvons aussi utiliser une class pour span. Par exemple, si nous voulons mettre une class red à notre premier span
Inheritance
Tous les éléments enfants hérite du style des style appliqué aux parents. Prenons un exemple de deux paragraphes.
Mettons un selector body avec color à red.
Les deux paragraphes seront de couleur rouge. Car les paragraphes sont à l’intérieur de body et sont donc enfant de body. Body est le parent de paragraphe. Dans ce cas on dira que p à hérité des styles de body.
Maintenant mettant les deux paragraphes à l’intérieur de div
Maintenant les deux paragraphes sont blue. Pourquoi ceci est comme cela car div est l’enfant de body. C’est parce que div reçu un style spécifique, le style de body ne compte plus. Les deux paragraphes ont hérité du style de div.
Si l’on ajoute un h2 dans le div et un selector h2 dans le styles.css, alors h2 les styles appliqués sur h2 sera prioritaire. Dans ce cas h2, aura une couleur verte qui prime sur le rouge de body, mais héritera quand même le uppercase de body.
Il y a quelques proprety de parent qui ne vont pas être hérités par les enfants. Dans l’exemple suivant, div possède un proprety border on voit que cette property n’est appliquée qu’au div.
Last Rule and Specificity Universal Selector
Il arrive lorsque le fichier styles.css devienne très grand et sans faire exprès, nous déclarons un selector plusieurs fois. Le dernier déclaré dans le fichier sera pris en considération.
Admettons maintenant que nous avons pour le div une couleur verte déclacrée après avoir déclaré h2. Bien que div soit déclaré après la couleur de notre h2 reste verte. Il y a donc un spécificité dans les sectors qui prennent les propriétés avant les selectors placé après.
Pour plus d’information sur ce sujet, on peut trouver dans google en tapant “specificity measurement css”. Ou sur 3schools.com
Il existe des selectors universels comme par exemple * qui
sélectionnera tous les selectors, mais ne sera pas prioritaire sur
certain selector positionné en fin de liste.
color properties / color background-color
color property est responsable de la couleur du texte
background-color est responsable de la couleur du fond de texte
Exemple :
comme on peut le constater, l’utilisation de backround-color et background produise le même résultat.
L’utilisation la plus commune est d’utiliser les couleurs par leur nom. Visual Studio propose directement les noms existants des couleurs. Il y 140 nom de couleurs.
RGB
Il y a un autre moyen d’indiquer la couleur qui l’utilisation de rgb qui signifie red green blue, chaque couleur va de 0-255 0 étant le noir
Une valeur 255 pour r représente la couleur pour rouge, 255 pour le g représente la couleur verte, 255 pour le b représente la couleur bleu. rgba ^^^^
La lettre a est pour opacité / transparence. (de 0 à 1)
On voit que plus la valeur de a tend vers 0 est plus le fond devient transparent.
hex value
#RRGGBB
Au lieu d’avoir des valeurs variant de 0 à 255 on aura des valeurs de 0 à F (hexadecimal) après 9 vient A
Visual Studio permet de se déplacer dans la zone pour choisir notre couleur et l’opacité avec le premier ascenseur à gauche. Et de convertire entre les différents code couleurs (rgb, hex, hsl)
Choisir sa palette de couleur
Il y a un site https://coolors.co il faut appuyer sur space pour changer de couleur et sur le cadenas pour choisir la couleur.
font-size, width, height, pixels
font-size est pour ajuster la taille du texte
width et height contrôle respectivement la largeur et la hauteur d’un élément (h1, …)
pixel est une unité absolue comme le plus petit point d’un écran pourquoi absolue? c’est parce que si on modifie la fenêtre du browser la mesure sera toujours identique.
Quand est-il avec height?
Percent value / relatives
On voit que la zone rouge est 50% plus petite en largeur et en hauteur par rapport à la partie bleu qui est l’élément parent du div en rouge..
em relative
Par défaut, la taille du texte dans une fenêtre d’un browser est de 16px.
On voit que la taille des deux textes sont identiques car une fait 32px et comme 1em fait par défaut 16px donc 2x16=32px
Changeons maintenant la taille dans le browser à très grand, donc on modifie la taille par défaut de 16px à plus grand. 1em sera plus grand que 16px et apparaîtra plus grand que le texte absolute
Créons des div qui sont des parents à nos h3
et mettons div selector un font-size de10px
On voit que relative est devenu plus petit car font-size de parent est devenu plus petit que 16px. Le texte absolute n’a pas changer.
rem
Contrairement à em, rem ne dépend pas du parent, mais de root. Le root est le tag html.
Dans l’exemple précédent si l’on met à la place de em, rem,
la taille n’héritera pas du parent qui est 16px dans ce cas là (defaut du browser). Par contre, si on le mais dans le root,
la taille du texte relative changera.
vh - height / vw - width (percent of the screen)
Ce sont des unités relatives par rapport à la taille de l’écran (fenêtre).
on mettra vw pour width et vh por height.
On voit que le carré rouge fait exactement la moitié de la fenête que se soit en hauteur ou en largeur. (ne pas prendre en compte la petite marge) Ces valeurs sont souvent utiliser pour les banners. (entête)
Default browser styles and google devTools
Pour ouvrir le devTool, faire un clique droite sur le browser et choisir inspecter. Il est vrai que c’est assez intimidant au début. Pour l’instant nous allons uniquement utiliser le menu Element. On retrouve tous les éléments que notre page possède (head, metatag, body, h1…)
Que se passe-t-il lorsque l’on clique sur h1?
Nous retrouvons notre css syntaxe. (voir element.style {}). Mais nous voyons des autres informations que l’on a pas entrée. Comme par exemple dispay: block; font-size: 2em; En fait ce sont les styles que chaque browser applique par défaut.
On remarque user agent stylesheet, cet inscription signal que ce sont les styles du browser appliqués par défaut. On peut réécrire ces valeurs comme par exemple la modification des marges.
Rajoutons un h2 est mettons quelques styles
Le devTool nous indique notre fichier styles.css et en dessous qu’elle propriété ne sont plus celle par défaut (biffé) Ce que l’on peut faire aussi c’est modifié directement dans le devTool des valeurs. Le fichier d’origine ne sera pas modifié.
Calc
Permet de faire des opérations mathématiques comme addition, soustraction, multiplication, division.
On remarque que la page est plus grande que ce que l’écran peut afficher contre le bas. Le dépassement est égale à 100px (la hauteur de navbar) Pour corriger cela on corrigera la hauteur en utilisant calc
Cette méthode est souvent utilisée pour la page d’accueil quand il y a une barre de navigation est le banner en dessous. Attention de bien mettre un espace avan et après l’opération (ici le - )
font-size font-family
Permet de changer la police d’écriture pour chaque élément que l’on veut.
font-stack generic-family
Il se peut que les polices que l’on a choisie ne soient supportées par le browser. Visual Code nous propose une série de font qui se ressemble séparée d’une virgule.
Google Fonts
Google propose aussi des fonts que l’on peut incorporer.
font-weight
Si l’on veut mettre en gras.
font-style
Pour mettre en italic, oblique, normal.
text-align
On peut utiliser left qui est par défaut à gauche et right pour droite.
text-indent
Sert à indenter la première ligne d’un paragraphe.
line-height letter-spacing word-spacing text-transform text-decoration
CSS Box Model
Padding
Les paddings appliqués sur le p, sont des raccourcis.
Margin
Est la marge entre le bord de l’écran et l’élément.
Warning
Les browsers applique par défaut une marges. C’est souvent source de confusion.
Tout comme le padding, on peut utiliser les raccourcis.
Comment faire pour coller ici le carré rouge au carré bleu?
Si l’on veut mettre tous les marges à 0 on écrira :
margin:0;
On retrouvera les mêmes raccourcis que padding. C’est-à-dire margin: 20px (1 valeur) appliquera 20px sur les quatre côtés. Avec 2 valeurs alors la première valeur représentera le top et le bottom la deuxième et pour la marge de droite et de gauche. On peut spécifier avec 4 valeurs qui sont respectivement pour le top, droite, bas, et gauche.
Border
Pour encadrer les éléments.
Il y a aussi des raccourcis pour borer. L’ordre des valeurs est pas importante.
On peut aussi choisir qu’un seul coté avec par exemple, border-bottom pour le coté du bas.
Arrondir et margin négatif
Pour un placement qui doivent se chevaucher, utiliser un margin négatif. Les coins peuvent aussi être arrondi grâce à la commande border-radius.
outline
est utilisé pour déplacer le cadre vers l’extérieur ou vers l’intérieur à l’aide de outline-offset suivant qu’il est positif ou négatif.
Display
Block crée toujours une ligne d’espacement
Inline ne crée pas de ligne d’espacement et sa taille s’ajuste au contenu.
On remarque que block s’étend sur toute la largeur de la page.
Certains éléments possèdent leur propre display property.
Avec la propriété display on peut changer le display qui est réglé par défaut.
Horizontal Centering
Pour aligner les blocks en bleu, nous devons écrire cela comme ceci
L’utilisation de margin est nécessaire ici 25px est la marges du haut et du bas tandis ce que auto est la marge automatique qui centre le block.
Top Bottom Margin
Block: Top Bottom Margin Respected
Inline: Top Bottom Margin Not Respected
Inline-Block
faisons le fichier css
on voit que margin n’a fonctionner que pour la droite et la gauche le top et le bottom n’a pas bougé. C’est parce qu’on est en inline. On peut essayer de mettre le display à block et voir si on peut régler le top et bottom.
Mais cela n’arrange pas les choses. On n’aimerait avoir tout sur une ligne et pouvoir réglé margin top et bottom.
En utilisant inline-block margin top et bottom fonctionne.
box-sizing
Ajoutons un padding à la box-1
On remarque que la box-1 a c’est agrandie de 20px de chaque coté. Mettons aussin un padding à box-3
Ouvrons le devTool de chrome et inspectons box-1, on voit que la dimensions est passée à 240px par 240px.
Le padding est souvent source de confusion car il augmente la taille des éléments.
C’est là qu’intervient le box-sizing: border-box
Si l’on inspecte à nouveau le devTool
on voit que l’intérieur est passé à 160x160px donc il n’a pas agrandi le div, mais à déplacé le texte de 20px de chaque coté vers l’intérieur du div.
Background images
Pour ce faire piquons sur pexels trois images que l’on va renommer par big.jpg small.jpg et folder-img.jpg. Redimensionnons big.jpg et folder-img.jpg à 400px de haut, small.jpg à 100x100px avec Gimp.
Disons que le div n’a pas de limite de largeur, mais une hauteur limitée à 400px. et mettons une couleur rouge pour le texte.
Pour le placement de l’image nous allons utiliser background: mais cette fois ci pas comme nous avons l’habitude de mettre color, à la place nous allons mettre un url().
path image
pour le path de l’image, uniquement cette notation fonctionne pour moi
pour voir directement dans le chrome en ouvrant index.html (sans live
server) :
url("../big.jpg"). Si le l’image est dans un dossier nommé img
url("../img/big.jpg")
On voit que lorsque l’on agrandi la fenêtre, si elle devient plus large que l’image alors le browser dupliquera l’image à droite.
Le browser par défaut a remplir tout le div par les images en les dupliquant non seulement en largeur mais aussi en hauteur.
Background-repeat
backround-repeat: repeat;rien ne change car c’est la valeur pardéfaut.
backround-repeat: no-repeat;
background-repeat: repeat-x ou repeat-y
Pour répéter l’image en largeur seulement. Mettre repeat-y pour
répéter l’image en hauteur.
background-repeat: space
On distingue de l’espace entre les images répétées.
background-repeat: round permet affichera toujours une image dans
toute sa largeur. Attention, elle sera déformée.
Pour ce qui est le plus couramment utilisé c’est le
background-repeat: no-repeat
Background-size: cover
Etend l’image sur toute la largeur du div quelque que soit la taille de l’image. L’image ne sera pas déformée. Il faudra faire attention à bien dimensionné l’image avant pour que l’image ne soit pas trop pixelisée en étendant le div.
Background-size: contain
Ne modifie pas le ratio de l’image.
Note
De tous ces background, celui qui sera le plus utilisé sera le cover pour faire des nices banners.
Background-position
La petite image est centrée.
Note
Ecrire right bottom est tout à fait possible.
Utile si l’on veut voir plûtot le bas, le haut le centre, ou droite ou gauche de l’image quand on agrandi l’image. Ici on se penche plutôt pour le bas.
Pour un positionnement encore plus précis on écrire en %.
Le premier % représente l’horizontal, et le deuxième, la verticale.
Background-attachment
Ajustons d’abord le div:
La hauteur de l’image est égale à la fenêtre.
et mettons le texte au centre et enlevons le margin par défaut avec
*{}
Apportons encore quelques modifications
Cette configuration peut-être utilisée pour les images d’arrière-plan d’un site internet.
Mettons maintenant un background-attachement
Qui a fixé l’image, pendant que l’on scroll vers le bas, le texte sur le dessus de l’image bouge.
Gradients
Sur une image
Pour l’instant, on remarque qu’il n’y a pas de dégradé, changeons le paramètre a = 0.1
On distingue maintenant le gradué :
Associons une image. Attention de ne pas oublier la virgule.
On voit que l’image s’est assombrie, on peut très bien prendre une autre couleur aussi.
Utilisation de raccourci pour background
Note
Attention, no-repeat et fixed ne peuvent être permuter.
Cela évite de tapez background… sur plusieurs lignes. L’image à la même propriété que la première sauf qu’il y a plus de dégradé. (idéal pour lire du texte sur l’image)
Linear gradient generator
Il existe un site https://www.colorzilla.com/gradient-editor/ qui permet de générer les dégradés. Ensuite il faut copier le code css.
Float property
On voit que le paragraphe est mis en-dessous de l’image car c’est un last block element.
Mettons maintenant un border et un padding
Que se passe-t-il maintenant si l’on utilise la propriété float?
On est tenté de dire que l’image est déjà floated vers la gauche. Mais par défaut la propriété est à none. Mettons float à left.
Si l’on met un left alors l’élément suivant va ête aussi à left, comme dans ce cas. Si l’on veut mettre l’élément suivant comme normal, il faudra utiliser la propriété clear: left.
Faisons la même chose avec right:
Rajoutons une deuxième image
En utilisant clear: both, le paragraphe revient à la ligne normal. C’est comme si on lui aurait enlevé la propriété left ou right.
L’image sort du div, en utilisant la commande overflow: hidden, on coupe la partie qui dépasse.
Enlevons une image et mettons l’image à droite du paragraphe.
On peut facilement mettre un peu de marge
Un autre exemple avec float
Si l’on rajoute un h1
On croirait que tout va bien le h1 c’est bien mis sur une nouvelle ligne.
Mais rajoutons un div
On voit que le hello world ne sait pas mis sur une nouvelle ligne.
Pour mettre le h1 comme il devrait s’afficher (sur une nouvelle ligne) on fera appel à clear:both.
c’est une bonne habitude de mettre ce clear:both pour des raisons de déboggage qui pourraient s’avérer pénible.
position: relative
avec position: relative, 4 options permettent de déplacer l’élément soient, top, bottom, left, right. Ils déplacent l’élément par rapport au flux normal (position normale par défaut)
position: absolute
C’est la rock-star du css.
Si l’élément d’avant est positionné avec relativ alors cet élément sera la référence pour l’élément positionné avec absolute. Pour voir mettons l’élément d’avant ici .two avec relative.
Enlevons-là pour voir
On voit que la référence est devenu le body.
Mettons la position du div à relative
Pour le mettre à la moitié du body, on enlève le relative de .div
position: fixed
Cet propriété sert à fixer un bouton par exemple pour qu’il soit fixe lorsque l’on scroll en-bas de la page.
Media Queries
Est utilisé pour appliquer différents styles suivant la grandeur de l’écran. En général on commence par l’écran le plus petit vers le plus grand.
Attention au un simple oubli d’un espace est la syntaxe est fausse.
min-width
la syntaxe min-width indique à partir de quelle grandeur le style doit être appliqué.
On peut utiliser le devTool pour inspecter la grandeur de l’écran.
Si nous n’écrasons pas dans @media un style déjà défini, comme par exemple text-decoration: underline, ce style sera maintenu.
Dans l’exemple suivant, on va mettre deux seuils pour avoir en fait trois styles différents.
On observe que dès que la fenêtre dépasse 768px alors le style vert est appliqué.
max-width
max-width indique que jusqu’à max-width le style est appliqué. Au-delà un autre style est appliqué.
Ce que l’on doit faire attention c’est que l’on peut écraser facilement les styles. Ici 768px écrase le 576px car il inclu ce dernier. Donc le style rouge (576px) ne sera jamais utilisé. Par contre si un style declaré dans 576px et ne figure pas dans 768px alors celui-ci sera tout de même appliqué.
z-index
Avec z-index, on peut règler l’ordre de juxtaposition des images.
Nous voulons comme ancêtre pour banner position: relative.
On distingue que les images sont superposées. Dans l’ordre dans lequelle elle ont été déclarées.
Par défaut, les images ont un z-index égale 0.
Si l’on met pour la première image un z-index égale à 0 l’image reste comme elle était.
Mettons z-index à 1 et l’image passe devant les autres.
Passons des z-index au trois, afin que la troisième image passe en arrière, ensuite la deuxième et la première en avant.
on peut très bien mette un z-index de -999 c’est la grandeur qui fait la priorité.
z-index fonctionne seulement en absolute et en relative. Si l’on met static alors z-index ne fonctionnera pas.
Dans ce cas tout fonctionne normalement. Si l’on met un z-index à 100, alors rien ne se passe avec position static. (le .one devrait passer tout en avant)
Pour que cela fonctionne il faut mettre à relative ou aboslute
pseudo elements ::before ::after CONTENT
::before
Pour l’exemple suivant nous allons créer un simple paragraphe.
On voit que le mot hello s’est collé devant le contenu de notre paragraphe écrit en html.
On peut rajouter n’importe quelle propriété
Si l’on ouvre le devTool on peut voir que le ::before a été rajouter dans le p
::after
Ceci est rajouter inline.
On peut changer en block
Donc nous avons nos sudo éléments avant et après le paragraphe.
content doit toujours être renseigné
on doit donc quand même spécifié content:”” quand il n’y pas de texte.
Cas pratique avec ::before et ::after
Nous allons rajouter une image et ce qui est important c’est que img soit dans un div.
Changeons la largeur de l’image
ok, cela fonctionne, mais il y a une meilleure solution.
Nous allons modifier le div et l’image sera responsible à ce div.
On remarque que l’image ne s’intégre pas dans le div (cadre rouge)
Pour la faire entrer dans le cadre mettons width: 100%
Même en modifiant le div l’image sera toujours intégrée au div
On remarque toutefois un espace enter le bas de l’image et le cadre du bas. On est tenté à mettre un height: 100% mais rien a bougé. Pour parer à cet inconvénient, il faut mettre à img un display: block. Ceci n’a rien à voir avec ::before ::after sudo elements, mais l’association en div et img requiert img avec un display: block.
Maintenant mettant quelque chose avec ::before avant l’image.
On remarque que hello ne s’est pas mis avant l’image, ceci est dû au fait que img représente déjà le contnent.
Donc essayons avec div, on met content à “” avec un border
On voit un petit rectangle gris, essayons maintenant de l’agrandir:
On voit qu’il a pas bougé.
Mais nous connaissons la propriété absolute.
On voit que le cadre n’est pas encore bon.
On se rappelle que absolut regarde pour quoi? Il regarde pour l’ancestor ou il y a un relative. S’il ne trouve rien il prendrea le body. C’est pourquoi le cadre est si grand. Donc on regarde pour l’ancestor et dans ce cas c’est div et rajoute un positon relative.
On peut dire que ce n’est pas vraiment 100% car il réside de l’espace (un tout petit peu). La raison à cela est dans le border-box. Mettons alors box-sizing: border-box. et le résultat est bon.
Ce qui est cool c’est qu’on peut utilisé relatvie avec l’ancestor. On peut utilisée des valeurs négatives. Ce qui va faire déplacer le cadre.
Pour faire passer le cadre en arrière plan on utilisera z-index: -2 Occupons nous de div::after, copions ce qu’il y a dans le before et passons le entre div::before et l’image.
transition
Voici un petit avant goût de ce que l’on peut faire avec hover et transition
Dès que l’on le pointeur de la souris passe par-dessus l’image alors after et before vont se décaller à 0;
Basic Selectors
Mettons quelques style à #heading
On voit qu’il y spécificité car #heading supplante le *. On se
rappelle que lorsque l’on utilise id alors dans le css il faudra
mettre #, pour class on mettra un point. Mettons maintenant à class du
style.
On va donc que grâce à la spécificité on peut régler les styles de chaque élément spécifique.
Descendant and Child Combinators
Children peuvent être Descendant, mais Descendant ne peut pas être Child. Prenons un example pour clarifier.
Si l’on veut sélectionner uniquement les h1 qui sont dans un div on écrira
Donc ici les deux h1 seront en rouge.
direct child
On peut sélectionner le direct child par exemple div > h1 sera sélectionner uniquement si h1 est directement sous div (qu’il n’y a rien entre le div et le h1) C’est pourquoi uniqument le premier h1 est sélectionner car l’autre h1 est sous li ul.
On n’est pas limité uniquemnt aux selectors, class fonctionnent aussi.
.header est plus spécifique car c’est une class
fonctionne aussi avec direct child
first-line ::first-letter
hover
On voit que quand on passe dessus avec le pointeur de la souris que le texte s’agrandit. Mettons un hover sur .header et sur a.
link :visited :hover :active
visited
On voit que si a égale à #, alors tous les visited passent à EN
(au rouge dans ce cas). Mais dès que l’on met un lien vers une page,
le lien devient pas visité.
hover
active
lorsque l’on clique sur le lien et sans relâcher le bouton de la souris, alors le lien devient vert.
root element of the document
root est utilisé par exemple pour agrandir le texte dont la taille a été fixée par rem. On remarque que par absolute le texte ne change pas malgré le changment de root à 150%. En fait par défaut 1rem = 16px.
transform
translate
un valeur négative fera déplacer l’élément vers la gauche et un pourcentage fera déplacer d’un pourcentage de la taille de l’élément à déplacé. Une valeur négative fera monter l’élément. On peut aussi combiner les deux directions.
scale
rotation
rotateX
rotationZ fait une rotation autours de l’axe Z et est égale à rotation tout courts.
skew
transition
Une transition est un changement effectué pendant un certain temps.
ce hover va faire changer la couleur de tous les div en faisant passer le pointeur de la souris sur les div.
On remarque que le changement de couleur est instantané, si l’on veut que ce changement s’opère pendant un certain temps on écrira
les 4s sont le temps que mettra la couleur du fond à virer du bleu au coloral.
Mettons une autre propriété de border-radius et l’on observe dès que l’on passe dessus le rayon passe directement à un rond. Pour que l’effet de border-radius se fasse aussi progressivement on séparera la propriété d’une virgule.
l’effet est effectué sur les deux propriétés avec un délai de 4s. Par contre si l’on veut un délai différent alors on écrira
Là, 4s est pour background et 2s est pour border-radius.
transition-delay
est pour mettre un délai comme pour un relai temporisé à la fermeture.
On peut noter d’autre manière
ici le 3s seconde représente la durée de la transition et 2s la tempo.
Si l’on veut appliquer à border-radius aussi
si l’on veut appliquer à toutes les propriétés
transition-timing-function
ease et default sont les mêmes
linear la vitesse de déplacement et la même du début à la fin.
ease-in accèlère progressive
ease-out plein pot au début et ralentissement progressive
ease-in-out accélération et déssélération progressive.
Animation
On a vu transition qui fait l’action de 0 à 100%, avec animation on peut faire varier à n’importe quel pourcentage.
iteration est le nombre de fois que l’animation doit se dérouler.
short hand
On peut écrire tout sur une ligne ceci remplace ce qui est commenté.
animation-fill-mode
Une fois que le nombre d’itération a été effectué, la modification reste à la dernière ici opacity sera à 0.5.
:root{}
définition de variable global
utile si il y beaucoup de variable qui se répètent comme par exemple color.
En local
Créons une nouvelle variable à l’intérieur de div et appelons-la dans .main-text et essayons aussi de l’appeler dans .third-heading. Comme .third-heading n’est pas dans un div alors la color ne sera pas réglée à rouge. Par-contre .main-text est dans un div et la coleur est au rouge.
Font Awesome
Tapez dans google font awesome.
à dévelloper car pas le droit de télécharger. Essayer un autre jour…
text-shadow
text-shadow generator
tapez dans google text-shadow generator.
Ensuite, il faut copier le code.
box-shadow
box-shadow generator
Il y a aussi un box-shadow generator
tapez dans google box-shadow generator
semantic
sert à structurer correctement une page html.
dans google tapez semantic w3school
emmet
si on utilise pas visual studio on peut tapez dans google emmet.
h1.maclass.big.yellow donnera
h1#main
h3#third.third
header.header.main
#box.box-1.box-2
div>ul>li*5
p{some texte}
ul>li*6{$}
JAVA Script
Get the most recent file in a directory node (à tester)
function getNewestFile(dir, regexp) {
var fs = require("fs"),
path = require('path'),
newest = null,
files = fs.readdirSync(dir),
one_matched = 0,
i
for (i = 0; i < files.length; i++) {
if (regexp.test(files[i]) == false)
continue
else if (one_matched == 0) {
newest = files[i];
one_matched = 1;
continue
}
f1_time = fs.statSync(path.join(dir, files[i])).mtime.getTime()
f2_time = fs.statSync(path.join(dir, newest)).mtime.getTime()
if (f1_time > f2_time)
newest[i] = files[i]
}
if (newest != null)
return (path.join(dir, newest))
return null
}
Coté client
Pour développer un script, il faut utiliser Visual Studio et installer l’extension Live Server. Ensuite ouvrir le répertoire et clique droite sur le fichier index.html qui contient le script et open with live server.
Pour que la page se rafraichisse automatiquement dans le browser, il faut mettre dans Visual Studio Code un délais à 600ms à Autosave.
Sever Side
How to install node.js
Without amin rights :
install that so it doesn’t need to restart the sever always:
npm install -g nodemon
Then enter :
nodemon index.js
Classes
Nous retournera 4.
On peut réassigner des nouvelles valeurs :
Ici le résultat sera de 3.
On peut aussi déclarer des fonctions dans nos class :
qui retounera : Loud Noise et 3
On peut passer une variable d’entrée Meow :
Le résultat : Meow et 3
On peut aussi créer des static function :
On peut alors accéder à la fonction sans passer par une variable (let)
La fonction get permet de traiter notre objet comme une propriété.
voici le résultat :
Admettons maintenant que nous voulions appliqué notre class à d’autre animaux comme chien, souris et que ces animaux hérite la même classe.
Ici Animal est la classe parent et Cat la classe enfant Cat aura hérité toutes les propriétés de Animal et on aura mis une autre valeur par défault à sound (meow).
Importons la class Cat
et appelons cat.makeNoise()
Voici le résultat :
Faisons un cat.metaData:
Résultat :
Loading Data Using Fetch
source : https://www.youtube.com/watch?v=2LhoCfjm8R4&t=15506s
index.html
<!DOCTYPE html>
<html>
<head>
<title>Loading and Parsing CSV Data</title>
</head>
<body>
<script>
const fetchText = async (url) => {
const response = await fetch(url);
return await response.text();
};
const csvUrl = 'https://gist.githubusercontent.com/windwaver/1d5d788cd934c4369210a7192ff581e4/raw/cssNamedColors.csv'
fetchText(csvUrl).then(text => {
console.log(text);
});
</script>
</body>
</html>
Parsing CSV Data with D3
<!DOCTYPE html>
<html>
<head>
<title>Loading and Parsing CSV Data</title>
<script src="https://unpkg.com/d3@6.6.0/dist/d3.min.js"></script>
<style>
pre {
font-size: 7em;
}</style>
</head>
<body>
<pre id="message-container"></pre>
<script>
const fetchText = async (url) => {
const response = await fetch(url);
return await response.text();
};
const csvUrl = 'https://gist.githubusercontent.com/windwaver/1d5d788cd934c4369210a7192ff581e4/raw/cssNamedColors.csv'
fetchText(csvUrl).then(text => {
const data = d3.csvParse(text)
let message = '';
message = message + Math.round(text.length / 1024) + ' kB\n';
message = message + data.length + ' rows\n';
message = message + data.columns.length + ' columns';
document.getElementById('message-container').textContent =message;
});
</script>
</body>
</html>
simplier
<!DOCTYPE html>
<html>
<head>
<title>Loading and Parsing CSV Data</title>
<script src="https://unpkg.com/d3@6.6.0/dist/d3.min.js"></script>
<style>
pre {
font-size: 7em;
}</style>
</head>
<body>
<pre id="message-container"></pre>
<script>
const csvUrl = 'https://gist.githubusercontent.com/windwaver/1d5d788cd934c4369210a7192ff581e4/raw/cssNamedColors.csv'
d3.csv(csvUrl).then(data => {
let message = '';
message = message + Math.round(text.length / 1024) + ' kB\n';
message = message + data.length + ' rows\n';
message = message + data.columns.length + ' columns';
document.getElementById('message-container').textContent =message;
});
// With fetch, async, and await.
// const fetchText = async (url) => {
// const response = await fetch(url);
// return await response.text();
// };
// fetchText(csvUrl).then(text => {
// const data = d3.csvParse(text)
// let message = '';
// message = message + Math.round(text.length / 1024) + ' kB\n';
// message = message + data.length + ' rows\n';
// message = message + data.columns.length + ' columns';
// document.getElementById('message-container').textContent =message;
});
</script>
</body>
</html>
Loading Data with React and D3
index.html
<!DOCTYPE html>
<html>
<head>
<title>Loading Data with React & D3</title>
<style>
body {
margin: 0;
overflow: hidden;
}
pre {
font-size: 7em;
}
</style>
<script src="https://unpkg.com/react@16.9.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.9.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/d3@5.11.0/dist/d3.min.js"></script>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
index.js
import React, { useState, useCallback, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { csv } from 'd3';
import { message } from './message'
const csvUrl = 'https://gist.githubusercontent.com/windwaver/1d5d788cd934c4369210a7192ff581e4/raw/cssNamedColors.csv'
const App = () => {
const [data, setData] = useState(null);
useEffect(() => {
csv(csvUrl).then(setData);
},[]);
return <pre>{data ? message(data) : 'Loading...'}</pre>;
};
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
message.js
export const message = data => {
let message = '';
message = message + Math.round(d3.csvFormat(data).length / 1024) + ' kB\n';
message = message + data.length + ' rows\n';
message = message + data.columns.length + ' columns';
return message;
};
React
L’installation a réussi dans le répertoire xxxxx_y, dans le répertoire formation cela échoue. Déplacer le répertoir où l’on veut après.
Pour compiler tapez :
npm start
Pour nettoyer après installation rapide voir cette video :
https://www.youtube.com/watch?v=dMH1_YtUTSQ
Deploy react on c-panel
follow this blog : https://dev.to/crishanks/deploy-host-your-react-app-with-cpanel-in-under-5-minutes-4mf6
Fichiers de base
Il faut au minimum un fichier index.html et index.js.
Contenu du fichier index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Contenu du fichier index.js :
import React from "react"
import ReactDOM from "react-dom"
ReactDOM.render(<h1>Hello World</h1>, document.getElementById("root"))
on remarque la ligne
React from "react"
qui est là pour activer JSX, une combinaison entre html et js.
<h1>Hello world!</h1>
est écrit en JSX.
Si l’on veut mettre plusieurs balise html comme
<h1>Hello world!</h1><p>Ceci est un paragraphe</p>
nous devrons les inclure dans un un div
<div><h1>Hello world!</h1><p>Ceci est un paragraphe</p></div>
Ce tutoriel est basé sur la video suivante:
https://www.youtube.com/watch?v=DLX62G4lc44&t=16575s
Il y aussi un site de l’enseignant ici :
ReactDOM & JSX
https://www.youtube.com/watch?v=DLX62G4lc44&t=565s
Objective: Fill in the boilerplate React code required to render an unordered list (<ul>) to the page. The list should contain 3 list items (<li>) with anything in them you want.
HINTS: import the libraries you need first use one of the libraries to render some JSX to the page
https://www.youtube.com/watch?v=DLX62G4lc44&t=1472s
import React from "react"
import ReactDOM from "react-dom"
ReactDOM.render(
<ul>
<li>1er élément</li>
<li>2ème élément</li>
<li>3ème élément</li>
</ul>,
document.getElementById("root"))
Functional Components Practice
https://www.youtube.com/watch?v=DLX62G4lc44&t=1234s
Objectives:
Set up the basic React code from scratch
Create a functional component called MyInfo that returns the following UI:
An h1 with your name
A paragraph with a little blurb about yourself
An ordered or unordered list of the top 3 vacaton spots you’d like to visite
Render an instance of that functional component to the browser Extra challenge: learn on your own (Google) how you can add some style to your page. (We will also cover this in an upcoming lesson).
https://www.youtube.com/watch?v=DLX62G4lc44&t=1472s
import React from "react"
import ReactDOM from "react-dom"
function MyInfo() {
return (
<div>
<h1>Zebulus André</h1>
<p>I'm trying to learn React</p>
<ol>
<li>Hawaii</li>
<li>New York</li>
<li>Seoul</li>
</ol>
</div>
)
}
ReactDOM.render(<MyInfo />, document.getElementById("root"))
Move Components into Seperate Files
Il serait bien de mettre les composants dans un répertoire nommé components.
Un fichier portant le même nom que le composant doit être créé. Il devra comporter import et export
import React from "react"
function MyInfo() {
return (
<div>
<h1>Zebulus André</h1>
<p>I'm trying to learn React</p>
<ol>
<li>Hawaii</li>
<li>New York</li>
<li>Seoul</li>
</ol>
</div>
)
}
export default MyInfo
Le fichier index devra importer ce fichier dans le répertoire où il se trouve. Noter bien le Nom du composant est précédé par < suivi d’un espace />.
import React from "react"
import ReactDOM from "react-dom"
import MyInfo from "./components/MyInfo"
ReactDOM.render(<MyInfo />, document.getElementById("root"))
Parent/Child Components
https://www.youtube.com/watch?v=DLX62G4lc44&t=2107s
Voici une structure dont une page internet se définirait :
Set up the React app from scratch Render an App component (defined in a separate file) Inside App, render:
A Navbar component
A MainContent component
A Footer component
https://www.youtube.com/watch?v=DLX62G4lc44&t=2594s
Voici arborescence des fichiers :
Le fichier index.js :
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />,document.getElementById("root"))
Le composant App :
import React from "react"
import Header from "./components/Header"
import MainContent from "./components/MainContent"
import Footer from "./components/Footer"
function App() {
return (
<div>
<Header />
<MainContent />
<Footer />
</div>
)
}
export default App
Le composant Header :
import React from "react"
function Header() {
return (
<header>
<nav>This is a awsome navbar</nav>
</header>
)
}
export default Header
Le composant MainContent :
import React from "react"
function MainContent() {
return(
<main>
<p>This is a paragraph</p>
This is the main content.
<ul>
<li>oeléwfoé</li>
<li>eriémcvjl</li>
<li>ewrojdflfsd</li>
<li>pook,mnk</li>
</ul>
</main>
)
}
export default MainContent
Le composant Footer :
import React from "react"
function Footer() {
return (
<footer>
this is an awsome footer. Pieds de page.
</footer>
)
}
export default Footer
Voici le résultat:
Todo App - Phase 1
From scratch, initialize the React app
Render an <App /> component
Create the <App /> component from scratch
Have the <App /> component render 3 or 4 checkboxes with paragraphs or spans next to it like you are making a todo list with some hard-coded items on it
Le fichier index.js :
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />, document.getElementById("root"))
Le component App.js :
import React from "react"
function App() {
return (
<div>
<input type="checkbox" />
<p>This is the first text of the checkbox 1</p>
<input type="checkbox" />
<p>This is the second text of the checkbox 2</p>
<input type="checkbox" />
<p>This is the third text of the checkbox 3</p>
<input type="checkbox" />
<p>This is the forth text of the checkbox 4</p>
</div>
)
}
export default App
Le résultat :
Styling React with CSS Classes
On placera le fichier style.css à l’endroit suivant :
Le fichier style.css :
body {
margin: 0;
}
.navbar {
height: 100px;
background-color: #333;
color: whitesmoke;
margin-bottom: 15px;
text-align: center;
font-size: 30px;
display: flex;
justify-content: center;
align-items: center;
}
En JSX on doit utiliser className=”…”
Le fichier Header.js :
import React from "react"
function Header() {
return (
<header className="navbar">
<nav>This is a awsome navbar</nav>
</header>
)
}
export default Header
Le résultat :
JSX to JavaScript and Back
Le code suivant n’affichera pas les variables firstName et lastName.
import React from "react"
import ReactDOM from "react-dom"
function App() {
const firstName = "Bob"
const lastName = "Ziroll"
return (
<h1>Hello firstName + " " + lastName !</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
Si l’on veut qu’à l’intérieur de JSX, du Java Script soit interprété, il faudra faire l’usage d’accolades {}
import React from "react"
import ReactDOM from "react-dom"
function App() {
const firstName = "Bob"
const lastName = "Ziroll"
return (
<h1>Hello {firstName + " " + lastName}!</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
En ES6 cela donnera:
import React from "react"
import ReactDOM from "react-dom"
function App() {
const firstName = "Bob"
const lastName = "Ziroll"
return (
<h1>Hello {`${firstName} ${lastName}`}!</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
Un autre exemple:
import React from "react"
import ReactDOM from "react-dom"
function App() {
const firstName = "Bob"
const lastName = "Ziroll"
const date = new Date()
const hours = date.getHours()
const minutes = date.getMinutes()
let timeOfDay
if (hours >= 0 && hours <= 5)
timeOfDay = "night"
else if (hours>5 && hours<12)
timeOfDay="morning"
else if (hours > 12 && hours <= 17)
timeOfDay = "afternoon"
else
timeOfDay ="evening"
return (
<h1>Good {timeOfDay} {`${firstName} ${lastName}`} it's {hours}:{minutes}!</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
Ce qui donnera:
Inline Styles with the Style Property
Si l’on veut mettre du style sur un h1 par exemple on mettra deux accolades un pour dire que l’on est dans du java script et l’autre pour dire que c’est un objet. Tous les noms qui ont un trait d’union devront être modifiés : enlever les traits d’union et mettre une lettre majuscule sur le nom qui venait après le trait d’union. Exemples background-color devient : backgroundColor. Si la propriété n’a que des chiffres on peut enlever les guillemets. Exemple : fontSize: 20 mais si on veut spécifier l’unité on remettra les guillements : fontSize: “20px”
<h1 style={{color:"#FF8C00"},{backgroundColor:}}> ... </h1>
Si beaucoup de style est appliqué, alors il peut être bien de noter cela comme suit :
const styles = {
color: "#FF8C00",
backgroundColor: "#FF2D00",
fontSize: 20
}
return(
<h1 style={styles}> ... </h1>
...
)
L’inline Styles peut être intéressant lorsque l’on veut quelque chose de dynamique. Prenons l’exemple fait plus haut.
import React from "react"
import ReactDOM from "react-dom"
function App() {
const firstName = "Bob"
const lastName = "Ziroll"
const date = new Date()
const hours = date.getHours()
const minutes = date.getMinutes()
let timeOfDay
const styles = {
fontSize: 50
}
if (hours >= 0 && hours <= 5){
timeOfDay = "night"
styles.color = "#04756F"
}
else if (hours>5 && hours<12){
timeOfDay="morning"
styles.color = "#8914A3"
}
else if (hours > 12 && hours <= 17){
timeOfDay = "afternoon"
styles.color = "#D90000"
}
else {
timeOfDay ="evening"
styles.color = "#6A0FDE"
}
return (
<h1 style = {styles}>Good {timeOfDay} {`${firstName} ${lastName}`} it's {hours}:{minutes}!</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
En testant à différentes heures
const date = new Date(2020,12,16,1,13)
const date = new Date(2020,12,16,7,28)
const date = new Date(2020,12,16,14,47)
const date = new Date(2020,12,16,21,16)
Todo App - Phase 2
Time to have fun styling! But first things first:
Change the input/p combo below to be a new component called <TodoItem />. <TodoItem /> (for now) will just have the same displayed data below (every todo item is the same) hardcoded inside of it. (We’ll learn soon how to make the TodoItem more flexible)
Style up the page however you want! You’re welcome to use regular CSS (in the CSS file) or inline styles, or both!
Le component TodoItem :
import React from "react"
function TodoItem() {
return (
<div className="todo-item">
<input type="checkbox" />
<p>This is the first text of the checkbox 1</p>
</div>
)
}
export default TodoItem
Le component App :
import React from "react"
import TodoItem from "./TodoItem"
function App() {
return (
<div className="todo-list">
<TodoItem />
<TodoItem />
<TodoItem />
<TodoItem />
</div>
)
}
export default App
Le fichier index.js :
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />,document.getElementById("root"))
Le fichier style.css :
body {
background-color: whitesmoke;
}
.todo-list {
background-color: white;
margin: auto;
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid #efefef;
box-shadow:
0 1px 1px rgba(0, 0, 0, 0.15),
0 10px 0 -5px #eee,
0 10px 1px -4px rgba(0, 0, 0, 0.15),
0 20px 0 -10px #eee,
0 20px 1px -9px rgba(0, 0, 0, 0.15);
padding: 30px;
}
.todo-item {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 30px 20px 0;
width: 70%;
border-bottom: 1px solid #cecece;
font-family: Roboto, sans-serif;
font-weight: 100;
font-size: 15px;
color: #333333;
}
input[type=checkbox] {
margin-right: 10px;
font-size: 30px;
}
input[type=checkbox]:focus {
outline: 0;
}
Le résultat :
On remarque que l’on a utiliser deux className qui ont été placé dans la balise <div>.
Props in React
Prenons un exemple d’une page qui a des parties similaires ici nous avons des cartes de visite de chat (voir figure ci-dessous), comportant chaqu’une une image un nom, un numéro de téléphone et un email. Nous pouvons apparenté ces cartes de visite à des components avec bien sur des données différentes comme les images, noms etc… Vient ici la notion de Props qui sont en fait les différentes données que l’on souhaite afficher dans la carte de visite.
En codant les données “en dur” nous aurons pour le fichier App.js :
import React from "react"
function App() {
return (
<div>
<div>
<img src="http://placekitten.com/300/200" />
<h3>Mr. Whiskerson</h3>
<p>Phone: (212) 555-1234</p>
<p>Email: mr.whiskaz@catnap.meow</p>
</div>
<div>
<img src="http://placekitten.com/400/200" />
<h3>Fluffykins</h3>
<p>Phone: (212) 555-2345</p>
<p>Email: fluff@me.com</p>
</div>
<div>
<img src="http://placekitten.com/400/300" />
<h3>Destroyer</h3>
<p>Phone: (212) 555-3456</p>
<p>Email: ofworlds@yahoo.com</p>
</div>
<div>
<img src="http://placekitten.com/200/100" />
<h3>Felix</h3>
<p>Phone: (212) 555-4567</p>
<p>Email: thecat@hotmail.com</p>
</div>
</div>
)
}
export default App
On aura très vite compris que s’il y avait un grand nombre de carte le fichier App.js deviendrait très grand.
En créant un component ContactCard nous pourrions simplement appeler ce component dans App.js autant de fois qu’il y a de carte de visite.
Voici le component ContactCard (dans fichier nommé ContactCard.js) :
import React from "react"
function ContactCard() {
return(
<div className="contact-card">
<img src="http://placekitten.com/300/200"/>
<h3>Mr. Whiskerson</h3>
<p>Phone: (212) 555-1234</p>
<p>Email: mr.whiskaz@catnap.meow</p>
</div>
)
}
export default ContactCard
et voici le component App (fichier App.js) :
import React from "react"
import ContactCard from "./ContactCard"
function App() {
return (
<div className="contacts">
<ContactCard />
<ContactCard />
<ContactCard />
<ContactCard />
</div>
)
}
export default App
On remarque sur la figure suivante que les données des cartes de visites sont toutes identiques. C’est là qu’il nous faut intégrer Props dans nos components.
A l’instar des functions recevant des variables d’entrée, les component recevront les données en entrée.
Pour passer les données au component ContactCard, on procédera de la manière suivante :
Remarque: on peut mettre les données toutes sur une ligne séparée d’un espace mais il est préférable de les indenter.
import React from "react"
import ContactCard from "./ContactCard"
function App() {
return (
<div className="contacts">
<ContactCard
name="Mr. Whiskerson"
imgURL="http://placekitten.com/300/200"
phone="(212) 555-1234"
email="mr.whiskaz@catnap.meow"
/>
<ContactCard
name="Fluffykins"
imgURL="http://placekitten.com/400/200"
phone="(212) 555-2345"
email="fluff@me.com"
/>
<ContactCard
name="Destroyer"
imgURL="http://placekitten.com/400/300"
phone="(212) 555-3456"
email="ofworlds@yahoo.com"
/>
<ContactCard
name="Felix"
imgURL="http://placekitten.com/200/100"
phone="(212) 555-4567"
email="thecat@hotmail.com" />
</div>
)
}
export default App
Pour utiliser les données dans le component ContactCard, il faudra écrire
function ContactCard(props){
...
A ce moment là les données sont passées au component ContactCard. Vérifions avec un console.log :
import React from "react"
function ContactCard(props) {
console.log(props)
return(
<div className="contact-card">
<img src="http://placekitten.com/300/200"/>
<h3>Mr. Whiskerson</h3>
<p>Phone: (212) 555-1234</p>
<p>Email: mr.whiskaz@catnap.meow</p>
</div>
)
}
export default ContactCard
Etant donné que le component est appelé quatre fois, les quatres objets avec leurs propriétés sont retournées.
Maintenant au lieu d’avoir les données codées en dur, mettons les données à la place.
<img src=props.imgURL/>
Ceci ne fonctionnera pas car nous sommes dans du JSX, il faut mettre enre accolades pour que se soit interprété en JS.
<img src={prop.imgURL}/>
Voici le fichier ContactCard.js:
import React from "react"
function ContactCard(props) {
return (
<div className="contact-card">
<img src={props.imgURL} />
<h3>{props.name}</h3>
<p>Phone: {props.phone}</p>
<p>Email: {props.email}</p>
</div>
)
}
export default ContactCard
Admettons maintenant que la liste des contacts serait de 50, la liste serait très longue à écrire. On peut alors paser un objet contact avec ces propriétés:
<ContactCard
contact={{name: "Mr. Whiskerson", imgURL:
"http://placekitten.com/300/200", phone: "(212) 555-1234"}}
/>
Notez bien la double accolade: une pour rentrer dans JS et l’autre pour dire que c’est un objet.
Les données passées ainsi ont bien meilleures allures, mais elles ne seront jamais écrite dans ce fichier mais plûtot écrites dans un fichier de données comme du JSON.
En passant cet objet contact, il nous faudra adapter le component ContactCard:
import React from "react"
function ContactCard(props) {
return (
<div className="contact-card">
<img src={props.contact.imgURL} />
<h3>{props.contact.name}</h3>
<p>Phone: {props.contact.phone}</p>
<p>Email: {props.contact.email}</p>
</div>
)
}
export default ContactCard
Props and Styling Practice
One LAST time in this course, set up a React app from scratch. Render an <App /> component App should be in its oww file. App should render 5 <Joke /> components. Each Joke should receive a “question” prop and a “punchLine” prop and render those however you’d like.
EXTRA CREDIT: Some jokes are only a punch line with no question: E.g.: “It’s hard to explain puns to kleptomaniacs because they always take things literally.” If you don’t pass in a “question” prop, how might you make it only show the punchline instead? Spend time practicing the style of your Joke component.
Voici le fichier index.js:
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />, document.getElementById("root"))
Le fichier App.js:
import React from "react"
import Joke from "./Joke"
function App() {
return (
<div>
<Joke
question="Où se cachent les canards?"
punchline="Dans les coins-coins."
/>
<Joke
question="Quel animal a trois bosses?"
punchline="Un chameau qui s'est cogné."
/>
<Joke
question="Comment appelle-t-on un avion qui rebondit?"
punchline="Un boing."
/>
<Joke
question="Pourquoi le père noël a-t-il une barbe blanche?"
punchline="Pour ne pas être confondu avec le petit chaperon rouge."
/>
<Joke
punchline="Vaut mieux prévenir que guérir."
/>
</div>
)
}
export default App
Le fichier Joke.js:
import React from "react"
function Joke(props) {
return(
<div>
<h3>Question: {props.question}</h3>
<h3>Réponse: {props.punchline}</h3>
<br/>
</div>
)
}
export default Joke
On remarque l’utilisation de
<br/>
pour insérer une ligne vide entre chaque joke. On aurait aussi pû utiliser
<hr/>
pour afficher une ligne de séparation
On remarque où il n’y pas de question la marque Question: subsiste. Pour faire disparaître ceci on utilisera la commande suivante style et display:
<h3 style={{display: props.question ? "block" : "none"}}>Question:
{props.question}<h3/>
un autre moyen (plus difficile à comprendre:
<h3 style={{display: !props.question && "none"}}> Question:
{props.question}<h3/>
et le fichier Joke.js:
import React from "react"
function Joke(props) {
return(
<div>
<h3 style={{display: props.question ? "block" : "none"}}>Question: {props.question}</h3>
<h3>Réponse: {props.punchline}</h3>
<br/>
</div>
)
}
export default Joke
En mettant une couleur grise aux réponses qui ne possèdent pas de question:
import React from "react"
function Joke(props) {
const styles1 = {
display: props.question ? "block" : "none",
color: "#FF8C00",
}
const styles2 = {
color: !props.question && "#888888"
}
return (
<div>
<h3 style={styles1}>Question: {props.question}</h3>
<h3 style={styles2}>Réponse: {props.punchline}</h3>
<br />
</div>
)
}
export default Joke
Mapping Components
Dans les exemples précédents, les données ont été codées en dur. La plupart du temps les données affichées par React proviennent de requêtes http par le biais d’API. Ces données sont stockées dans une base de données qui sont ensuite exportée dans un fichier JSON. Comme nous ne savons pas encore utiliser ces moyens, nous nous servirons des données stockées dans un fichier sous forme d’un tableau.
Voici le fichier JokesData.js:
const JokesData = [
{
question: "Où se cachent les canards",
punchline: "Dans les coins-coins"
},
{
question: "Quel animal a trois bosses?",
punchline: "Un chameau qui s'est cogné."
},
{
question: "Comment appelle-t-on un avion qui rebondit?",
punchline: "Un boing."
},
{
question: "Pourquoi le père noël a-t-il une barbe blanche?",
punchline: "Pour ne pas être confondu avec le petit chaperon rouge."
},
{
punchline: "Vaut mieux prévenir que guérir."
}
]
Ce tableau comporte des éléments qui sont des objets avec trois propriétés : id, question et punchline.
On note la commande export default JokeData, pour que l’on puisse utiliser les données dans App.js
Comment peut-on prendre les données d’un tableau et les convertir en nombre de components? Nous allons utiliser une fonction d’ordre supérieur dans un tableau. Qu’est que c’est que ça? prenons exemple :
nous pouvons réduire cette function en arrow function :
Comme nous avons qu’un paramètre en entrée nous pouvons omettre les parenthèses :
Et comme une arrow function retourne dans tous les cas une valeur on peut omettre le mot return et mettre tout sur une ligne.
Et voici le résultat:
On remarque que cette function d’ordre supérieur applique sur tous les éléments du tableau une multiplication par 2. On remarque aussi que map ne modifie pas le tableau original. Il faut donc attribuer le résultat à un nouveau tableau (ici doubled)
D’autre fonction d’ordre supérieur sont intéressantes à étudier comme
filter et reduce.
En appliquant le même raisonnement à notre tableau dataJokes. Ce que nous souhaitons appliquer à tous les éléments de dataJokes, c’est d’avoir une ligne comme ressemblant à ceci :
et voici donc la commande map qui fait cela :
Maintenant nous pouvons mettre ce tableau de components dans React et JSX fait cela très bien!
import React from "react"
import Joke from "./Joke"
import JokesData from "./JokesData"
function App() {
const jokeComponents = JokesData.map(item => <Joke question={item.question} punchline={item.punchline} />)
return (
<div>
{jokeComponents}
</div>
)
}
export default App
Et le résultat est identique. On déplore toutefois un avertissement :
Ceci est dû au mappage du tableau. Il faut inclure une clé (key) unique par élément. On aurait pû choisir key=question car on sait qu’il n’y aura pas deux questions identiques. Le mot key doit obligatoirement être choisi. Dans un fichier data, ily a souvent une propriété id (qui est unique) utilisons-la pour notre tableau:
Et voici le fichier final de App.js:
import React from "react"
import Joke from "./Joke"
import JokesData from "./JokesData"
function App() {
const jokeComponents = JokesData.map(item => <Joke key={item.id} question={item.question} punchline={item.punchline} />)
return (
<div>
{jokeComponents}
</div>
)
}
export default App
Et le component Joke qui n’a pas bougé depuis l’exercie précédent :
import React from "react"
function Joke(props) {
const styles1 = {
display: props.question ? "block" : "none",
color: "#FF8C00",
}
const styles2 = {
color: !props.question && "#888888"
}
return (
<div>
<h3 style={styles1}>Question: {props.question}</h3>
<h3 style={styles2}>Réponse: {props.punchline}</h3>
<br />
</div>
)
}
export default Joke
Commme déjà cité plus haut il y a plusieurs méthodes relatif au tableau qui sont bons à voir ou à revoir (tapez MDN et la méthode dans google):
filter
map
sort
reduce
every
some
find
findindex
Mapping Components Practice
Given a list of products (as an array of objects, as seen in vschoolProducts) render a <Product /> component (which you’ll also to create) for each product in the list.
Make sure to use the array’s .map() method to create thes components, and don’t forget to pass a key prop to it to avoid the warning.
Voici le fichier vschoolProducts.js:
const products = [
{
id: "1",
name: "pencil",
price: 1,
description: "Perfect for those who can't remember things! 5/5 Highly recommend."
},
{
id: "2",
name: "Housing",
price: 0,
description: "Housing provided for out-of-state students or those who can't commute"
},
{
id: "3",
name: "Computer Rental",
price: 300,
description: "Don't have a computer? No problem!"
},
{
id: "4",
name: "Coffee",
price: 2,
description: "Wake up!"
},
{
id: "5",
name: "Snack",
price: 0,
description: "Free Snacks!"
},
{
id: "6",
name: "Rubber Duckies",
price: 3.50,
description: "For those who make mistakes"
}
]
export default products
Normalement les données du tableau mappé devrait ressembler à ça:
c’est-à-dire que nous passions les propriétés de l’objet. On peut aussi passer l’objet entier et sortir les propriétés dans le composant enfant (ici Product)
Voilà le fichier App.js:
import React from "react"
import Product from "./Product"
import productsData from "./vschoolProducts"
const productComponents = productsData.map(item => <Product key={item.id} product={item} />)
function App() {
return (
<div>
{productComponents}
</div>
)
}
export default App
Remarque: Quand on export des données d’un fichier ici du fichier vschoolProducts.js nous l’exportons avec la commande suivante: export default products, mais il est possible de l’importer avec un autre nom: dans le fichier App nous l’importons avec le nom productsData (import productsData from “./vschoolProducts”
Et le fichier Product.js:
import React from "react"
function Product(props) {
return (
<div>
<h2>{props.product.name}</h2>
<p>{props.product.price.toLocaleString("en-US", { style: "currency", currency: "USD" })} - {props.product.description}</p>
</div>
)
}
export default Product
Pour afficher l’unité du prix, on s’est servi de la méthode string.
Le résultat final:
Todo App - Phase 3
Let’s practice props and mapping components on our todo list app:
I’ve created a js file with some todos data in it, which I’m imported into this files. (Normally this data would come from an API call, not a local file).
Challenge: Using the array map method, render a child component for each todo item in the todosData array and pass the relevant data to it.
L’exercice est très similaire à l’exercice précédent, j’exposerai seulement les fichiers comme résultat. Sauf pour la partie case à cocher, j’expliquerai comment coché avec la propriété checked.
Voici le fichier todosData.js:
const todosData = [
{
id: 1,
text: "Take out the trash",
completed: true
},
{
id: 2,
text: "Grocery shopping",
completed: false
},
{
id: 3,
text: "Clean gecko tank",
completed: false
},
{
id: 4,
text: "Mow lawn",
completed: true
},
{
id: 5,
text: "Catch up on Arrested Development",
completed: false
}
]
export default todosData
Voici le fichier index.js (rien de nouveau dans celui-ci):
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />, document.getElementById("root"))
Voici le fichier App.js:
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
function App() {
const todoItems = todosData.map(item => <TodoItem key={item.id} item={item} />)
return (
<div>
{ todoItems}
</div>
)
}
export default App
Attention de bien mettre key pour empêcher les doublons.
et le fichier TodoItem.js:
import React from "react"
function TodoItem(props) {
return (
<div className="todo-item">
<input type="checkbox" checked={props.item.completed} />
<p>{props.item.text}</p>
</div>
)
}
export default TodoItem
On remarque l’utilisation de la propriété checked:
<input type="checkbox" checked={props.item.completed} />
Pour afficher un vu suivant props.item.completd fixé par true ou false dans le fichier todosData.js. Le navigateur affiche un message d’erreur car cela fige la case à cocher (plus de possibilité de cocher ou de décocher manuellement). Mais cela va être résolut par la suite.
Class-based Components
Si l’on veut approfondir avec React, on sera limité par l’utilisation des Functional Component. C’est pourquoi nous allons utiliser les Class-based Components. Pour l’instant nous allons introduire les Class-based Components pour reproduire exactement ce que les fonctions peuvent faire. Mais dans les prochaines leçons nous allons découvrir que les Class-based Components peuvent faire bien plus, comme States, Livecycle Methods.
Découvrons maintenant comment convertir une Functional Component en Class-based Component:
import React from "react"
function App() {
return (
<div>
<h1>Code goes here</h1>
<div>
)
}
pour une Class-based Component, il n’y pas de parenthèses commme pour une Functional Component.
class App extends React.Component
export default App
Chaque Class-based Component à besoi d’au moin une méthode et cette méthode est la méthode render et cela doit impérativement être écrit de la cette manière :
class App extends React.Component {
render() {
}
}
export default App
La méthode render va retourner exactement la même chose que ce que l’on a pour les Functional Components. Nous pouvons donc copier ce qu’il y a dans dans return avec le mot return de la Functional Component :
class App extends React.Component { render() { return ( <div> <h1>Code goes here</h1> </div> ) } } export default App
Cette Class-based Component est identique à la Functional Component.
Voyons maintenant la méthode render(), à chaque fois que l’on désire faire une logique d’affichage, comme par expemple l’exercice d’affichage du texte en fonction de l’heure que l’on avait fait plus haut, le code sera inséré après la méthode render() et avant return :
class App extends React.Component {
render() {
const date = new Date();
return (
<div>
<h1>Code goes here</h1>
</div>
)
}
}
export default App
L’inline styling pourra aussi y être placé.
On peut créé des méthodes après class et avant render() et les appeler après la méthode render() avec this.yourMehodHere():
class App extends React.Component {
yourMethodeHere() {
}
render() {
const style = this.yourMethodeHere()
return (
<div>
<h1>Code goes here</h1>
</div>
)
}
}
export default App
Pour l’utilisation de props on fera précédé le mot props par this. :
class App extends React.Component {
yourMethodeHere() {
}
render() {
return (
<div>
<h1>Code goes here{this.props.whatever}</h1>
</div>
)
}
}
export default App
En ayant l’habitude d’utiliser props dans des functional Component, on oubliera vite le mot this. dans une Class-based Component.
Class-based Components Practice
Pour cette exercice nous allons mettre tous les composants dans un même fichier. Normalement, chaque composant est mis dans un fichier séparé.
Challenge:
Convert all 3 components to be class-based
Fix the small bug
import React from "react"
import ReactDOM from "react-dom"
// #1
function App() {
return (
<div>
<Header />
<Greeting />
</div>
)
}
// #2
function Header(props) {
return (
<header>
<p>welcome, {props.username}!</p>
</header>
)
}
// #3
function Greeting() {
const date = new Date()
const hours = date.getHours()
let timeOfDay
if (hours < 12) {
timeOfDay = "morning"
} else if (hours >= 12 && hours < 17) {
timeOfDay = "afternoon"
} else {
timeOfDay = "night"
}
return (
<h1>Good {timeOfDay} to you, sir or madam!</h1>
)
}
ReactDOM.render(<App />, document.getElementById("root"))
Pour convertir une Functional Component en Class-base Component :
Remplacer le mot function en class
Enlever les () après le nom de la fonction
Ecrire extends React.Component
Ecrire render()
Si il y a du code pour styling, etc… le mettre juste après render()
Copier return et son contenu
Si il y a des props, mettre {this.props.whatever}
import React from "react"
import ReactDOM from "react-dom"
// #1
class App extends React.Component {
render() {
return (
<div>
<Header />
<Greeting />
</div>
)
}
}
// #2
class Header extends React.Component {
render() {
return (
<header>
<p>welcome, {props.username}!</p>
</header>
)
}
}
// #3
class Greeting extends React.Component {
render() {
const date = new Date()
const hours = date.getHours()
let timeOfDay
if (hours < 12) {
timeOfDay = "morning"
} else if (hours >= 12 && hours < 17) {
timeOfDay = "afternoon"
} else {
timeOfDay = "night"
}
return (
<h1>Good {timeOfDay} to you, sir or madam!</h1>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"))
On voit qu’il y un message d’erreur ‘props’ is not defined. Ceci est normal, car dans une class on doit utiliser this.props.whatever
Aussi, il faut passer les données à props
<Header username="windwaver" />
Voici le code final:
import React from "react"
import ReactDOM from "react-dom"
// #1
class App extends React.Component {
render() {
return (
<div>
<Header username="windwaver" />
<Greeting />
</div>
)
}
}
// #2
class Header extends React.Component {
render() {
return (
<header>
<p>welcome, {this.props.username}!</p>
</header>
)
}
}
// #3
class Greeting extends React.Component {
render() {
const date = new Date()
const hours = date.getHours()
let timeOfDay
if (hours < 12) {
timeOfDay = "morning"
} else if (hours >= 12 && hours < 17) {
timeOfDay = "afternoon"
} else {
timeOfDay = "night"
}
return (
<h1>Good {timeOfDay} to you, sir or madam!</h1>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"))
Et le résultat:
State
Voilà, nous sommes arrivés au point le plus important de React. C’est la compréhension de state. State est utilisé pour la gestion des données. State permet de modifier les données. La différence entre state et props c’est que les données passées à un autre component par props ne peuvent être changées, elle sont immuables. State permet cela. On ne pourra par exemple jamais attribué une valeur à props comme par exemple :
Chaque fois que l’on veut modifier une donnée on devra passer par state. Et state ne peut être invoqué que par une Class-based Component.
Pour introduire state dans une Class-based Component, il nous faut écrire la méthode constructor() une ligne en dessous de class… La méthode constructor() est issue du Java Script. Elle initialise la class.
Pour se familiariser avec class voir Classes ou voir la vidéo suivante :
https://scrimba.com/p/p4Mrt9/cQnMDHD
Ensuite en dessous il nous faut écrire super() cette méthode à pour but de tirer quelque goodies de React.Component. Un des goodies est la méthode set state() que l’on verra plus loin. En dessous de super() on mettra this.state = {} qui est un objet avec une propriété que l’on peut appeler dans le Component.
Voici le fichier:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
answer: "Yes"
}
}
render() {
return (
<div>
<h1>Is React important to know? {this.state.answer}</h1>
</div>
)
}
}
export default App
et le résultat :
Le this.state initialise notre state. Le fait particulier de state est que l’on peut modifier sa valeur plus tard. On peut passer state à un component enfant en invoquant props.
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
answer: "Yes"
}
}
render() {
return (
<div>
<h1>Is React important to know? {this.state.answer}</h1>
<ChildComponent answer = {this.state.answer}/>
</div>
)
}
}
export default App
Un truc cool avec state est quand on modifie la variable state tous les composant utilisant sa valeurs vont être rafraîchit. Nous verrons ceci plus tard avec la commande set state.
State Practice
Challenge:
Given an incomplete class-based component without a constructor, add a constructor and initialiye state to fix the brocken component.
import React from "react"
class App extends Component() {
return(
<div>
<h1>{this.state.name}</h1>
<h3>{this.state.age} years old</h3>
</div >
)
}
export default App
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
name: "Terry",
age: 27
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
<h3>{this.state.age} years old</h3>
</div >
)
}
}
export default App
Et le résultat:
State Practice 2
Given a stateless functional component, add state to it. State should have a property called isLoggedIn wich is a boolean (true if logged in, false if not). Then, give your best shot at rendering the word “in” if the user is logged in or “out” if the user is logged out.
import React from "react"
function App() {
return (
<div>
<h1>You are currently logged (in/out)</h1>
</div>
)
}
export default App
voici pour la première partie:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoggedIn: true
}
}
render() {
return (
<div>
<h1>You are currently logged (in/out)</h1>
</div>
)
}
}
export default App
pour la dernière partie on utilisera du conditional rendering. Attention de bien le placer entre render() et return() :
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoggedIn: false
}
}
render() {
let wordDisplay
if (this.state.isLoggedIn === true) {
wordDisplay = "in"
}
else {
wordDisplay = "out"
}
return (
<div>
<h1>You are currently logged {wordDisplay}</h1>
</div>
)
}
}
export default App
et le résulat :
Todo App - Phase 4
In the previous iteration of this todo list app, we pulled in todos data from a JSON file and mapped over it to display the todo items. Eventually we’ll want to be able to modify the data, which will only happen if we’ve “loaded” the data in to the component’s state
Challenge: Change the <App /> component into a stateful class component and load the imported todosData into state.
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
function App() {
const todoItems = todosData.map(item => <TodoItem key={item.id} item={item} />)
return (
<div>
{ todoItems}
</div>
)
}
export default App
en changeant en class:
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
class App extends React.Component {
constructor() {
super()
this.state = {
todo: todosData
}
}
render() {
const todoItems = this.state.todo.map(item => <TodoItem key={item.id} item={item} />)
return (
<div>
{ todoItems}
</div>
)
}
}
export default App
Handling Events in React
Handling Events sont des événements tel que l’utilisateur déclenchera quand il clique sur un élément ou passe la souris sur un élément. Vous serez sûrement familié avec le language html qui est le suivant:
<button onclick="myFunction()">Click me</button>
Avec React c’est presque la même chose: les événements sont repris du Java Script, ils auront une majuscule.Ppour l’évémement de ci-dessus cela deviendrait:
onClick
Pour:
onmouseover
cela devient:
OnMouseOver
Ici quelques nom d’événement à réviser:
https://reactjs.org/docs/events.html#supported-events
Voici un code avec un bouton sans événement:
Administrons une fonction à l’événement onClick à ce bouton:
et le résultat quant on clique sur le bouton:
Ou en appelant la fonction déclarée séparément:
Un petit exercice: en se référant à la page ci-dessous:
https://reactjs.org/docs/events.html#supported-events
trouver et écrire un événement lorsque le pointeur de la souris passe sur l’image, un événement se déclenche.
Il est clair que faire sortir le résultat d’un événement en console.log n’est pas intéressante. En fait les événements pourront modifié les state et c’est ce qui va faire une app très robuste.
Todo App - Phase 5
Challenge: Get rid of our warning about not having an onChange on our input. For now, the function that runs onChange can simply console.log something.
Voici le code comme il était resté au dernier exercice:
import React from "react"
function TodoItem(props) {
return (
<div className="todo-item">
<input type="checkbox" checked={props.item.completed} />
<p>{props.item.text}</p>
</div>
)
}
export default TodoItem
Voici la solution:
import React from "react"
function TodoItem(props) {
return (
<div className="todo-item">
<input
type="checkbox"
checked={props.item.completed}
onChange={() => console.log("changed")}
/>
<p>{props.item.text}</p>
</div>
)
}
export default TodoItem
On remarque pour plus de clarté, on peut mettre à la ligne ce qu’il y a entre <input …. et />
Changing State
Voici le moment venu d’apprendre comment on change la valeur de state. Prenons un exemple: un compteur (count) avec un bouton en dessous et lorsque l’on clique sur le bouton cela va nous changer la valeur de count.
voici le code de départ:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button> Change!</button>
</div >
)
}
}
export default App
Petit exercie que faut il mettre pour que quand on appuie sur le boutton quelque chose apparaisse dans le console.log?
On doit rajouter un évenement onClick:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={() => console.log("clicked")}> Change!</button>
</div >
)
}
}
export default App
Au lieu d’une arrow function (ici un fonction anonyme en ligne) créons une méthode et déclarons-la au bon endroit. Pour savoir où la déclarer, voici une explicaton sur les zones:
La partie render() est réservée pour les méthodes utilisée par React, entre constructor() et render() on peut mettre autant de méthodes que l’on veut.
Une forte convention que les gens ont, est de l’appeler handleClick lorsque on l’associe à l’événement onClick. Attention de bien mettre this.handlclick quand on appelle la méthode.
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
}
handleClick() {
console.log("clicked!")
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.handleClick}> Change!</button>
</div >
)
}
}
export default App
Bon ceci est enuyeux, changeons maintenant la valeur de state (ici de count).
Pour changer la valeur de count, on est tenté de changer directement avec la commande suivante:
handleClick(){
this.state.count++
}
Mais ceci ne se fait pas on ne change jamais la valeur originale de state. On crée une nouvelle version de state. On peut apparenté ceci aux habit que l’on porte. On ne changera pas la couleur de l’habit en le peignant, on changera l’habit. Et c’est la même chose pour state. Rappelons nous lorsque nous évoquons extends React.Component, il y quelques goodies qui nous sont offerts comme la méthode setState(). A chaque fois que l’on voudra changer state nous utiserons cette méthode. Il y deux choses que l’on peut passer à cette méthode en paramètre : prenons la plus simple, une nouvelle version de state. State est un un objet et l’on peut passer un nouvel objet comme ici :
this.setState({count: 1})
nous arrivons à une erreur : à chaque fois que l’on crée une class method, nous seront obligé de “bind” cette méthode à notre class. Si vous n’êtes pas tout à fait familié avec “bind” ne vous en fait pas trop. Sachez que chaque fois que vous faite une méthode avec setState, il faudra la “binder” avec votre classe. Et le moyen de “binder” se fait à l’intérieur de constructor().
this.handleClick = this.handleClick.bind(this)
Ce que fait cette commande est d’assurer que la méthode handleClick soit bound au contexte de this au travers de la classe.
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
this.handleClick=this.handleClick.bind(this)
}
handleClick() {
this.setState({ count: 1 })
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.handleClick}> Change!</button>
</div >
)
}
}
export default App
Résultat quand on click sur bouton la valeur passe de 0 à 1.
Lorsque l’on n’a pas besoin de connaître le résultat de la version d’avant de state, l’assignation du nouveau objet fera l’affaire. Par contre, lorsque l’on veut additioner 1 à count, il nous faut connaître l’état précédent. Pour ce faire on fera passer une fonction :
handleClick() {
this.setState(prevState => {
return {
count: prevState.count +1
}
})
}
Résultat : Lorsque l’on clique sur le bouton le compteur est incrémenter de 1.
Récapitulons :
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0
}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState(prevState => {
return {
count: prevState.count + 1
}
})
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.handleClick}> Change!</button>
</div >
)
}
}
export default App
Nous avons:
<h1>{this.state.count}</h1>
qui affiche notre state ici la propriété count
Cette propriété a été initialisée dans constructor
On a ajouter un event onClick à notre button qui actionne notre méthode handleClick. Cette méthode a été crée dans la class App
Parce que la méthode handleClick utilise la méthode setState qui vient de extends React.Component, nous devons être sûr de “binder” dans constructor
Une fois que la méthode handleClick a été “bindé”, on peut utiliser la méthode setState pour soit attribué un objet pour créer une nouvel version de state (sans se préoccupé de la version précédente)
, soit de passer une fonction qui passe le paramètre comme un objet de la version précédente et returne la nouvelle version après avoir utilisé la version précédente.
Cette partie de state est très importante à connaître car elle sera utilisée souvent lors des prochaines leçons. Donc effacer tout le code et regarder si vous pouvez tout le refaire de tête. C’est le meilleure moyens d’en prendre connaissance.
Todo App - Phase 6
Dans cet exercice, nous allons modifier le code de notre Todo App de telle façon que lorsque l’on clique sur une case à cocher, la case sera cochée ou décochée. Nous allon en fait modifier le state.
/**
* Let's make it so our checkbox can actually mark our todo as complete or incomplete!
* This challenge is a little more involved than some of the past ones. Check the comments
* in the code for some help on accomplishing this one
*
* Challenge:
* 1. Create an event handler in the App component for when the checkbox is clicked (which is an
* `onChange`event)
* a. This method will be the trickest part. Check the comments in the stubbed-out method below
* for some pseudocode to help guide you through this part
* 2. Pass the method down to the TodoItem component
* 3. In the TodoItem component, make it so when the `onChange` event happens, it calls the
* `handleChange` method and passes the id of the todo into the function
*/
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
class App extends React.Component {
constructor() {
super()
this.state = {
todo: todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
/**
* Update state so that the item with the given id flips `completed` from false to true
* (or vise versa)
* Remember not to modify prevState directly, but instead to return a new version of state with
* with the change you want included in that update. (Think how you might use the `.map)`
* method to do this
*/
}
render() {
const todoItems = this.state.todo.map(item => <TodoItem key={item.id} item={item} />)
return (
<div>
{ todoItems}
</div>
)
}
}
export default App
Faisons cela dans un ordre quelquonque : toute d’abord faisons un console.log à notre méthode handleChange :
pour tester lorsqu’on clique sur une case l’id est bien affiché. Maintenant, faisons les points 2. et 3. :
Donc le point 2, dit qu’il faut passer notre méthode handleChange à notre composant TodoItem:
et maintenant notre TodoItem reçoit notre méthode: props.handleChange. Prenez note que la méthode prend id comme paramètre et que OnChange reçoit une propriété event. Cela n’est pas suffisant d’appeler notre props de cette manière :
car onChange ne pas recevoir une propriété event, mais seulement un objet event à la place.
on insérer une fonction qui émet une propriété event et qui appelle la méthode handleChange avec comme paramètre props.item.id.
Dans ce cas nous n’allons pas utiliser event on peut donc juste l’effacer:
Faisons un test en cliquant sur les cases à cocher on voit que l’id correspondant s’affiche correctement:
Voici le code complet de TodoItem.js:
import React from "react"
function TodoItem(props) {
return (
<div className="todo-item">
<input
type="checkbox"
checked={props.item.completed}
onChange={() => props.handleChange(props.item.id)}
/>
<p>{props.item.text}</p>
</div>
)
}
export default TodoItem
Voilà les points 2 et 3 sont achevés. Occupons-nous d’actualisé notre state :
Cette partie est la plus trickie. Nous devons nous occuper de l’entier du tableau, car nous enregistrons notre tableau dans notre state et nous ne voulons jamais changer notre state directement, nous ne pouvons pas simplement changer l’élément du bon id en flippant sa valeur de true à false ou vice versa car cela modifie la version original de state. A l’opposé nous allons créer un nouveau tableau en conservant tous les éléments à l’exception de l’élément qui passera de true à false ou vice versa. Pour ce faire, nous allons utiliser la méthode map car comme nous le savons déjà celle-ci retournera un tout nouveau tableau.
Donc ce que l’on va d’abord faire c’est utiliser setState avec une fonction pour conserver la version originale : Nous allons utiliser map pour faire une boucle de notre tableau original.
prevState.todos est notre ancienne version de todos. Nous allons parcourir tous les éléments de ce tableau avec
todo => {
if (todo.id === id)}
et cet id est l’élément que l’on veut basculer.
ensuite nous allons retourner todo pour mettre ce nouveau tableau dans updateTodos.
encore un return pour assigner le nouveau tableau à la propriété todos de l’objet.
Et voici le code complet de App.js:
/**
* Let's make it so our checkbox can actually mark our todo as complete or incomplete!
* This challenge is a little more involved than some of the past ones. Check the comments
* in the code for some help on accomplishing this one
*
* Challenge:
* 1. Create an event handler in the App component for when the checkbox is clicked (which is an
* `onChange`event)
* a. This method will be the trickest part. Check the comments in the stubbed-out method below
* for some pseudocode to help guide you through this part
* 2. Pass the method down to the TodoItem component
* 3. In the TodoItem component, make it so when the `onChange` event happens, it calls the
* `handleChange` method and passes the id of the todo into the function
*/
import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"
class App extends React.Component {
constructor() {
super()
this.state = {
todos: todosData
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(id) {
/**
* Update state so that the item with the given id flips `completed` from false to true
* (or vise versa)
* Remember not to modify prevState directly, but instead to return a new version of state with
* with the change you want included in that update. (Think how you might use the `.map)`
* method to do this
*/
this.setState(prevState => {
const updatedTodos = prevState.todos.map(todo => {
if (todo.id === id) {
todo.completed = !todo.completed
}
return todo
})
return {
todos: updatedTodos
}
})
}
render() {
const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange} />)
return (
<div>
{ todoItems}
</div>
)
}
}
export default App
Le test a bien fonctionné en cliquant sur une case ça bascule bel et bien.
Lifecycle Methods Part 1
Chaque component sous React possède en arrière plan des méthodes de cycle de vie. Comme la vie humaine qui a une naissance, …, et une mort. Tous les éléments React vont traverser des événements lorsqu’ils sont rendus (rendered) et mis à jour. L’équipe de React a déprecié trois Lifecycle methods. Au lieu de prendre chaqu’une des méthodes une à une, nous allons présenter les méthodes les plus utilisées. Pour une introduction plus complète à ces méthodes veuillez vous référer à ce site: https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1
et le site officiel de l’équipe React:
https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes
Conditional Rendering
Le Conditional Rendering peut être appliqué de beaucoup de façon différentes. Proposons une façons dans le code suivant:
import React from "react"
import Conditional from "./Conditional"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoading: true
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
isLoading: false
})
}, 1500)
}
render() {
return (
<div>
<Conditional isLoading={this.state.isLoading} />
</div>
)
}
}
export default App
Dans le code de ci-dessus, on a ajouté un state avec une propriété isLoading à true. Ceci est souvent utilisé lors d’appel vers un API, et pendant le chargement on veut afficher quelque chose pour dire qu’il y a un processus en cours. Ainsi l’utilisateur n’aura pas l’impression que l’app a crashé. Le Conditional Rendering intervient là. Nous avons un autre Component Conditional qui reçoit le props isLoading avec la version courante de state : this.state.isLoading. Dans Conditional nous allons ajouter ce que l’on veux afficher à l’écran.
Rappelez-vous que la méthode componentDidMount() est une chance pour nous d’écrire du code pour qu’il s’execute avant que notre Component ici App s’execute à l’écran pour la première fois. Le code compris dans componentDidMount est en fait un code qui simule une requête API. Nous avons mis un délai de 1500 via la fonction setTimeout qui va faire basucler la propriété isLoading à false. Une fois que ça bascule à false, le component Conditional va recevoir une nouvel prop, ce qui va réexuter la méthode render() ce qui va faire à nouveau s’excuter le component Conditional qui est une functional component et selon ce qui a dedans faire executer quelque chose d’autre. Donc notre component Conditional va recevoir une nouvel prop. Avant d’aller plus loin vérifions que notre component Conditional fonctionne, en mettant un console.log(props.isLoading) : ci-dessous le component Conditional:
import React from "react"
function Conditional(props) {
console.log(props.isLoading)
return (
<div>
<h1>Temp</h1>
</div>
)
}
export default Conditional
Lorsque l’on rafraîchit la page, true s’affiche tout de suite et 1.5s plus tard false s’affiche.
Maintenant au lieu d’afficher Temp nous allons mettre une condition qui affichera quelque chose de différent suivant la valeur de isLoading.
import React from "react"
function Conditional(props) {
if (props.isLoading === true) {
return (
<h1>Loading...</h1>
)
} else {
return (
<div>
<h1>Some cool stuff about conditional rendering</h1>
</div>
)
}
}
export default Conditional
Le résultat est que ça affiche isLoading pendant 1.5s et ensuite Some cool stuff…
Ce code utilise du pur Java Script avec if. On préférera réécrire ce code de la façon suivante avec ce mode de conditionnement mais c’est un choix personnel bien-sûr :
condition ? statement if true : statement if false
import React from "react"
function Conditional(props) {
return (
<div>
<h1>Navbar</h1>
{props.isLoading ? <h1>Loading...</h1> : <h1>Some cool stuff about conditional rendering</h1>}
<h1>Footer</h1>
</div>
)
}
export default Conditional
Nous avons mis ce code dans un component Conditional, mais le meilleur endroit pour mettre ce genre de code est dans le component App. Car c’est dans la méthode render() qui est le plus approprié à dire qu’un composant doit être executé ou pas.
Voici le code App.js et Conditional.js:
import React from "react"
import Conditional from "./Conditional"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoading: true
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
isLoading: false
})
}, 1500)
}
render() {
return (
<div>
{this.state.isLoading ?
<h1>Loading..</h1> :
<Conditional />}
</div>
)
}
}
export default App
import React from "react"
function Conditional() {
return (
<div>
<h1>Some cool stuff about conditional rendering</h1>
</div>
)
}
export default Conditional
Conditional Rendering Part 2
Un autre moyen que d’utiliser: condition ? statement if true : statement if false est l’opérateur && (and):
Si à gauche de && est true alors ce qui est à droite est fait (retourne false si à droite c’est false). Si à gauche de && est faux alors ce qui est à droite est null ou n’est pas executé.
Prenons un exemple:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
unreadMessages: [
"Call your mom!",
"New spam email available. All links are definitely safe to click."
]
}
}
render() {
return (
<div>
<h2>You have {this.state.unreadMessages.length} unread messages!</h2>
</div>
)
}
}
export default App
Ce code affiche le nombre de message non lus. Quand il n’y pas de message ce code affiche quand même quelque chose :
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
unreadMessages: []
}
}
render() {
return (
<div>
<h2>You have {this.state.unreadMessages.length} unread messages!</h2>
</div>
)
}
}
export default App
Lorsqu’il n’y pas de message on ne souhaiterait pas non plus être informé qu’il y 0 message (trop d’information tue l’information). D’après ce que l’on vient de voir dans la leçon précédente on peut écrire ceci comme cela:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
unreadMessages: []
}
}
render() {
return (
<div>
{
this.state.unreadMessages.length > 0 ?
<h2>You have {this.state.unreadMessages.length} unread messages!</h2> :
null
}
</div>
)
}
}
export default App
Qui n’affiche rien quand il y a zéro message.
On peut grâche à l’opérateur && réduire ce code comme cela:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
unreadMessages: []
}
}
render() {
return (
<div>
{
this.state.unreadMessages.length > 0 &&
<h2>You have {this.state.unreadMessages.length} unread messages!</h2>
}
</div>
)
}
}
export default App
qui a le même résultat qu’avant.
En mettant trois messages on remarque que le message réapparaît avec trois messages non lus.
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
unreadMessages: ["a","b","c"]
}
}
render() {
return (
<div>
{
this.state.unreadMessages.length > 0 &&
<h2>You have {this.state.unreadMessages.length} unread messages!</h2>
}
</div>
)
}
}
export default App
Conditional rendering Practice
import React from "react"
/*
Challenge:
Given a stateless functional component:
1. Follow the steps necessary to add state to it,
2. Have state keep of wheter the user is logged in or not
3. Add a button that logs the user in/out
a. extra challenge - make the button display "log in" if they're not logged in and "log out" if
they are
4. Display text that says "Logged in" if the user is logged in, or "Logged out" if they're not.
*/
function App() {
return (
<div>
Code goes here
</div>
)
}
export default App
Hints:
Pour faire cet exercice, il nous faudra en 1) un class-base component et une méthode constructor. En 2) Il faudra un state avec une propriété d’objet booléene, appelons-là isLoggedIn (true or false). En 3) on ajoutera un even listener (onClick) et pour l’extra challenge on utilisera du Conditional Rendering. On appliquera aussi du Conditional Rendering au point 4).
import React from "react"
/*
Challenge:
Given a stateless functional component:
1. Follow the steps necessary to add state to it,
// class-based component
// constructor method
2. Have state keep of wheter the user is logged in or not
// isLoggedIn: Boolean (true or false)
3. Add a button that logs the user in/out
// event listener (onClick)
a. extra challenge - make the button display "log in" if they're not logged in and "log out" if
they are
// Conditional Rendering
4. Display text that says "Logged in" if the user is logged in, or "Logged out" if they're not.
// Conditional Rendering
*/
function App() {
return (
<div>
Code goes here
</div>
)
}
export default App
Pour commencer il nous faut un class-based component car nous devons utiliser state. On remplace function par App et on enlève les parenthèses. Etant donné qu’il nous faudra introduire state nous devrons avoir la méthode constructor() suivi de super(). On initialise state qui est un objet avec une propriété isLoggedIn.
Donc voici pour les points 1) et 2)
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoggedIn: false
}
}
render() {
return (
<div>
Code goes here
</div>
)
}
}
export default App
Maintenant nous devons ajouter un bouton. Ensuite on ajoute un event listner pour permettre à notre button d’effectuer une action. Une méthode de classe nommée this.handClick est attribué à l’event listner. Créons la méthode de classe handlClick. “Bindons” la dans constructor(). Avant d’aller plus loin, il est bien de contrôler que tout fonctionne jusque là. Mettons un console.log pour vérifier cela:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoggedIn: false
}
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
console.log("I'm working")
}
render() {
return (
<div>
<button onClick={this.handleClick}>LOG IN</button>
</div>
)
}
}
export default App
et le résultat affiche bien ce que l’on veut quand on clique sur le bouton.
Ce que l’on souhaite maintenant faire c’est de basculer la propriété isLoggedIn à true ou false suivant la donnée courante. On utilise setState pour ce faire, et comme on veut définir state en fonction de la valeur précédente, on utilisera une function. Pour afficher la nouvelle valeur de state on placera dans le render() le texte sur le bouton égale à l’inverse de isLoggedIn. On placera aussi un autre texte suivant que l’on est connecté ou pas. Pour placer ces textes on fera usage du Conditional Rendering :
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
isLoggedIn: false
}
this.handleClick=this.handleClick.bind(this)
}
handleClick(){
this.setState(prevState => {
return {
isLoggedIn: !prevState.isLoggedIn
}
})
}
render() {
let buttonText = this.state.isLoggedIn ? "LOG OUT" : "LOG IN"
let displayText= this.state.isLoggedIn ? "Logged in" : "Logged out"
return (
<div>
<button onClick={this.handleClick}>{buttonText}</button>
<h1>{displayText}</h1>
</div>
)
}
}
export default App
Et le résultat:
On voit bien que lorsque on clique sur le bouton l’état change impéccablement et le texte aussi.
Todo App - Phase 7
Reprenons notre exercice de Todo. Dans cette exercice nous allons appliquer un style lorsque la tâche a été effectuée. Comme mettre la ligne en italique, grisée, et biffée.
On utilise pour cela du inline styling. En fonction de la valeur de props.item.completed on choisira d’appliquer le style ou non. Voici le code :
/**
* Challenge: Style the completed todo items differently from the incomplete items.
*/
import React from "react"
function TodoItem(props) {
const completedStyle = {
fontStyle: "italic",
color: "#cdcdcd",
textDecoration: "line-through"
}
return (
<div className="todo-item">
<input
type="checkbox"
checked={props.item.completed}
onChange={() => props.handleChange(props.item.id)}
/>
<p style={props.item.completed ? completedStyle: null}>{props.item.text}</p>
</div>
)
}
export default TodoItem
Et un screenshot pour montrer le résultat :
Fetching data from an API
Voici un lien pour l’explication de la comande fetch :
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
La commande fetch renvoie une promise. Pour l’explication de promise voir le site suivant:
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261
Dans cet exemple nous allons capturer les données de personnages du film Star Wars. Un site existe et se trouve à l’adresse suivante:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {}
}
componentDidMount(){
fetch("https://swapi.dev/api/people/1")
.then(response => response.json())
.then(data => console.log(data))
}
render() {
return (
<div>
Code goes here
</div>
)
}
}
export default App
Pour enregistrer les données reçue par fetch nous allons les mettre dans state.
Voici le code pour ce faire:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
character: {}
}
}
componentDidMount() {
fetch("https://swapi.dev/api/people/1")
.then(response => response.json())
.then(data =>
this.setState({
character: data
})
)
}
render() {
return (
<div>
{this.state.character.name}
</div>
)
}
}
export default App
Et le résultat:
Pour informer l’utilisateur que les données sont en cours de téléchargement on peut écrire un message d’information avec le code suivant:
import React from "react"
class App extends React.Component {
constructor() {
super()
this.state = {
loading: false,
character: {}
}
}
componentDidMount() {
this.setState({loading: true})
fetch("https://swapi.dev/api/people/1")
.then(response => response.json())
.then(data =>
this.setState({
loading: false,
character: data
})
)
}
render() {
const text = this.state.loading ? "loading..." : this.state.character.name
return (
<div>
<p>{text}</p>
</div>
)
}
}
export default App
Le téléchargement est ici tellement rapide que l’on a à peine le temps de voir loading. Mais cela s’affiche correctement.
Forms Part 1
Un peu de théorie avant de se plonger dans le vif du sujet:
https://reactjs.org/docs/forms.html
La saisie dans un formulaire avec React déclenche un événement onChange qui modifie state après chaque caractère saisi. Pour illustrer ceci faisons un exemple d’une simple saisie d’un input.
import React, { Component } from "react"
class App extends Component {
constructor() {
super()
this.state = {}
}
render() {
return (
<form>
<input type="text" placeholder="First Name" />
</form>
)
}
}
export default App
Pour voir chaque changement dans cette input box, on mettra un déclencheur onChange dans input box. Donc chaque fois que l’on changera la saisie dans l’input box on activera une fonction. Le but étant de changer state à chaque caractère saisi. Donc on doit prendre la valeur de input box et la passer à state. Pour l’instant state n’a pas de propriété à changer, mettons en un maintenant.
import React, { Component } from "react"
class App extends Component {
constructor() {
super()
this.state = {
firstname: ""
}
}
handChange(){
}
render() {
return (
<form>
<input type="text" placeholder="First Name" onChange={this.handleChange} />
</form>
)
}
}
export default App
Etant donné que l’on ne se soucie pas de la valeur précédente de state on instanciera state de la manière suivante:
et que doit-on mettre à la place des points d’interrogation? On sait que lors de déclenchement d’événement il y des paramètre prédéterminés qui sont transmis à la fonction. Nous allons donc mettre le paramètre event à notre fonction:
On trouve des informations importantes dans le paramètre event. Par exemple, on peut accéder à la valeur de notre input box.
event.target représente la source de l’événement déclenché ici c’est l’input box. Donc notre state est vraiment le reflet de la valeur saisie de notre input box.
pour voir la valeur de state mettons un h1 pour voir le résultat:
On voit que rien de s’affiche. C’est parce que nous n’avons pas binder notre handleChange. Il faut mettre la commande suivante dans le constructor()
Et maintenant on voit que ça fonctionne:
Maintenant au lieu d’avoir qu’une seule valeur dans notre formulaire, mettons en plusieurs:
import React, { Component } from "react"
class App extends Component {
constructor() {
super()
this.state = {
firstName: "",
lastName: ""
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
firstName: event.target.value
})
}
render() {
return (
<form>
<input type="text" placeholder="First Name" onChange={this.handleChange} />
<br />
<input type="text" placeholder="Last Name" onChange={this.handleChange} />
<h1>{this.state.firstName} {this.state.lastName}</h1>
</form>
)
}
}
export default App
Le résultat n’est pas vraiment satisfaisant car il efface First Name dès que l’on commence à tapez quelque chose dans Last Name.
Pour parer à celon nous pourrions très bien faire une fonction pour chaque entrée d’un formulaire comme par exemple handleChangeLastName. Mais cela ne sera pas très simple lorsque le formulaire aura beaucoup de champs.
Au lieu de cela nous n’allons pas coder en dur firstName ici:
Mais donner un nom de propriété à notre input box:
et aussi apporter le changement suivant à notre fonction handleChange():
On voit que ça fonctionne bien:
Encore une chose pour améliorer on ajoute value à notre input box:
et lorsque la ligne devient longue on peut mettre chaque attribut sur une ligne :
De cette manière on force la value à ce qu’est state.
Une autre chose pour simplifier le déboggage et pour rendre plus lisible le code:
Et pour clore cette section le code de App.js en entier:
import React, { Component } from "react"
class App extends Component {
constructor() {
super()
this.state = {
firstName: "",
lastName: ""
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const {name, value} = event.target
this.setState({
[name]: value
})
}
render() {
return (
<form>
<input
type="text"
value={this.state.firstName}
name="firstName"
placeholder="First Name"
onChange={this.handleChange} />
<br />
<input
type="text"
value={this.state.lastName}
name="lastName"
placeholder="Last Name"
onChange={this.handleChange} />
<h1>{this.state.firstName} {this.state.lastName}</h1>
</form>
)
}
}
export default App
Forms Part 2
Nous allons introduire maintenant les différents éléments utiles que peuvent contenir les éléments de formulaires qui sont:
<textarea /> element
<input type=”checkbox” />
<input type=”radio” />
<select> and <option> elements
textarea
En html, textarea n’a pas de self closing tag comme input mais comporte un closing tag:
<textarea></textarea>
Que l’on peut étendre dans la page web. L’utilisateur a aussi la possibilité de mettre un largeur et un hauteur fixe.
En React, il n’y a pas de closing tag. Ca reprend la même philosophie que input et est plus consistent.
input type= checkbox
Il n’y pas de propriété value comme utilisé avec type text ou textarea. Il faut penser que sa propriété est checked ou pas. Cela veut dire que l’on va mettre un propriété checked:
Et ceci va faire entrer la notion d’une propriété Bolean. Donc checkbox maintiennent des valeurs booléennes dans state. Pour l’exemple, mettons:
Déclarons cette valeur dans state:
On remarque que la page ne nous permet pas de déchecké. Ceci est normal car nous avons mis la propriété à true par state. Pour pouvoir être en mesure de déchecker on va rajouter la propriété onChange et un name:
et mettons un peu en forme:
Maintenant la partie tricky: dans une input box on trace ce qui à été tapez. Rappelez vous dans le handleChange on traçait par value pour la mise à jour de state. Dans une check box il n’y a pas de value mais une propriété checked et cette propriété va retourner soit vraie ou false. Ce que nous aurons besoins pour maintenir notre handleChange, c’est savoir si notre élément de notre formulaire est une checkbox ou pas. Nous devrons tirer de event.target le type et checked:
Parce que une checkbox n’a pas value nous ne pourrons pas executer le code:
mais nous voudrons changer [name] qui est friendly et lui assigner la valeur checked:
Et là nous pouvons déchecker:
Pour enlever le warning pour textarea mettons aussi un handleChange:
select box
React heureusement maintient la propriété value par exemple si l’on veut une liste de notre couleur préférée:
La valeur que l’on choisira dans option sera transmise à state.favColor
Déclarons cette propriété dans state:
mettons aussi handleChange et name pour être sûr que ça coïncide avec notre propriété de state, les valeurs de options doivent être remplies:
et le résultat:
Ce qui cool avec react c’est que tout les éléments peuvent être activés par une seule fonction handlChange. Check box doit juste être testée avec une condition if (ou ? … : …).
Pour le summit button, html5 gère ça très bien: quand il trouve button dans un form il l’associera automatiquement à un summit button. Dès que l’utilisateur appuiera sur ce bouton l’événment onSumit du formulaire sera déclenché.
Voici le app.js:
import React, { Component } from "react"
class App extends Component {
constructor() {
super()
this.state = {
firstName: "",
lastName: "",
isFriendly: true,
gender: "",
favColor: "blue"
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const { name, value, type, checked } = event.target
type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value })
}
render() {
return (
<form>
<input
type="text"
value={this.state.firstName}
name="firstName"
placeholder="First Name"
onChange={this.handleChange} />
<br />
<input
type="text"
value={this.state.lastName}
name="lastName"
placeholder="Last Name"
onChange={this.handleChange} />
{
/**
* Othewr useful form elements:
*/
}
<textarea
value={"Some default value"}
onChange={this.handleChange}
/>
<br />
<label>
<input
type="checkbox"
name="isFriendly"
checked={this.state.isFriendly}
onChange={this.handleChange}
/> Is friendly?
</label>
<br />
<label>
<input
type="radio"
name="gender"
value="male"
checked={this.state.gender === "male"}
onChange={this.handleChange}
/> Male
</label>
<br />
<label>
<input
type="radio"
name="gender"
value="female"
checked={this.state.gender === "female"}
onChange={this.handleChange}
/> Female
</label>
{/*Formik*/}
<br />
<label>Favorite Color:</label>
<select value={this.state.favColor}
onChange={this.handleChange}
name="favColor"
>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="red">Red</option>
<option value="orange">Orange</option>
<option value="yellow">Yellow</option>
</select>
<h1>{this.state.firstName} {this.state.lastName}</h1>
<h2>You are a {this.state.gender}</h2>
<h2>Your favorite color is {this.state.favColor}</h2>
</form>
)
}
}
export default App
Forms Practice
Voici un exercice sur les Forms: la consigne se trouve à l’intérieur du fichier Apps.js
import React, { Component } from "react"
/**
* Challenge: Wire up the partially-finished travel form so that it works!
* Remember to use the concept of controlled forms
* https://reactjs.org/docs/forms.html
*
* All information should be populating the text below the form in real-time
* as you're filling it out
*
* This exercice is adapted from th V School curriculum on vanilla JS forms:
* https://coursework.vschool.io/travel-form/
*
* All of our challenges and learning ressources are opne for the public
* to play around with and learn from at https://coursework.vschool.io
*/
class App extends Component {
constructor() {
super()
this.state = {}
}
render() {
return (
<main>
<form>
<input placeholder="First Name" /><br />
<input placeholder="Last Name" /><br />
<input placeholder="Age" /><br />
{/* Create radio buttons for gender here */}
<br />
{/* Create select box for location here */}
<br />
{/* Create check boxes for dietary restrictions here */}
<br />
<button>Submit</button>
</form>
<hr />
<h2>Entered information:</h2>
<p>Your name: {/* First and last name here */}</p>
<p>Your age: {/* Age here */}</p>
<p>Your gender: {/* Gender here */}</p>
<p>Your destination: {/* Destination here */}</p>
<p>
Your dietary restrictions:
{/* Dietary restrictions here, comma separated */}
</p>
</main>
)
}
}
export default App
Il y plusieurs manières d’aborder cet exercice. Tout d’abord nous allons initialiser tout ce qu’il y a à l’intérieur de state:
Remarques:
La propriété age mettons-la à 0 pour l’instant. La location sera sous la propriété destination. Une check box pour dietaryRestrictions. Il y aura en fait plusieurs check boxes car on peut très bien être allergique à plusieurs ingrédients. C’est pourquoi nous l’initialiserons avec un tableau.
Maintenant que nous avons initialisé ce qu’il y a dans state, nous allons remplir les éléments existant dans les input donnée dans le fichier Apps.js faisant office de consigne.
Nous savons que nous aurons besoin d’une propriété name pour chaque input et d’une value déterminée par state (this.state.???). Chaque input sera aussi sujet au changement (onChange=…) qui appellera probablement handleChange. Attention les trois figures suivantes le nom de handChange a mal été orthographié, c’est en fait handleChange.
Pour plus de lisibilité mettons cela sur plusieurs lignes:
Attribuons maintenant à name les propriétés de state respectivement, complétons aussi this.state. … avec les mêmes noms:
Avant que nous poursuivons par rajouter des éléments, occupons-nous de handleChange et ne pas oublier le bind:
Descendons maintenant pour voir si ces trois inputs fonctionnenet correctement:
Jusque-là tout à l’air fonctionner mais essayer d’initialiser la propriété age à null et le navigateur grogne. Mettons la à un empty string est ça a l’air mieux.
Occupons-nous de notre gender, il est bien de le mettre entre un label. On se rappelle radio button possède une value, name et une propriété checked. Et celui-ci est un peu tricky lorsque celui-ci est male alors il sera checked.
Copions ce bribe de code pour female:
Parfait on peut sélectionner male ou female.
Mettons encore ceci à l’affichage de gender.
Occupons-nous de select box pour Destination.
select box contiendra 4 options car ce n’est pas une grande compagnie aérienne.
Chaque option prendra une propriété value. Les valeurs de nos options sont en fait les valeurs que state devrait être si une de ces options a été choisie. Ce sont en fait nos différentes locations. Mettons ces valeurs en minuscule pour que l’on soit consistent avec le reste. La valeur value de select est la valeur choisie. Et comme les autres, soyons sûr qu’il comporte un name qui match avec la propriété dans state. Et comme d’habitude onChange. Et dans la partie display on met la destination.
On remarque que Germany est affiché dans la liste par défault et que dans le display il ne s’affiche pas. Pour en fait sélectionner Germany il faudra d’abord sélectionner un autre pays et séléctionner Germany. Pour parer à ce défaut, on affichera par défault un autre texte:
Ok, nous avons gardé le plus difficile pour la fin et c’est nos checked box. Souvenons-nous lors de l’initialisation de nos propriété de state, nous avions mis un tableau vide pour dietaryRestrictions. En fait il sera plus facille de créer un sous objet et une valeur booléene pour chaque dietaryRestriction.
Nous aurons donc trois check boxes. Englobons check box dans un label. type sera à “checkbox”, name à la valeur de notre propriété de state comme isVegan, onChange l’événement déclenchant handleChange, checked qui sera égal à une propriété nested. Le text de label sera Vegan? Copions ceci et remplaçons avec les autres restrictions culinaires.
Vous noterez que nous ne sommes pas en mesure de checker ces
checkboxes. Les checkbox n’a pas de propriété value et handleChange ne
peut modifier que les propriétés value. Nous devons d’abord contrôler
si le type une checkbox, donc nous devons tirer de event: type et
checked. On ne peut pas simplement dire que [name]: checked, car
nous avons choisi d’avoir un nested object. Pour une raison que je ne
saurai expliquer le concept de nested object doit être oublié. Mais
peut être une piste pourquoi ça ne marche pas c’est peut-être dû au
fait que changer un nested object les autres propriété de state ne se
mettent pas à jour. Comme workaround nous allons supprimé notre
subobject : dietaryRestrictions. Et mettre chaque élément comme une
propriété de state.
et modifions encore:
et là ça a l’air de marcher:
Complétons encore le display:
On remarque que lorsque l’on coche restriction, React n’affiche pas de boléen.
On peut écrire le code suivant pour une bon affichage:
et le résultat final :
import React, { Component } from "react"
/**
* Challenge: Wire up the partially-finished travel form so that it works!
* Remember to use the concept of controlled forms
* https://reactjs.org/docs/forms.html
*
* All information should be populating the text below the form in real-time
* as you're filling it out
*
* This exercice is adapted from th V School curriculum on vanilla JS forms:
* https://coursework.vschool.io/travel-form/
*
* All of our challenges and learning ressources are opne for the public
* to play around with and learn from at https://coursework.vschool.io
*/
class App extends Component {
constructor() {
super()
this.state = {
firstName: "",
lastName: "",
age: "",
gender: "",
destination: "",
isVegan: false,
isKosher: false,
isLactoseFree: false
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const { name, value, type, checked } = event.target
type === "checkbox" ?
this.setState({
[name]: checked
})
:
this.setState({
[name]: value
})
}
render() {
return (
<main>
<form>
<input
name="firstName"
value={this.state.firstName}
onChange={this.handleChange}
placeholder="First Name"
/>
<br />
<input
name="lastName"
value={this.state.lastName}
onChange={this.handleChange}
placeholder="Last Name"
/>
<br />
<input
name="age"
value={this.state.age}
onChange={this.handleChange}
placeholder="Age"
/>
<br />
<label>
<input
type="radio"
name="gender"
value="male"
checked={this.state.gender === "male"}
onChange={this.handleChange}
/> Male
</label>
<br />
<label>
<input
type="radio"
name="gender"
value="female"
checked={this.state.gender === "female"}
onChange={this.handleChange}
/> Female
</label>
<br />
<select
value={this.state.destination}
name="destination"
onChange={this.handleChange}
>
<option value="">-- Please Choose a destination --</option>
<option value="germany">Germany</option>
<option value="norway">Norway</option>
<option value="north pole">North Pole</option>
<option value="south pole">South Pole</option>
</select>
<br />
<label>
<input
type="checkbox"
name="isVegan"
onChange={this.handleChange}
checked={this.state.isVegan}
/> Vegan?
</label>
<br />
<label>
<input
type="checkbox"
name="isKosher"
onChange={this.handleChange}
checked={this.state.isKosher}
/> Kosher?
</label>
<br />
<label>
<input
type="checkbox"
name="isLactoseFree"
onChange={this.handleChange}
checked={this.state.isLactoseFree}
/> Lactose Free?
</label>
<br />
<button>Submit</button>
</form>
<hr />
<h2>Entered information:</h2>
<p>Your name: {this.state.firstName} {this.state.lastName}</p>
<p>Your age: {this.state.age}</p>
<p>Your gender: {this.state.gender}</p>
<p>Your destination: {this.state.destination}</p>
<p>Your dietary restrictions:</p>
<p>Vegan : {this.state.isVegan ? "Yes" : "No"}</p>
<p>Kosher : {this.state.isKosher ? "Yes" : "No"}</p>
<p>Lactose Free : {this.state.isLactoseFree ? "Yes" : "No"}</p>
</main >
)
}
}
export default App
Container/Component Architecture
Notre exemple d’avant possède beaucoup de ligne et il est pas facile de trouver la bonne ligne. On voit qu’une partie s’occupe de la display logique en particulier ce qu’il y dans le render. Une autre partie contient les state et le business logique comme handleChange. Il serait très judicieux de segmenter notre code en partie comme la UI logique ou la rendering Logique et la Business logique qui en fait commande la rendering Logique. Le but c’est d’avoir un component qui maintient state et la méthode qui update state et un autre component dédié à UI logique ou presentation logique appelé presentational component. Qui aura la seule tache de recevoir props pour un affichage correcte.
Un petit lien pour lire:
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
Analysons maintenant le code vu précédemment. Tout notre code est maintenu dans un seul composant App. En réalité on veut que notre App render notre form et que form fasse tout les formy things. Créons un nouveau component appelé Form.js et copions tout le contenu de App.js dans Form.js. Changeons le nom App en Form et export default Form. Revenons dans App.js et importons Form. Comme Form s’occupe au rendu de notre formulaire on peut en faire un functional component.
Et l’on voit que notre app fonctionne toujours. On se rappelle que App est comme une table des matières comportant par exemple un header, main et un footer.
Pour l’instant nous avons tout dans Form. Nous allons créer un nouveau component appelé FormComponent.js Pour plus de consistence renommons Form.js en FormContainer.js et updatons App.js avec ce nom.
Dans le FormContainer coupons tout la render logique. Ensuite dans le component FormComponent rajoutons:
et copions en-dessous ce que nous avons coupé.
On remarque que l’app ne fonctionne plus c’est parce que nous avons coupé ce que qu’il y avait dans un class component dans un functionnal component.
Nous avons this.state.firstName et this.handleChange cette
functionnal component n’a pas de handleChange méthode et n’a pas de
state. En fait elle va recevoir tout par props. Nous reviendrons dans
une minute pour fixer cela.
Dans notre FormContainer nous avons maintenant un render() vide. Ce que nous allons faire c’est que FormContainer dedicate tout le UI stuff au FormComponent. Donc à l’entente nous allons importer FormComponent. Et render simplement <FormComponent />
Bien entendu nous devrons faire passer tout un tas de props. Mais déjà nous pouvons voir que la structure est devenue plus simple. Donc nous devons faire passer state et handleChange. Passons d’abord handleChange :
Maintenant dans le composant FormComponent partout où il y
this.handleChange nous devons le remplacer par
props.handleChange.
Pour state nous pourrions passez tout les propriétés par
firstName={this.state.firstName etc… mais cela va rajouter plein
de ligne à la suite de <FormComponent. Une autre option qui
s’offre à nous est d’utiliser un objet appelé data={this.state}
et modifions FormComponent:
remettons return() car nous l’avions couper dans FormContainer et rajouter dans FormComponent: import React
Et l’app refonctionne.
Voici le fichier App.js:
import React, { Component } from "react"
import FormContainer from "./FormContainer"
function App() {
return (
<FormContainer />
)
}
export default App
Voici le fichier FormContainer.js:
import React, { Component } from "react"
import FormComponent from "./FormComponent"
class FormContainer extends Component {
constructor() {
super()
this.state = {
firstName: "",
lastName: "",
age: "",
gender: "",
destination: "",
isVegan: false,
isKosher: false,
isLactoseFree: false
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const { name, value, type, checked } = event.target
type === "checkbox" ?
this.setState({
[name]: checked
})
:
this.setState({
[name]: value
})
}
render() {
return(
<FormComponent
handleChange={this.handleChange}
data={this.state}
/>
)
}
}
export default FormContainer
Voici le fichier FormComponent.js:
import React from "react"
function FormComponent(props) {
return (
<main>
<form>
<input
name="firstName"
value={props.data.firstName}
onChange={props.handleChange}
placeholder="First Name"
/>
<br />
<input
name="lastName"
value={props.data.lastName}
onChange={props.handleChange}
placeholder="Last Name"
/>
<br />
<input
name="age"
value={props.data.age}
onChange={props.handleChange}
placeholder="Age"
/>
<br />
<label>
<input
type="radio"
name="gender"
value="male"
checked={props.data.gender === "male"}
onChange={props.handleChange}
/> Male
</label>
<br />
<label>
<input
type="radio"
name="gender"
value="female"
checked={props.data.gender === "female"}
onChange={props.handleChange}
/> Female
</label>
<br />
<select
value={props.data.destination}
name="destination"
onChange={props.handleChange}
>
<option value="">-- Please Choose a destination --</option>
<option value="germany">Germany</option>
<option value="norway">Norway</option>
<option value="north pole">North Pole</option>
<option value="south pole">South Pole</option>
</select>
<br />
<label>
<input
type="checkbox"
name="isVegan"
onChange={props.handleChange}
checked={props.data.isVegan}
/> Vegan?
</label>
<br />
<label>
<input
type="checkbox"
name="isKosher"
onChange={props.handleChange}
checked={props.data.isKosher}
/> Kosher?
</label>
<br />
<label>
<input
type="checkbox"
name="isLactoseFree"
onChange={props.handleChange}
checked={props.data.isLactoseFree}
/> Lactose Free?
</label>
<br />
<button>Submit</button>
</form>
<hr />
<h2>Entered information:</h2>
<p>Your name: {props.data.firstName} {props.data.lastName}</p>
<p>Your age: {props.data.age}</p>
<p>Your gender: {props.data.gender}</p>
<p>Your destination: {props.data.destination}</p>
<p>Your dietary restrictions:</p>
<p>Vegan : {props.data.isVegan ? "Yes" : "No"}</p>
<p>Kosher : {props.data.isKosher ? "Yes" : "No"}</p>
<p>Lactose Free : {props.data.isLactoseFree ? "Yes" : "No"}</p>
</main >
)
}
export default FormComponent
Meme Generator Capstone Project
Create the boilerplate to get React to render something on the screen Render an <App /> component, which you’ll need to create separately
Voici le fichier index.js:
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
ReactDOM.render(<App />, document.getElementById("root"))
Voici le fichier App.js:
import React from "react"
function App() {
return (
<h1>Hello!</h1>
)
}
export default App
Create 2 new components - Header and MemeGenerator Header will only display things MemeGenerator will be calling to an API and holding on to data Each should be in their own file of the same name.
Commençons à changer le header:
Voilà c’est gentiment tout ce que l’on va apporter au component Header. On remarque qu’il est responsive.
Occupons-nous de MemeGenerator:
Initialize state to save the following data:
top text
bottom text
random image (initialize with “http://i.imgflip.com/1bij.jpg”)
We’ll be using an API that provides a bunch of meme images.
Your task: make an API call to “https://api.imgflip.com/get_memes” and save the data that comes back (response.data.memes) to a new state property called allMemeImgs. (The data that comes back is an array)
Parfait cela nous renvoit un objet avec plusieurs propriété. Celle qui va nous intéresser est l’url.
A la place de <h1>MEME GENERATOR SECTION</h1>, nous allons mettre un controlled form. Voici l’énoncé de l’exercice:
Create 2 input fields, one for the topText and one for the bottomText. Remember that these will be “controlled forms”, so make sure to add all the attributes you’ll need for that to work
Create the onChange handler method. It should update the corresponding state on every change of the input box.
Ne pas oublier le bind à placer dans constructor()
La prochaine étape est placé à un endroit notre meme. Rappeler nous recevons dans un tableau tout les meme que cet API possède. Et ce que nous allons implanté c’est que lorsque l’utilisateur appuie sur le bouton GEN, un meme est choisi au hasard. Pour l’afficher dans une air en dessous. Nous allons construire cette air maintenant.
Create a method that,when the “Gen” button is clicked, chooses one of the memes from our àllMemeImgs` array at random and makes it so that is the meme image that shows up in the bottom portion of our meme generator site.
On pourrait très bien mettre un onClick sur notre button, mais comme il est à l’intérieur d’un form, je préfère mettre un onSubmit sur le form.
Créons le handleSubmit avec even en paramètre because we don’t prevent the default parce que nous ne voulons pas toujours rafraîchir notre page. (j’ai rien compris mais bon…). N’oublions pas de binder cette nouvelle méthode. Décrivons les étapes de cette méthode:
get a random int (index in the array)
get the meme from that index
set randomImg to the .url of the random item
Et en cliquant sur GEN une image aléatoire s’affiche
Et les codes:
MemeGenerator.js:
import React, { Component } from "react"
class MemeGenerator extends Component {
constructor() {
super()
this.state = {
topText: "",
bottomText: "",
randomImg: "http://i.imgflip.com/1bij.jpg",
allMemeImgs: []
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const { memes } = response.data
this.setState({ allMemeImgs: memes })
})
}
handleChange(event) {
const { name, value } = event.target
this.setState({
[name]: value
})
}
handleSubmit(event) {
event.preventDefault()
const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length)
const randMemeImg = this.state.allMemeImgs[randNum].url
this.setState({ randomImg: randMemeImg })
}
render() {
return (
<div>
<form className="meme-form" onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.topText}
name="topText"
placeholder="Top Text"
onChange={this.handleChange}
/>
<input
type="text"
value={this.state.bottomText}
name="bottomText"
placeholder="Bottom Text"
onChange={this.handleChange}
/>
<button>Gen</button>
</form>
<div className="meme">
<img src={this.state.randomImg} alt="" />
<h2 className="top">{this.state.topText}</h2>
<h2 className="bottom">{this.state.bottomText}</h2>
</div>
</div>
)
}
}
export default MemeGenerator
Header.js:
import React from "react"
function Header() {
return (
<header>
<img
src="http://www.pngall.com/wp-content/uploads/2016/05/Trollface.png"
alt="Problem?"
/>
</header>
)
}
export default Header
style.css:
* {
box-sizing: border-box;
}
body {
margin: 0;
background-color: whitesmoke;
}
header {
height: 100px;
display: flex;
align-items: center;
background: #6441A5; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2a0845, #6441A5); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2a0845, #6441A5); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
header > img {
height: 80%;
margin-left: 10%;
}
header > p {
font-family: VT323, monospace;
color: whitesmoke;
font-size: 50px;
margin-left: 60px;
}
.meme {
position: relative;
width: 90%;
margin: auto;
}
.meme > img {
width: 100%;
}
.meme > h2 {
position: absolute;
width: 80%;
text-align: center;
left: 50%;
transform: translateX(-50%);
margin: 15px 0;
padding: 0 5px;
font-family: impact, sans-serif;
font-size: 2em;
text-transform: uppercase;
color: white;
letter-spacing: 1px;
text-shadow:
2px 2px 0 #000,
-2px -2px 0 #000,
2px -2px 0 #000,
-2px 2px 0 #000,
0 2px 0 #000,
2px 0 0 #000,
0 -2px 0 #000,
-2px 0 0 #000,
2px 2px 5px #000;
}
.meme > .bottom {
bottom: 0;
}
.meme > .top {
top: 0;
}
.meme-form {
width: 90%;
margin: 20px auto;
display: flex;
justify-content: space-between;
}
.meme-form > input {
width: 45%;
height: 40px;
}
.meme-form > button {
border: none;
font-family: VT323, monospace;
font-size: 25px;
letter-spacing: 1.5px;
color: white;
background: #6441A5;
}
.meme-form > input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
font-family: VT323, monospace;
font-size: 25px;
text-align: cen
}
.meme-form > input::-moz-placeholder { /* Firefox 19+ */
font-family: VT323, monospace;
font-size: 25px;
text-align: cen
}
.meme-form > input:-ms-input-placeholder { /* IE 10+ */
font-family: VT323, monospace;
font-size: 25px;
text-align: cen
}
.meme-form > input:-moz-placeholder { /* Firefox 18- */
font-family: VT323, monospace;
font-size: 25px;
text-align: cen
}
Writing Modern React Apps
Dans cette section nous allons voir comment écrire quelques lignes de façon plus moderne.
En fait on peut écrire nos méthodes de classe en arrow function: par exemple notre méthode handleChange: le changement à l’air très petit mais nous permet de supprimer le bind.
Aussi on peut créer directement des variables de classe. Sans que l’on ait à créer un constructor.
Voici quelques liens vers des nouveautés de React:
Official React Context API - https://reactjs.org/docs/context.html
Error Boundaries - https://reactjs.org/docs/error-boundaries.html
render props - https://reactjs.org/docs/render-props.html
Higher Order Components - https://reactjs.org/docs/higher-order-components.html
React Router - https://reacttraining.com/react-router/core/guides/philosophy
React Hooks - https://reactjs.org/docs/hooks-intro.html
React lazy, memo, and Suspense - https://reactjs.org/blog/2018/10/23/react-v-16-6.html
Smiley Face
source : https://www.youtube.com/watch?v=2LhoCfjm8R4&t=15506s
index.html
<!DOCTYPE html>
<html>
<head>
<title>Smiley Face Part I</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src="https://unpkg.com/react@16.9.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.9.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/d3@6.6.0/dist/d3.min.js"></script>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Face} from './Face'
const width = 960;
const height = 500;
const App = () => (
<Face
width = {width}
height = {height}
centerX = {width/2}
centerY = {height/2}
strokeWidth = {20}
eyeOffsetX = {100}
eyeOffsetY = {100}
eyeRadius = {40}
mouthWidth = {20}
mouthRadius = {140}
/>
);
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
Face.js
import {BackgroundCircle} from './BackgroundCircle'
import {Eyes} from './Eyes'
import {Mouth} from './Mouth'
import {FaceContainer} from './FaceContainer'
export const Face = ({
width,
height,
centerX,
centerY,
strokeWidth,
eyeOffsetX,
eyeOffsetY,
eyeRadius,
mouthWidth,
mouthRadius
}) => (
<FaceContainer
width={width}
height={height}
centerX={centerX}
centerY={centerY}
>
<BackgroundCircle
radius={centerY-strokeWidth/2}
strokeWidth={strokeWidth}
/>
<Eyes
eyeOffsetX={eyeOffsetX}
eyeOffsetY={eyeOffsetY}
eyeRadius={eyeRadius}
/>
<Mouth
mouthWidth={mouthWidth}
mouthRadius={mouthRadius}
/>
</FaceContainer>
);
FaceContainer.js
export const FaceContainer = ({children, width, height, centerX, centerY}) => (
<svg width={width} height={height}>
<g transform={`translate(${centerX},${centerY})`}>
{children}
</g>
</svg>
);
BackgroundCircle.js
export const BackgroundCircle = ({radius, strokeWidth}) => (
<circle
r={radius}
fill="yellow"
stroke="black"
stroke-width={strokeWidth}
/>
);
Eyes.js
export const Eyes = ({eyeOffsetX,eyeOffsetY,eyeRadius}) => (
<>
<circle
cx={-eyeOffsetX}
cy={-eyeOffsetY}
r={eyeRadius}
/>
<circle
cx={eyeOffsetX}
cy={-eyeOffsetY}
r={eyeRadius}
/>
</>
);
Mouth.js
import { arc } from 'd3';
export const Mouth = ({mouthWidth, mouthRadius}) => {
const mouthArc = arc()
.innerRadius(mouthRadius)
.outerRadius(mouthRadius + mouthWidth)
.startAngle(Math.PI / 2)
.endAngle(Math.PI * 3/2);
return <path d={mouthArc()}/>
};
Mouse Follower
A circle that follows a circle.
source : https://www.youtube.com/watch?v=2LhoCfjm8R4&t=15506s
index.html
<!DOCTYPE html>
<html>
<head>
<title>Mouse Follower</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src="https://unpkg.com/react@16.9.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.9.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/d3@5.11.0/dist/d3.min.js"></script>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
index.js
import React, {useState, useCallback} from 'react';
import ReactDOM from 'react-dom';
const width = 960;
const height = 500;
const circleRadius = 30;
const initialMousePosition = {x: width / 2, y: height / 2};
const App = () => {
const [mousePosition, setMousePosition]=useState(initialMousePosition);
const handleMouseMove = useCallback(event => {
const { clientX, clientY} = event;
setMousePosition({x: clientX, y: clientY})
},[setMousePosition]);
return (
<svg width={width} height={height} onMouseMove={handleMouseMove}>
<circle
cx={mousePosition.x}
cy={mousePosition.y}
r={circleRadius}
/>
</svg>
);
};
const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
Working with .xml
JavaScript Tip: Loading XML Data Using Fetch
https://www.youtube.com/watch?v=0gON4MUdJE8
JavaScript Question: How do I Work with XML Data?
Good videos to learn
2.3 HTTP Post Request with fetch() - Working with Data and APIs in JavaScript https://www.youtube.com/watch?v=Kw5tC5nQMRY&t=443s
2.4 Saving to a Database - Working with Data and APIs in JavaScript https://www.youtube.com/watch?v=xVYa20DCUv0
Read The Docs
Note
Nouveau: pour que Read The Docs puisse bien compiler il faut copier les trois fichiers .yaml, requirements.txt et conf.py depuis ce lien https://github.com/readthedocs/tutorial-template/tree/main
dans le répertoire windwaver (projet) on a le fichier readthedocs.yalm dont le contenu est le suivant:
dans le répertoire docs on a le fichier requirememts.txt dont le contenu est le suivant:
sphinx==7.1.2
sphinx-rtd-theme==1.3.0rc1
dans le répertoire source on a le fichier conf.py suivant: .. literalinclude:: /IT/sources/ReadTheDocs/conf.py
Ce tutoriel montre comment mettre en ligne un document fait avec ReStructureText en utilisant Read The Docs via Github.
Prérequis
Anaconda
un éditeur de texte (emacs)
un compte chez Github et l’installation sur PC (droits admin requis)
un compte chez Read The Docs (RTD)
Méthode
créer un répertoire avec comme nom le nom du projet dans cet exemple c’est
windwaverdans ce répertoire créer un répertoire nommé
docsouvrir Anaconda Prompt (pas le powershell)
se déplacer dans le répertoire
windwaver/docstapez:
sphinx-quickstart
répondre à la question Seperate source …
yComme ça les fichiersmake.batetMakefileseront seront séparés du répertoire_sourcesdans lequel seront nos fichiers (.rstet le fichierconfig.py)ouvrir le fichier
_sources/conf.pymodifier la ligne
html_theme = 'alabaster'parhtml_theme = 'sphinx_rtd_theme'ajouter la ligne suivante:
master_doc = 'index'sinon ça bug avec Read The Docscliquer-droite sur le répertoire
windwaveret choisir Git Basch Herelancer la commande:
git init
lancer la commande:
git config --global user.name 'Wind Waver'
lancer la commande:
git config --global user.email 'waverwind@gmail.com'
lancer la commande:
git add .
lancer la commande:
git status
lancer la commande:
git commit -m 'premier changement'
où
premier changementest le commentaire de la modificationsur https://github.com créer un nouveau répertoire et nommer le
windwavercopier et coller la commande (dans le MINGW64):
git remote add origin https://github.com/windwaver/windwaver.git
copier et coller la commande:
git push -u origin master
créer le fichier
READMEtouch README.md
décrire dans ce fichier le projet (à éditer dans emacs). Pour la mise en page c’est du Mark Down
lancer la commande suivante:
git add .
lancer:
git commit -m 'rajout de readme'
ensuite:
git push
sur https://readthedocs.org cliquer sur importer et faire un refresh
choisir le dossier
windwavercliquer sur build, cela va créer le site
éditer les différents fichiers
à chaque modification lancer les commandes suivante:
git add . git commit -m 'commentaire de la modification' git push
attendre quelques seconde et rafraichir le site avec
F5
Permission denied
Il arrive parfois après la commande push -u... que le message
suivant s’affiche:
Méthode pour réparer
Divers liens
GitHub
La branche master est la branche de production. C’est-à-dire que c’est la branche qui a la version qui tourne sans bug.
La branche dev est la branche de dévellopement c’est là que les contributeurs apportent leur dévelopement. (preProd)
Les branches des contributeurs sont celles où les personnes développent leur programmes pour ensuite les merger sur la branche dev (ici la branche du contributeur c’est devYDU)
Les branches hotfix sont les branches qui permettent de directement fixer des problèmes urgents sur la branche master.
.gitignore
On indique dans ce fichier les éléments qui ne doivent pas être
“pusher”. C’est souvent le résultat d’un programme comme par exemple
ce qui a dans le répertoire build
On indiquera dans ce fichier, les éléments qui devront être ignorés comme suit:
build/html
build/latex
Ici on ne voudra pas que les répertoire html et latex soient
“pusher””.
Déroulement
Merger et création des branches requises (mettre à jour son working repertory)
Voir d’abord les branches existantes:
Se mettre dans le working directory à l’aide du terminal ;
Faire un
git pull
git log--graph(tapez q pour quitter)ou taper
git guiet aller dans Repository -> Visualize All Branch HistorySi la branche dev et devYDU existent:
On synchronise ce qui a sur le server dans sont répertoire de travail, taper:
git pull(si pas déjà fait)Se déplacer dans la branche dev, taper:
git checkout 'dev'On merge se qui a dans la branche master dans la branche dev:
git merge 'master'(on se place dans répertoire cible et on précise le repertoire source à tirer vers soi, ici le répertoire source c’est master) Normalement la branche dev est à jour, mais si il existe des branches hotfix alors il faudra faire cette opération.Se déplacer dans la branche de devYDU, taper:
git checkout 'devYDU'On merge se qui a dans la branche dev dans sa branche perso:
git merge 'dev'(on se place dans répertoir cible et on précise le repertoire source à tirer vers soi, ici le répertoire source c’est dev)
Si les branches requises n’existent pas sur le serveur:
On synchronise ce qui a sur le server dans son répertoire de travail, taper:
git pullCréons notre branche perso en tapant:
git branch 'devYDU'Ceci va créer une branche en local.Ensuite on la met sur le server:
git pushcomme la branche n’existe pas encore git nous demande de lancer la commande suivante:git push --set-upstream origin devYDUSi besoin créer la branche dev:
git branch 'dev'Ceci va créer une branche en local.Ensuite on la met sur le server:
git pushcomme la branche n’existe pas encore git nous demande de lancer la commande suivante:git push --set-upstream origin devUne fois les branches requises créées, on fait les points de la liste de ci-dessus (Si la branche dev et devYDU existent)
Faire ses modifications dans la branche devYDU
Dès que les modifications ne présentent pas de bug, on va dire de prendre en compte les modifications à git, taper:
git add .git commit -m 'dire ce que l'on a changer'
On va poussez les changements de la branche devYDU au server:
git push;
Mise en preProd (merger nos changements dans la branche dev)
faire un
git pullau cas si la branche dev aurait subi des modifsSe déplacer dans la branche dev, taper:
git checkout 'dev'
git merge 'devYDU'On pousse la branche dev sur le serveur:
git push
Mise en prod (merger la branche dev dans la branche master)
Une fois que la branche dev a été testée et n’a pas de bug, il est temps de la merger dans la branche master
faire un
git pullau cas si la branche dev aurait subi des modifsSe déplacer dans la branche master, taper:
git checkout 'dev'
git merge 'dev'On pousse la branche master sur le serveur:
git push
Une bonne vidéo pour apprendre
Cliquer ici
Installation
Cliquer ici
Pour modifier un projet
créer un repertoire
clique-droite sur le répertoire et choisir
git bashgit init
git config --global user.name 'Wind Waver'
git config --global user.email 'waverwind@gmail.com'
git clone https://github.com/windwaver/windwaver.git
git pull
git remote add origin https://github.com/windwaver/windwaver.git
git push -u origin master
Petites applications
Cette section présente des petites applications ou outils permettant de faire des petites choses utiles.
GSview
Extraction d’une page d’un document pdf
ouvrir avec GSview
Fichier -> Convert
choisir la bonne page et mettre Type à pdfwrite.
BRISS
Cette application permet de rogner une figure pdf.
Touches racourcis :
l |
pour loader un fichier |
c |
pour rogner (crop) |
GIMP
Convertir une image en .eps
Fichier -> enregistrer sous
entrer le nom_fichier.eps
Convertir divers formats
Convertir pdf en png
Essayer PDF to PNG ici
Convertir .rst en .tex
Essayer pandoc ici
Conversions du son
CD -> mp3
Avec Ubuntu 12.04, j’utilise
asunder, c’est un bon programme car il extrait directement les métadonnées du CD.soundKonverter: on peut aussi utiliser ce programme. Astuce : copier/coller le contenu du CD sur le disque dur.
Extraire une bande son
Pour couper (extraire/éditer) une bande son :
Audacity
PLEX
Remote access
Caméra de surveillance
Enregistrement de la caméra sur mydlink
télécharger l’application sur windows
connecter avec le cable rj45
il ne faut pas activer le wifi tout faire avec le cable réseau
un fois que la caméra est visible avec l’app du smartphone
on peut activer le wifi de la caméra et entrer le mot de passe du réseau wifi
tester si en déconnectant le cable réseau, l’image est envoyée par le wifi
Paramétrer l’alerte par email
se connecter avec le cable réseau tjrs sur linux
il faut changer l’ip de linux en tapant :
sudo ifconfig eth0 192.168.0.1 netmask 255.255.255.0
on peut vérifier l’ip à tout moment en tapant
ip aon peut aussi vérifier tous les ip qui sont connecté sur le réseau local en tapantnmap -sn 192.168.1.0/24ouvrir firefox et se connecter à l’adresse 192.168.0.20
usr name : admin pwd: même que pour l’autre cam dl…
pour pouvoir être alarmé par email on ouvrira l’assistant de détection (wizard) il n’y a que par le wizard où l’on peut activer l’alerte par email en tout cas pour 5222L. Entrer les données comme suit: Password est celui de hotmail
Ne pas oublier d’indiquer la plage de détection on peut aussi le faire après-coups avec le smartphone.
