LaTeX : créer des formulaires PDF éditables

Une des fonctionnalités récentes apportées au format PDF est celle des formulaires éditables par l’utilisateur. Celle-ci lui permet ainsi de remplir un certain nombre de champs avant l’impression, directement depuis son viewer préféré. De plus, l’implantation des fonctions JavaScript sous Acrobat Reader étendent encore les possibilités de ces formulaires.

La création de formulaires PDF nous est tout simplement offerte par le classique package hyperref.

Exemple minimal

\documentclass{minimal}
\usepackage{hyperref}
 
\begin{document}
  \begin{Form}
    \TextField[name=name,width=10em]{Name:}
    \TextField[name=surname,width=10em]{Surname:}
 
    \medskip
    Hello there, I am \TextField[name=name]{} \TextField[name=surname]{}, glad to meet you!
  \end{Form}
\end{document}

Dans cet exemple, on commence par définir deux champs. On donne à chacun d’eux un nom et une largeur. Grâce à leurs noms, on peut donc répéter leur contenu autant de fois que nécessaire dans le formulaire, comme illustré sur la phrase d’après.

Autres types de champ

Dans l’exemple ci-dessus, on a utilisé un champ de texte éditable, mais on retrouve en fait les même types de champ qu’en HTML :

\ChoiceMenu[combo,name=country,default=France]{Country:}{Spain,Uganda,Moon,Other}

Cases d’option (ou « boutons radio »)

\ChoiceMenu[radio,default=Male,name=sex]{Sex:}{Male,Female}

Cases à cocher

\CheckBox[name=highschool]{High School}

 

Exécuter des actions entre les champs

Dans l’exemple de code minimal donné plus haut, on réutilise un champ en l’appelant par son nom, mais cette technique ne marche donc que si l’on souhaite le même type de champ. Grâce à l’utilisation de JavaScript dans le formulaire, il est possible d’extraire la valeur d’un champ pour l’utiliser dans un autre.

Affecter une valeur à un champ

Le plus simple pour cela est d’ajouter un bouton à notre formulaire, et d’utiliser une action onclick pour changer les valeurs des champs. Exemple avec des champs de type ChoiceMenu :

\begin{Form}
  \TextField[name=name,width=3cm,charsize=12pt]{Name:}
  \ChoiceMenu[combo,name=country,width=5cm,charsize=12pt,default=France]{Country:}
             {Spain,Uganda,Moon,Other=an Unknown country} \\
  \ChoiceMenu[radio,default=male,name=sex,charsize=14pt]{Sex:}{Male=male,Female=female}
  \PushButton[name=Remplissage,
              onclick={
                this.getField("sextxt").value= this.getField("sex").value;
                this.getField("countrytxt").value= this.getField("country").value;
                      }
              ]{Remplir}
 
In a word: \TextField[name=name,readonly=true]{} is a \TextField[name=sextxt,readonly=true]{} from \TextField[name=countrytxt,readonly=true]{}
\end{Form}

Ici, un premier formulaire demande des informations à l’utilisateur. Quand celui-ci clique sur le bouton « Remplir », les champs présents dans la phrase de résumé sont automatiquement remplis. Ces champs sont non éditables (option readonly). Vous noterez que j’ai donné de façon surabondante les valeurs possibles des champs éditables (ex : « Male=male »), ceci permet d’utiliser une valeur alternative à celle réellement affichée lors de la sélection (qui est donc celle à gauche du signe « = »).

Opérations mathématiques

Vous vous en doutez, JavaScript est assez malin pour permettre les opérations mathématiques entre différentes variables, qui peuvent être extraites des champs. Exemple ultra simple pour faire la moyenne de deux valeurs :

\begin{Form}
  \TextField[name=nb1,value=0]{Valeur numero 1}\\
  \TextField[name=nb2,value=0]{Valeur numero 2}\\
  \TextField[name=moy]{Moyenne des deux}\\
  \PushButton[name=go,
              onclick={var a = this.getField("nb1");var b=this.getField("nb2");
                       var moy=this.getField("moy");moy.value=(a.value+b.value)/2
                       }
              ]{Cliquez ici pour calculer}
\end{Form}

On utilise ici des variables intermédiaires pour stocker les valeurs des champs. Les paramètres « value » servent à imposer les valeurs par défaut.

Personnalisation des champs

Champs de texte

Par défaut, les champs de texte sont encadrés de rouge, ce qui est à mon sens loin d’être élégant. Pour virer ce truc, et en prime changer la police de saisie :

\TextField[name=prenom,value=Prenom,
           format={var f = this.getField('prenom');
                       f.strokeColor = ['T'];f.fillColor=['T'];
                       f.textFont ='Verdana'
                   },
            width=10em]{Pr\'{e}nom}

 Boutons radio

Là encore, le symbole par défaut n’est pas très conventionnel (une étoile). Si vous souhaitez un style plus académique (le même qu’en HTML) :

\ChoiceMenu[radio,radiosymbol=\ding{108},
           default=male,name=sex,charsize=14pt]
           {Sex:}{Male=male,Female=female}

Si vous souhaitez plus d’infos à ce propos, je vous invite à consulter cette page.

Compilation avec Babel en Français

Vous aurez noté que, JavaScript oblige, l’utilisation des point-virgules est plus que fréquente ici. Il faut donc « désactiver » temporairement ce caractère. On utilise donc la même méthode qu’avec TikZ :

\shorthandoff{;}
\begin{Form}
  % Notre formulaire en français, tranquille
\end{Form}
\shorthandon{;}

Débugage

S’il y a une erreur dans votre code JavaScript, ce n’est surement pdfLaTeX qui va vous le dire ! Sachez alors que dans les préférences d’Adobe Reader, onglet ‘JavaScript’, on peut activer le débogueur de scripts.

Pour aller plus loin

Vous pouvez bien entendu commencer par la documentation officielle de hyperref, mais elle manque un peu d’épaisseur à ce sujet. Je ne vais pas non plus vous faire un cours de JavaScript (je laisse ça au site du zéro), mais sachez qu’une page d’Adobe est spécialement dédiée à l’utilisation de JavaScript pour Acrobat.