<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Courtm</id>
	<title>LimeSurvey Manual - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.limesurvey.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Courtm"/>
	<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/Special:Contributions/Courtm"/>
	<updated>2026-08-11T13:12:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/12/fr&amp;diff=61315</id>
		<title>Translations:Survey participants/12/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/12/fr&amp;diff=61315"/>
		<updated>2014-04-06T22:20:50Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;File:token-menu2.png&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:token-menu2.png]]&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/3/fr&amp;diff=61314</id>
		<title>Translations:Survey participants/3/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/3/fr&amp;diff=61314"/>
		<updated>2014-04-06T22:19:29Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;=Introduction=&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61313</id>
		<title>Survey participants/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61313"/>
		<updated>2014-04-06T21:44:01Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; __TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Remarque&#039;&#039;&#039;:  Le système des invitations a beaucoup changé depuis la version 1.85 et versions ultérieures. Donc, si vous utilisez une version antérieure, il y aura des différences entre votre version et la documentation. Nous vous recommandons de mettre à niveau dès que possible.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
En de nombreuses occasions, vous voulez inviter un groupe de personnes pour participer à votre sondage, garder la trace des répondants ayant terminé le sondage, et vous assurer que chaque personne ne peut participer qu&#039;une seule fois. Le système des invitations vous permet d&#039;effectuer les opérations suivantes:&lt;br /&gt;
*Créez manuellement des invitations (nom, adresse email, ...)&lt;br /&gt;
*Importer une liste de noms et d&#039;adresses email pour les participants (à partir d&#039;un fichier CSV ou une interrogations LDAP)&lt;br /&gt;
*Ajouter / Supprimer des invitations&lt;br /&gt;
*Générer un numéro unique pour le jeton de chaque participant (code d&#039;invitation)&lt;br /&gt;
*Envoyez une invitation par courriel à chaque personne de votre liste, par groupe ou individuellement&lt;br /&gt;
*Envoyer un courriel de rappel à chaque personne de votre liste qui n&#039;a pas encore répondu, par groupe ou individuellement&lt;br /&gt;
*Suivi les répondants de votre liste qui ont répondu&lt;br /&gt;
*Interdire l&#039;accès aux personnes qui n&#039;ont pas de ceode d&#039;invitation, et ceux qui ont déjà répondu&lt;br /&gt;
*Modifier / changer tous les détails dans votre liste d&#039;invitation&lt;br /&gt;
&lt;br /&gt;
Une fois le questionnaire en accès restreint (vous avez activé les invitations pour ce questionnaire), alors &#039;&#039;&#039;seules les personnes avec une invitation valide (pas encore utilisée) peuvent accéder au questionnaire&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Si vous activez &#039;&#039;Permettre l&#039;enregistrement public ?&#039;&#039; dans les propriétés du questionnaire, les participants pourront s&#039;inscrire à votre sondage et avoir leur code d&#039;invitation personnel généré automatiquement.&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=Some token settings are set in survey settings, see [[Creating a new survey#Tokens]]}} &lt;br /&gt;
&lt;br /&gt;
==Est-ce qu&#039;une sondage utilisant les invitations peut assurer des réponses anonymes?==&lt;br /&gt;
&lt;br /&gt;
La réponse à cette question est &#039;&#039;&#039;Oui&#039;&#039;&#039;. Les invitations peuvent être utilisées tant pour les sondages anonymes que non anonymes. Ceci est déterminé lors de la création du questionnaire. Si un questionnaire n&#039;est pas anonyme (ou &#039;suivi&#039;) alors le code d&#039;invitation peut être utilisé pour trouver les réponses que le répondant a faites au questionnaire. Si le sondage est anonyme, alors aucun lien n&#039;est disponible entre la table des invitations et la table des réponses (techniquement: pas de relation de clé étrangère).&lt;br /&gt;
&lt;br /&gt;
=Comment activer les invitations ?=&lt;br /&gt;
&lt;br /&gt;
Il y a deux manières d&#039;activer les invitations:&lt;br /&gt;
#Juste après l&#039;activation du questionnaire, il vous sera demandé si vous souhaitez activer les invitations: {IMG(attId=&amp;quot;84&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
# &#039;&#039;&#039;Ou&#039;&#039;&#039; vous pouvez cliquer sur le symbole de gestion des invitations [[File:tokens.png]] - avant même que le sondage soit activé.&lt;br /&gt;
&lt;br /&gt;
=Les outils de contrôle des invitations=&lt;br /&gt;
&lt;br /&gt;
[[File:token-menu2.png]]&lt;br /&gt;
&lt;br /&gt;
Après la création de la table des invitations, vous pouvez cliquer sur l&#039;icône pour administrer les codes d&#039;invitation. Voici un bref aperçu des options de menu de l&#039;écran de gestion des invitations:&lt;br /&gt;
*&#039;&#039;&#039;Administration&#039;&#039;&#039;: Retourne à l&#039;écran d&#039;administration principal du questionnaire&lt;br /&gt;
*&#039;&#039;&#039;Résumé&#039;&#039;&#039;: Affiche un résumé des invitations de la table nombre de codes d&#039;invitation, nombre d&#039;invitation envoyée, et nombre de réponse. Permet également d&#039;accéder aux fonctions de d&#039;administration de la base de données voir ci-dessous. C&#039;est l&#039;écran par défaut.&lt;br /&gt;
*&#039;&#039;&#039;Parcourir&#039;&#039;&#039;: Affiche la liste complète des participants de la table des invitations. Depuis l&#039;écran d&#039;affichage, vous pouvez modifier ou supprimer des entrées individuelles dans la table ainsi qu&#039;un certain nombre d&#039;autres fonctions utiles voir la section Parcourir ci-dessous&lt;br /&gt;
*&#039;&#039;&#039;Ajouter une nouvelle invitation&#039;&#039;&#039;: Permet d&#039;ajouter une entrée à la table des invitations&lt;br /&gt;
*&#039;&#039;&#039;Ajouter des codes factices&#039;&#039;&#039;: Permet d&#039;ajouter une ou plusieurs codes d&#039;invitations à la table des invitations trèsb rapidement.&lt;br /&gt;
*&#039;&#039;&#039;Gérer les champs des attributs supplémentaire:&#039;&#039;&#039;: Permet d&#039;ajouter des champs supplémentaires à la table des invitations pour stocker des données personnalisées liés aux participants&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir d&#039;un CSV&#039;&#039;&#039;: Permet d&#039;importer les informations des invitations depuis un fichier CSV&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir de LDAP&#039;&#039;&#039;: Permet d&#039;importer les informations d&#039;une requête LDAP testé sur openLDAP, mais devrait fonctionner dans tous annuaire compatible LDAP, dont ActiveDirectory.&lt;br /&gt;
*&#039;&#039;&#039;Export les invitations vers un fichier CSV&#039;&#039;&#039;: Crée un fichier standard CSV (délimité par des virgules) avec la liste complète des participants de la table des invitations en cours.&lt;br /&gt;
*&#039;&#039;&#039;Éditer les modèles de courriel&#039;&#039;&#039;: Pour personnaliser les textes et contenus utilisés pour les invitations, les rappels, confirmations, et les courriels d&#039;inscription.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039;: Envoi global des invitations par courriel à tous les participants de la table des invitations qui n&#039;ont pas déjà reçu une invitation.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels de rappel&#039;&#039;&#039;: Envoi global des courriels de rappel à tous les participants ayant reçu une invitation et n&#039;ayant pas encore répondu.&lt;br /&gt;
*&#039;&#039;&#039;Générer les codes&#039;&#039;&#039;: Crée les codes d&#039;invitation uniques pour toutes les entrées individuelles de la table des invitations qui n&#039;en disposent pas encore.&lt;br /&gt;
*&#039;&#039;&#039;Effacer la tabe des inviations&#039;&#039;&#039;: Supprimer la table des invitations et passer le questionnaire en accès libre ou ouvert.&lt;br /&gt;
*&#039;&#039;&#039;Paramètres de rejet&#039;&#039;&#039;:  Paramètrage du courriel recevant les courriels de rejet. Ces paramètres peuvent être modifié à ce niveau ou au niveau général. Ce dispositif a été ajouté dans la version 1.91.&lt;br /&gt;
&lt;br /&gt;
=Modification et ajout d&#039;une invitation=&lt;br /&gt;
&lt;br /&gt;
Une entrée typique d&#039;invitation contient les champs suivants:&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;83&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039; : ... du participant (peut être utilisé dans les courriels et les questionnaires).&lt;br /&gt;
*&#039;&#039;&#039;Courriel&#039;&#039;&#039;: l&#039;adresse courriel du participant&lt;br /&gt;
*&#039;&#039;&#039;Statut du courriel&#039;&#039;&#039;: un champ pour conserver une trace des mauvaises adresses de courriels. Par exemple, si l&#039;administrateur du sondage ont reçu des notifications d&#039;erreur par courriel à partir de ce courriel, ce qu&#039;il peut définir ce champ à autre chose que &#039;OK&#039; (par exemple &#039;utilisateur inconnu&#039;, ou &#039;quota dépassé&#039;). Le marquage cette invitation avec un autre statut que &#039;OK&#039;, permettra d&#039;ignorer cette entrée lors de l&#039;envoi d&#039;invitation ou de couriel de rappel. Notez que ceci est entièrement manuel à moins vous décidez de mettre en place un script qui met à jour ce champ automatiquement.&lt;br /&gt;
*&#039;&#039;&#039;Code&#039;&#039;&#039;: c&#039;est le code de l&#039;invitation. Il est généralement généré automatiquement avec le bouton &#039;Générer les codes d&#039;invitations&#039;.&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: pour configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle l&#039;invitation a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Rappel envoyé?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le rappel a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Complété?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le questionnaire a était validé pour les questionnaire non anonyme ou Y pour les questionnaires anonyme.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois que le code d&#039;invitation peut être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; Valide jusqu&#039;à&#039;&#039;&#039; : Vous pouvez définir une plage de date/heure durant laquelle ce code d&#039;invitation pourra être utilisé. Vous pouvez laisser ces champs vides si vous ne souhaitez pas limiter les dates pour certains utilisateurs. Remarque: Si l&#039;utilisateur répond au questionnaire au moment ou la date arrive à échéance,  l&#039;invitation est verrouillé immédiatement, le répondant ne pourra pas terminer le sondage.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Ce sont les champs d&#039;attribut définissables par administrateur - voir ci dessous.&lt;br /&gt;
&lt;br /&gt;
=Codes factices=&lt;br /&gt;
&lt;br /&gt;
Le système des codes factices a été ajouté à partir de la version 1.91.&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;85&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Nombres de jetons&#039;&#039;&#039;:  Nombre de codes d&#039;invitations à ajouter. Par défaut à 100.&lt;br /&gt;
*&#039;&#039;&#039;Longueur du code&#039;&#039;&#039;: Nombre de caractères ou la longueur des codes d&#039;invitations. Par défaut à 15.&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039;: .. des participants.&lt;br /&gt;
*&#039;&#039;&#039;Couriel&#039;&#039;&#039;: l&#039;adresse de courriel des participants&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: Si vous voulez configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois ou le code pourra être utilisé&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; jusqu&#039;à&#039;&#039;&#039; :  la plage de date / l&#039;heure où les codes pourront être utilisés.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Champs d&#039;attribut définissables par l’administrateur&lt;br /&gt;
&lt;br /&gt;
Veuillez noter que le nom, l&#039;adresse de courriel, la langue seront fixés à la même valeur pour tous les codes factices.&lt;br /&gt;
&lt;br /&gt;
=Bounce Settings{{NewIn|1.91}}=&lt;br /&gt;
&lt;br /&gt;
Les paramètres de rejet ont été ajoutés à partir de la version 1.91&lt;br /&gt;
&lt;br /&gt;
[[File:surveyBounseSettings.png]]&lt;br /&gt;
*&#039;&#039;&#039;Survey bounce email&#039;&#039;&#039;:  A valid email address for return mail.   For faster bounce back processing, this email box should be limited to bounce back only.&lt;br /&gt;
*&#039;&#039;&#039;Bounce settings to be used&#039;&#039;&#039;: There are three options:  1- None (default) - no bounce back processing, 2- Use settings below - Will set bounce back processing at the survey level, or 3- Use global settings -- Settings based on the system level.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: Three options: 1- Off, 2- IMAP or 3- POP&lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;:  Host name and port number.   Port number isn&#039;t typically needed unless the email host uses a non-standard port. Example:  mail.example.net:25 or imap.gmail.com:995&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;:  User Name or User ID of the email account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;:  password of the email account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;:  Three options:  1- None (default), 2- SSL, or 3- TLS&lt;br /&gt;
&lt;br /&gt;
=Champs des attributs personnalisés=&lt;br /&gt;
&lt;br /&gt;
It is possible to add a number of additional fields to the tokens table to save additional data for a participant. By clicking on the [[File:token_manage.png]] icon you can manage these fields. You can add more attribute fields (by default they have a a length of 255 chars) and also set descriptions for each field - so they look nicer in the administration, when you browse tokens, when creating [[Setting conditions|conditions]] based on attribute fields or even when you export results for non-anonymous surveys.&lt;br /&gt;
&lt;br /&gt;
Il est possible d&#039;ajouter un certains nombre de champs supplémentaires à la table des invitations pour enregistrer des données supplémentaires concernant les participants. En cliquant sur l&#039;icône [[File:token_manage.png]], vous pouvez gérer ces champs. Vous pouvez ajouter des champs d&#039;attributs (par défaut, ils ont une longueur de 255 caractères) et des descriptions pour chaque champ - pour qu&#039;ils soient plus explicite dans l&#039;interface d&#039;administration, lorsque vous consultez la tables des invitations, ou loirs de conditions basées sur des attributs ou lorsque vous exportez un questionnaire non anonyme.&lt;br /&gt;
&lt;br /&gt;
=Utilisation de l&#039;écran d&#039;affichage des invitations et édition des réponses=&lt;br /&gt;
&lt;br /&gt;
L&#039;écran d&#039;affichage montre une liste de toutes les entrées de la table des invitations, ainsi que des boutons d&#039;action pour effectuer des t&amp;amp;acirc;ches spécifiques sur une entrée individuelle.&lt;br /&gt;
&lt;br /&gt;
La ligne du haut du tableau est composée de 3 parties: celle de droite permet de sélectionner le nombre de lignes affichées, ainsi que le point de départ; au centre un formulaire de recherche; les boutons sur le coté gauche permettent de naviguer dans la liste.&lt;br /&gt;
&lt;br /&gt;
La deuxième ligne de la table comprend le nom du champ, et une flèche verte qui - s&#039;il est cliqué - permet de trier par rapport à ce champs.&lt;br /&gt;
&lt;br /&gt;
La colonne &amp;quot;Actions&amp;quot; donne une liste de t&amp;amp;acirc;ches spécifiques qui peuvent être effectuées sur cette entrée individuelle:&lt;br /&gt;
&lt;br /&gt;
[[File:token-actions.png]]&lt;br /&gt;
*Lancer le questionnaire pour cette invitation&lt;br /&gt;
*Éditer cette invitation&lt;br /&gt;
*Supprimer cette invitation&lt;br /&gt;
*Envoyer un courriel d&#039;invitation ou de rappel à cette netrée&lt;br /&gt;
*Si le questionnaire est non-anonyme, un bouton supplémentaire apparait pour visualiser la réponse correspondante.&lt;br /&gt;
&lt;br /&gt;
=Administration de la base de donnée=&lt;br /&gt;
&lt;br /&gt;
[[File:token-summary.png]][[File:token-db-mgt.png]]&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;91&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
En plus d&#039;afficher un bref résumé de l&#039;état de votre table d&#039;invitation, l&#039;écran d&#039;accueil vous permet aussi d&#039;effectuer quelques manipulations sur cette table.&lt;br /&gt;
*&#039;&#039;&#039;Mettre toutes les invitations à &#039;Non envoyée&#039;&#039;&#039;&#039; Défini l&#039;ensemble des invitations à &amp;quot;Non envoyée&amp;quot; ( à &#039;N&#039; ). Ne devrait normalment ne pas être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer tous les codes uniques&#039;&#039;&#039;: Efface tous les codes des invitations, n&#039;efface que les codes, pas les invitations. Ne devrait pas être utilisé en situation normale.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer toutes les invitations&#039;&#039;&#039;: Supprime complétement la table d&#039;invitation. Ouvre le sondage aux personnes connaissant l&#039;adresse du questionnaire.&lt;br /&gt;
&lt;br /&gt;
= Import/export des inviations=&lt;br /&gt;
&lt;br /&gt;
== Import via un fichier CSV==&lt;br /&gt;
&lt;br /&gt;
L&#039;import se fait via cet écran&lt;br /&gt;
&lt;br /&gt;
[[File:uploadtoken.jpg]]&lt;br /&gt;
&lt;br /&gt;
Votre fichier CSV doit être à la norme des [http://fr.wikipedia.org/wiki/Comma-separated_values fichiers CSV (&#039;Comma Separated Value&#039;)] , c&#039;est à dire séparé par des virgule (,). La première ligne de texte est toujours l&#039;en-tête et sera utilisé pour identifier les colonnes de la table. Les champs de données possibles sont:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email,emailstatus,token,language code,tid,attribute_1,attribute_2, attribute_...&lt;br /&gt;
&lt;br /&gt;
Pour obtenir une liste complète des noms de champs de la table d&#039;invitation, vous pouvez exporter une table existante.&lt;br /&gt;
&lt;br /&gt;
Les champs peuvent être dans n&#039;importe quel ordre, mais les colonnes pour le nom, pour le prénom et pour le courriel sont obligatoires. Vous pouvez importer les champs supplémentaire des attributs au même moment.&lt;br /&gt;
&lt;br /&gt;
Un fichier CSV au strict minimum pourrait ressembler à ceci:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    John,Doe,john@doe.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Date format for token import&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The date format for the &amp;quot;validfrom&amp;quot; and &amp;quot;validuntil&amp;quot; fields in the CSV token inport file is &amp;quot;YYYY-MM-DD HH:MM&amp;quot;, e.g.:&lt;br /&gt;
&lt;br /&gt;
    2012-01-01 00:00&lt;br /&gt;
&lt;br /&gt;
--would correspond to 1st January, 2012, at 12:00 AM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filtering duplicates&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En activant l&#039;option pour filtrer les doublons, vous pouvez définir les champs qui sont utilisés pour identifier les doublons. Par défaut le &#039;Nom, Prénom et Adresse de Courriel&#039; sont présélectionnés. Si un doublon est trouvé lors de l&#039;importation de la ligne liée est omise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dépannage pour l&#039;import des invitations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A common error when users try to import tokens is an invalid CSV file. This is often caused by Microsoft Excel. Many users have a list of e-mail addresses saved as an XLS document. A file can be saved as CSV in Excel, however, depending on the locale of the OS Microsoft may use semi-colon (;) as the comma separator, while a standard CSV file uses comma (,) as the separator. If not sure just open the file with a standard text editor and check what separator was used. Starting in version 2.00 can you select the used separator during import.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aussi utiliser [http://fr.libreoffice.org/libreoffice/calc/ Libre Office Calc] pour importer votre fichier xls et exporter un fichier CSV au bon format.&lt;br /&gt;
&lt;br /&gt;
You can use [http://www.libreoffice.org/features/calc/ LibreOffice Calc] to export import your xls file and export your csv file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Add additional attributes at import&#039;&#039;&#039;&lt;br /&gt;
It is also possible to add new custom attributes when import a CSV file. It is still needed to define what attributes will be added. The way to do this is:&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    attribute_1 &amp;lt;Casenr&amp;gt;; token; attribute_2 &amp;lt;Title&amp;gt;; attribute_3 &amp;lt;destination&amp;gt;; lastname; firstname; attribute_4 &amp;lt;Sender&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
== Creating CSV file with Excel on the Mac==&lt;br /&gt;
&lt;br /&gt;
When you create a CSV file with Excel 2011 on the MAC and use the standard &amp;quot;save as&amp;quot; option, you loose special characters such as ü, &amp;amp;euml;, é etc. when importing into LimeSurvey Token Table.&lt;br /&gt;
&lt;br /&gt;
To make this work properly choose to save the file as a Windows text CSV file (tested on the Dutch version of Excel, saved as &amp;quot;Door lijstscheidingstekens gescheiden Windows tekst (.CSV)&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Then when importing the file in the LimeSurvey token table, under &amp;quot;character set of file&amp;quot; choose &amp;quot;Mac West European&amp;quot;. The special characters will be imported correctly.&lt;br /&gt;
&lt;br /&gt;
Testé seulement sur la version 2.0 de LimeSurvey&lt;br /&gt;
&lt;br /&gt;
== Export au format CSV ==&lt;br /&gt;
&lt;br /&gt;
Quand vous exporter votre table au format CSV, les champs sont exportés dans l&#039;ordre suivant:&lt;br /&gt;
&lt;br /&gt;
tid,prénom,nom,email,emailstatus,invitation,langue,code,attribut_1,attribut_2,...&lt;br /&gt;
&lt;br /&gt;
== Import depuis un annuaire LDAP ==&lt;br /&gt;
&lt;br /&gt;
[[File:token-Ldap-import.png]]&lt;br /&gt;
* Les requêtes sont définies manuellement par administrateur du système dans le fichier config-ldap.php&lt;br /&gt;
* Les doublons sont identifiés par le prénom, le nom et l&#039;adresse de courriel. Si un doublon est trouvé, lors de l&#039;importation la ligne concernée est omise, sauf si vous avez décoché la case de filtre des doublons.&lt;br /&gt;
&lt;br /&gt;
== Un truc pour générer un nombre important de fausses adresses de courriels==&lt;br /&gt;
&lt;br /&gt;
Quelquefois, vous pouvez avoir besoin d&#039;un grand nombre d&#039;adresses de courriel et d&#039;invitations. Vous pouvez utiliser les fonctions de votre tableur ( par exemple OpenOffice Calc) pour les fabriquer. Supposons que vous souhaitiez des milliers d&#039;adresses de courriel de la forme : 1@test.com, 2@test.com,3@test.com,... Vous aller entrer une liste consécutive de nombres dans la colonne A en indiquant à partir de la ligne 2 : =A1+1, ensuite copier/coller A2 autant de fois que vous le souhaitez. Dans la colonne B, en entête, vous indiquez email et à partir de B2: =A2&amp;amp;&amp;quot;@example.org&amp;quot;. Vous pouvez ensuite enregistrer ce fichier au format CSV et l&#039;importer dans votre table d&#039;invitation.&lt;br /&gt;
&lt;br /&gt;
Depuis la version 1.91, vous pouvez directement utiliser la génération automatique de code factices.&lt;br /&gt;
&lt;br /&gt;
== Une astuce pour générer un grand nombre de liens individuels incluant l&#039;invitation ==&lt;br /&gt;
&lt;br /&gt;
La structure du lien pour un sondage est la suivante :&lt;br /&gt;
&lt;br /&gt;
Limesurvey 1.x: http://url-vers-votre-installation-limesurvey/index.php?sid=XXXX&amp;amp;lang=fr&amp;amp;token={TOKEN}&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2.x: http://url-vers-votre-installation-limesurvey/index.php/survey/index/sid/xxxx/newtest/Y/lang/FR/token/{TOKEN}&lt;br /&gt;
&lt;br /&gt;
So you proceed similar to the example above for generating email adresses.&lt;br /&gt;
*First column: http://url-to-your-limesurvey-installation/index.php?sid=XXXX&amp;amp;lang=en&amp;amp;token= (for version 1.x) OR http://url-to-your-limesurvey-installation/index.php/survey/index/sid/xxxx/newtest/Y/lang/EN/token/ (for version 2.x) (same URL for all, as long as the language is the same!)&lt;br /&gt;
*Second column: {TOKEN} (put your tokens here, of course they must be individual)&lt;br /&gt;
*Third column: use the CONCATENATE function to join the first column with the second column.&lt;br /&gt;
&lt;br /&gt;
= L&#039;envoi des courriels=&lt;br /&gt;
&lt;br /&gt;
== Les champs réservés des courriels==&lt;br /&gt;
&lt;br /&gt;
Les textes suivants sont autorisés dans des modèles des courriels d&#039;invitation ou de rappel et sont saisi dans les propriétés du sondage. Lors de l&#039;envoi des courriels ces champ seront déjà remplacé dans l&#039;aperçu de votre invitation ou de votre courriel de rappel.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{ADMINEMAIL}||courriel de l&#039;adminsitrateur&lt;br /&gt;
|-&lt;br /&gt;
|{ADMINNAME}||Nom de l&#039;administrateur&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYNAME}||Titre du questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYDESCRIPTION}||Description du questionnaire&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les champs suivants sont aussi permis dans les courriels d&#039;invitation ou de rappel et seraont remplacé lors de l&#039;envoi du courriel&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYURL}||L&#039;adresse URL pour démarrer le questionnaire - en cas d&#039;envoi au format HTML, ce sera un lien HTML complet&lt;br /&gt;
|-&lt;br /&gt;
|@@SURVEYURL@@||L&#039;adresse URL pour démarrer le questionnaire au format texte - c&#039;est l&#039;adresse brute. Utilisable dans le corps HTML par exemple (disponible à partie de la version 1.90)&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_2}||Attribute 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If your survey is NOT anonymous, the following field names are available to insert token data in survey text and javascript. You can use these fields in confirmation and notification email template, too.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{TOKEN:EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_2}||Attribut 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Additional hints===&lt;br /&gt;
*If your survey is using anonymized responses then token-related placeholders will not work in notification email templates.&lt;br /&gt;
*You can use [[Expression Manager|Expression Manager]] to use expressions for tailoring an email{{NewIn|1.92}}. Please have a look at the [[Expression Manager HowTos|Expression Manager HowTos]] for an example.&lt;br /&gt;
Also have a look at the examples on using [[Adding a question#Information from tokens table|information from tokens table]].&lt;br /&gt;
&lt;br /&gt;
==Paramètres des courriels==&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;invitation :&#039;&#039;&#039;: La ligne du sujet de votre courriel d&#039;invitation en cas de table d&#039;invitation.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;invitation :&#039;&#039;&#039;: C&#039;est le texte du courriel d&#039;invitation qui sera envoyé. Il est par défaut rempli par un message d&#039;invitation par défaut ( provenant du fichier de langue). Vous pouvez utiliser les champs suivants pour insérer des informations personnalisées dans chaque courriel.&lt;br /&gt;
**&#039;&#039;&#039;{FIRSTNAME}&#039;&#039;&#039; - sera remplacé par le prénom&lt;br /&gt;
**&#039;&#039;&#039;{LASTNAME}&#039;&#039;&#039; - sera remplacé par le nom&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYNAME}&#039;&#039;&#039; - sera remplacé par le titre du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYDESCRIPTION}&#039;&#039;&#039; - sera remplacé par la description du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_1}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 1&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_2}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 2, etc ...&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse d&#039;accès au sondage en HTML&lt;br /&gt;
**&#039;&#039;&#039;@@SURVEYURL@@&#039;&#039;&#039; - sera remplacé par l&#039;adresse brute d&#039;accès au sondage (à partir de la v1.90)&lt;br /&gt;
**&#039;&#039;&#039;{OPTOUTURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse peremattant au répondant de se désinscrire (opt-out) du questionnaire&lt;br /&gt;
&lt;br /&gt;
Noter que ses champs reservés sont possible dans les champs des courriels suivant.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de rappel&#039;&#039;&#039;: Le sujet du courriel de rappel&lt;br /&gt;
#&#039;&#039;&#039;Courriel de rappel&#039;&#039;&#039;: Texte du contenu du courriel de rappel, éventuellement en HTML&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de confirmation&#039;&#039;&#039; Quand les invitations sont utilisée, un courriel de confirmation est envoyé au participant à la validation du questionnaire. C&#039;est ici le sujet de ce courriel.&lt;br /&gt;
#&#039;&#039;&#039;Courriel de confirmation&#039;&#039;&#039;: Le texte du courriel de confirmation. Effacer ce texte permet de ne pas envoyer de confirmation.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le sujet envoyé suite à une inscription sur un questionnaire.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le texte du courrier de confirmation envoyé suite à une inscription, il contient le nécessaire pour accède r directement au questionnaire.&lt;br /&gt;
&lt;br /&gt;
==Envoi des courriels==&lt;br /&gt;
&lt;br /&gt;
=== Envoyer les invitations===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;88&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ignorer les invitations pour lesquelles le statut du courriel est différent de &amp;quot;OK&amp;quot;, en choisissant &amp;quot;Sauter les invitations avec une adresse de courriel invalide&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Renvoyez une invitation====&lt;br /&gt;
&lt;br /&gt;
Quelquefois vous voulez renvoyer des courriels d&#039;invitation à certaines personnes. Quand vous utilisez &#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039; seules les personnes auxquelles vous n&#039;avez pas encore envoyé d&#039;invitation vont recevoir un courriel.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez donc renvoyer aussi des invitations à des utilisateurs en particulier en éditant leur invitation et en indiquant &#039;&#039;&#039;N&#039;&#039;&#039; dans la case &#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;, en remplaçant la date existante.&lt;br /&gt;
&lt;br /&gt;
==== Désinscription d&#039;un participant (opt-out)====&lt;br /&gt;
&lt;br /&gt;
Lorsque vous utilisez le tag { OPTOUTURL} dans votre courriel d&#039;invitation ou de rappel , vos participants ont la possibilité de se retirer de cette enquête en particulier en cliquant simplement sur cette adresse URL. Cela permet de ne pas harceler les utilisateurs avec des courriels de rappel. Un participant qui a opté de votre enquête aura &#039;Opt Out&#039; l&#039;état électronique indiquée dans le jeton.&lt;br /&gt;
&lt;br /&gt;
=== Envoi des rapppels===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;92&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Quand vous envoyez des rappels, vous pouvez:&lt;br /&gt;
*Passer les invitations avec une adresse invalide&lt;br /&gt;
*Passer les invitations pour laquelle un courriel a été &#039;récemment&#039; envoyé.&lt;br /&gt;
*Passer les invitations pour lequel un nombre donné de courriels ont déjà été envoyés.&lt;br /&gt;
&lt;br /&gt;
Note: A reminder will only be send to tokens where the &amp;quot;completed&amp;quot; field is not &amp;quot;N&amp;quot; (this means the respondent has either not taken or has not completed the survey).&lt;br /&gt;
&lt;br /&gt;
=== Envoi groupé de courriel===&lt;br /&gt;
&lt;br /&gt;
Quand vous avez un grand nombre de courriel à envoyer en même temps, LimeSurvey va limiter les envois par groupe de N courriel ( ceci est paramétrable dans les options générales, par défaut à 50)&lt;br /&gt;
&lt;br /&gt;
Vous devez cliquer sur suivant jusque ce que l&#039;ensemble des courriels soient envoyés.&lt;br /&gt;
&lt;br /&gt;
=== Courriel de confirmations===&lt;br /&gt;
&lt;br /&gt;
Quand vous utiliser les invitations, un courriel de confirmation lui est envoyé à la validation du questionnaire.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want this message to be sent, just deactivate this in the General survey settings.&lt;br /&gt;
&lt;br /&gt;
=== Spam problems===&lt;br /&gt;
&lt;br /&gt;
Often users complain not having received an invitation/reminder email because the user&amp;amp;rsquo;s spam filter treated the email as spam.&lt;br /&gt;
&lt;br /&gt;
If an email is treated as spam mostly depends on the spam filter being used and its settings. A spam filter usually checks the sender address and the email subject and content, so there are ways and means to influence how they treat your LimeSurvey invitation and reminder emails.&lt;br /&gt;
&lt;br /&gt;
At [http://www.limesurvey-consulting.com/how-to-prevent-limesurvey-email-invitations-or-reminders-being-treated-as-spam/ this blog post] on limesurvey-consulting.com a lot of possible issues and solutions are listed.&lt;br /&gt;
&lt;br /&gt;
===Wrong domain in invitation/reminder email link===&lt;br /&gt;
&lt;br /&gt;
LimeSurvey automatically tries to determine the URL for the invitation link by looking at the URL by which you logged in to the LimeSurvey administration. However with some server (mis-)configurations this might not work properly and you will have to set this manually.&lt;br /&gt;
&lt;br /&gt;
You can edit application/config/config.php to change the default base URL value. Add hostInfo property like this to the existing &#039;components&#039; array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;    &#039;components&#039; =&amp;gt; array(&lt;br /&gt;
       ...&lt;br /&gt;
       &#039;request&#039; =&amp;gt; array(&lt;br /&gt;
           &#039;hostInfo&#039; =&amp;gt; &#039;http://www.example.com&#039;,&lt;br /&gt;
       ),&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regarding the source of the problem: LimeSurvey tried to determine the domain from the server PHP variable $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;HTTP_HOST&#039;] or $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;SERVER_NAME&#039;].&lt;br /&gt;
&lt;br /&gt;
Some web server software do not properly seem to provide this information or are mis-configured.&lt;br /&gt;
&lt;br /&gt;
= Enregistrement public=&lt;br /&gt;
&lt;br /&gt;
==Permettre l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vouloir ouvrir votre questionnaire à tous mais avoir le système de contrôle utilisable avec les invitations. Ceci est possible : si vous initialiser la table des invitations et que vous choisissez OUI à Permettre l&#039;enregistrement public? dans les paramètres du questionnaire alors les répondants vont pouvoir s&#039;inscrire avant de répondre à votre questionnaire. Aprèsn s&#039;éêtre inscrit, il recevront une adresse URL pour remplir le questionnaire.&lt;br /&gt;
&lt;br /&gt;
Tous les codes d&#039;invitations provenant d&#039;un enregistrement public commence par la lettre R.&lt;br /&gt;
&lt;br /&gt;
==Les &#039;captchas&#039; dans l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Pour protéger votre sondage d&#039;inscription par des robits, il y a une fonction de &#039;captcha&#039; pour l&#039;enregistrement, la sauvegardez et le chargelent des questionnaires (à partir de la version 1.48). Cette fonctionnalité n&#039;est disponible que si vous avez le support GD d&#039;activé dans votre configuration de PHP (voir [[Installation|Prérequis d&#039;Installation]] ).&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/22/fr&amp;diff=61312</id>
		<title>Translations:Survey participants/22/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/22/fr&amp;diff=61312"/>
		<updated>2014-04-06T21:44:00Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Les paramètres de rejet ont été ajoutés à partir de la version 1.91&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61311</id>
		<title>Survey participants/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61311"/>
		<updated>2014-04-06T21:43:13Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; __TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Remarque&#039;&#039;&#039;:  Le système des invitations a beaucoup changé depuis la version 1.85 et versions ultérieures. Donc, si vous utilisez une version antérieure, il y aura des différences entre votre version et la documentation. Nous vous recommandons de mettre à niveau dès que possible.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
En de nombreuses occasions, vous voulez inviter un groupe de personnes pour participer à votre sondage, garder la trace des répondants ayant terminé le sondage, et vous assurer que chaque personne ne peut participer qu&#039;une seule fois. Le système des invitations vous permet d&#039;effectuer les opérations suivantes:&lt;br /&gt;
*Créez manuellement des invitations (nom, adresse email, ...)&lt;br /&gt;
*Importer une liste de noms et d&#039;adresses email pour les participants (à partir d&#039;un fichier CSV ou une interrogations LDAP)&lt;br /&gt;
*Ajouter / Supprimer des invitations&lt;br /&gt;
*Générer un numéro unique pour le jeton de chaque participant (code d&#039;invitation)&lt;br /&gt;
*Envoyez une invitation par courriel à chaque personne de votre liste, par groupe ou individuellement&lt;br /&gt;
*Envoyer un courriel de rappel à chaque personne de votre liste qui n&#039;a pas encore répondu, par groupe ou individuellement&lt;br /&gt;
*Suivi les répondants de votre liste qui ont répondu&lt;br /&gt;
*Interdire l&#039;accès aux personnes qui n&#039;ont pas de ceode d&#039;invitation, et ceux qui ont déjà répondu&lt;br /&gt;
*Modifier / changer tous les détails dans votre liste d&#039;invitation&lt;br /&gt;
&lt;br /&gt;
Une fois le questionnaire en accès restreint (vous avez activé les invitations pour ce questionnaire), alors &#039;&#039;&#039;seules les personnes avec une invitation valide (pas encore utilisée) peuvent accéder au questionnaire&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Si vous activez &#039;&#039;Permettre l&#039;enregistrement public ?&#039;&#039; dans les propriétés du questionnaire, les participants pourront s&#039;inscrire à votre sondage et avoir leur code d&#039;invitation personnel généré automatiquement.&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=Some token settings are set in survey settings, see [[Creating a new survey#Tokens]]}} &lt;br /&gt;
&lt;br /&gt;
==Est-ce qu&#039;une sondage utilisant les invitations peut assurer des réponses anonymes?==&lt;br /&gt;
&lt;br /&gt;
La réponse à cette question est &#039;&#039;&#039;Oui&#039;&#039;&#039;. Les invitations peuvent être utilisées tant pour les sondages anonymes que non anonymes. Ceci est déterminé lors de la création du questionnaire. Si un questionnaire n&#039;est pas anonyme (ou &#039;suivi&#039;) alors le code d&#039;invitation peut être utilisé pour trouver les réponses que le répondant a faites au questionnaire. Si le sondage est anonyme, alors aucun lien n&#039;est disponible entre la table des invitations et la table des réponses (techniquement: pas de relation de clé étrangère).&lt;br /&gt;
&lt;br /&gt;
=Comment activer les invitations ?=&lt;br /&gt;
&lt;br /&gt;
Il y a deux manières d&#039;activer les invitations:&lt;br /&gt;
#Juste après l&#039;activation du questionnaire, il vous sera demandé si vous souhaitez activer les invitations: {IMG(attId=&amp;quot;84&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
# &#039;&#039;&#039;Ou&#039;&#039;&#039; vous pouvez cliquer sur le symbole de gestion des invitations [[File:tokens.png]] - avant même que le sondage soit activé.&lt;br /&gt;
&lt;br /&gt;
=Les outils de contrôle des invitations=&lt;br /&gt;
&lt;br /&gt;
[[File:token-menu2.png]]&lt;br /&gt;
&lt;br /&gt;
Après la création de la table des invitations, vous pouvez cliquer sur l&#039;icône pour administrer les codes d&#039;invitation. Voici un bref aperçu des options de menu de l&#039;écran de gestion des invitations:&lt;br /&gt;
*&#039;&#039;&#039;Administration&#039;&#039;&#039;: Retourne à l&#039;écran d&#039;administration principal du questionnaire&lt;br /&gt;
*&#039;&#039;&#039;Résumé&#039;&#039;&#039;: Affiche un résumé des invitations de la table nombre de codes d&#039;invitation, nombre d&#039;invitation envoyée, et nombre de réponse. Permet également d&#039;accéder aux fonctions de d&#039;administration de la base de données voir ci-dessous. C&#039;est l&#039;écran par défaut.&lt;br /&gt;
*&#039;&#039;&#039;Parcourir&#039;&#039;&#039;: Affiche la liste complète des participants de la table des invitations. Depuis l&#039;écran d&#039;affichage, vous pouvez modifier ou supprimer des entrées individuelles dans la table ainsi qu&#039;un certain nombre d&#039;autres fonctions utiles voir la section Parcourir ci-dessous&lt;br /&gt;
*&#039;&#039;&#039;Ajouter une nouvelle invitation&#039;&#039;&#039;: Permet d&#039;ajouter une entrée à la table des invitations&lt;br /&gt;
*&#039;&#039;&#039;Ajouter des codes factices&#039;&#039;&#039;: Permet d&#039;ajouter une ou plusieurs codes d&#039;invitations à la table des invitations trèsb rapidement.&lt;br /&gt;
*&#039;&#039;&#039;Gérer les champs des attributs supplémentaire:&#039;&#039;&#039;: Permet d&#039;ajouter des champs supplémentaires à la table des invitations pour stocker des données personnalisées liés aux participants&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir d&#039;un CSV&#039;&#039;&#039;: Permet d&#039;importer les informations des invitations depuis un fichier CSV&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir de LDAP&#039;&#039;&#039;: Permet d&#039;importer les informations d&#039;une requête LDAP testé sur openLDAP, mais devrait fonctionner dans tous annuaire compatible LDAP, dont ActiveDirectory.&lt;br /&gt;
*&#039;&#039;&#039;Export les invitations vers un fichier CSV&#039;&#039;&#039;: Crée un fichier standard CSV (délimité par des virgules) avec la liste complète des participants de la table des invitations en cours.&lt;br /&gt;
*&#039;&#039;&#039;Éditer les modèles de courriel&#039;&#039;&#039;: Pour personnaliser les textes et contenus utilisés pour les invitations, les rappels, confirmations, et les courriels d&#039;inscription.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039;: Envoi global des invitations par courriel à tous les participants de la table des invitations qui n&#039;ont pas déjà reçu une invitation.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels de rappel&#039;&#039;&#039;: Envoi global des courriels de rappel à tous les participants ayant reçu une invitation et n&#039;ayant pas encore répondu.&lt;br /&gt;
*&#039;&#039;&#039;Générer les codes&#039;&#039;&#039;: Crée les codes d&#039;invitation uniques pour toutes les entrées individuelles de la table des invitations qui n&#039;en disposent pas encore.&lt;br /&gt;
*&#039;&#039;&#039;Effacer la tabe des inviations&#039;&#039;&#039;: Supprimer la table des invitations et passer le questionnaire en accès libre ou ouvert.&lt;br /&gt;
*&#039;&#039;&#039;Paramètres de rejet&#039;&#039;&#039;:  Paramètrage du courriel recevant les courriels de rejet. Ces paramètres peuvent être modifié à ce niveau ou au niveau général. Ce dispositif a été ajouté dans la version 1.91.&lt;br /&gt;
&lt;br /&gt;
=Modification et ajout d&#039;une invitation=&lt;br /&gt;
&lt;br /&gt;
Une entrée typique d&#039;invitation contient les champs suivants:&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;83&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039; : ... du participant (peut être utilisé dans les courriels et les questionnaires).&lt;br /&gt;
*&#039;&#039;&#039;Courriel&#039;&#039;&#039;: l&#039;adresse courriel du participant&lt;br /&gt;
*&#039;&#039;&#039;Statut du courriel&#039;&#039;&#039;: un champ pour conserver une trace des mauvaises adresses de courriels. Par exemple, si l&#039;administrateur du sondage ont reçu des notifications d&#039;erreur par courriel à partir de ce courriel, ce qu&#039;il peut définir ce champ à autre chose que &#039;OK&#039; (par exemple &#039;utilisateur inconnu&#039;, ou &#039;quota dépassé&#039;). Le marquage cette invitation avec un autre statut que &#039;OK&#039;, permettra d&#039;ignorer cette entrée lors de l&#039;envoi d&#039;invitation ou de couriel de rappel. Notez que ceci est entièrement manuel à moins vous décidez de mettre en place un script qui met à jour ce champ automatiquement.&lt;br /&gt;
*&#039;&#039;&#039;Code&#039;&#039;&#039;: c&#039;est le code de l&#039;invitation. Il est généralement généré automatiquement avec le bouton &#039;Générer les codes d&#039;invitations&#039;.&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: pour configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle l&#039;invitation a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Rappel envoyé?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le rappel a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Complété?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le questionnaire a était validé pour les questionnaire non anonyme ou Y pour les questionnaires anonyme.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois que le code d&#039;invitation peut être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; Valide jusqu&#039;à&#039;&#039;&#039; : Vous pouvez définir une plage de date/heure durant laquelle ce code d&#039;invitation pourra être utilisé. Vous pouvez laisser ces champs vides si vous ne souhaitez pas limiter les dates pour certains utilisateurs. Remarque: Si l&#039;utilisateur répond au questionnaire au moment ou la date arrive à échéance,  l&#039;invitation est verrouillé immédiatement, le répondant ne pourra pas terminer le sondage.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Ce sont les champs d&#039;attribut définissables par administrateur - voir ci dessous.&lt;br /&gt;
&lt;br /&gt;
=Codes factices=&lt;br /&gt;
&lt;br /&gt;
Le système des codes factices a été ajouté à partir de la version 1.91.&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;85&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Nombres de jetons&#039;&#039;&#039;:  Nombre de codes d&#039;invitations à ajouter. Par défaut à 100.&lt;br /&gt;
*&#039;&#039;&#039;Longueur du code&#039;&#039;&#039;: Nombre de caractères ou la longueur des codes d&#039;invitations. Par défaut à 15.&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039;: .. des participants.&lt;br /&gt;
*&#039;&#039;&#039;Couriel&#039;&#039;&#039;: l&#039;adresse de courriel des participants&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: Si vous voulez configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois ou le code pourra être utilisé&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; jusqu&#039;à&#039;&#039;&#039; :  la plage de date / l&#039;heure où les codes pourront être utilisés.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Champs d&#039;attribut définissables par l’administrateur&lt;br /&gt;
&lt;br /&gt;
Veuillez noter que le nom, l&#039;adresse de courriel, la langue seront fixés à la même valeur pour tous les codes factices.&lt;br /&gt;
&lt;br /&gt;
=Bounce Settings{{NewIn|1.91}}=&lt;br /&gt;
&lt;br /&gt;
Please also check out the [[Email bounce tracking system]] page for more information how to correctly configure this feature.&lt;br /&gt;
&lt;br /&gt;
[[File:surveyBounseSettings.png]]&lt;br /&gt;
*&#039;&#039;&#039;Survey bounce email&#039;&#039;&#039;:  A valid email address for return mail.   For faster bounce back processing, this email box should be limited to bounce back only.&lt;br /&gt;
*&#039;&#039;&#039;Bounce settings to be used&#039;&#039;&#039;: There are three options:  1- None (default) - no bounce back processing, 2- Use settings below - Will set bounce back processing at the survey level, or 3- Use global settings -- Settings based on the system level.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: Three options: 1- Off, 2- IMAP or 3- POP&lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;:  Host name and port number.   Port number isn&#039;t typically needed unless the email host uses a non-standard port. Example:  mail.example.net:25 or imap.gmail.com:995&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;:  User Name or User ID of the email account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;:  password of the email account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;:  Three options:  1- None (default), 2- SSL, or 3- TLS&lt;br /&gt;
&lt;br /&gt;
=Champs des attributs personnalisés=&lt;br /&gt;
&lt;br /&gt;
It is possible to add a number of additional fields to the tokens table to save additional data for a participant. By clicking on the [[File:token_manage.png]] icon you can manage these fields. You can add more attribute fields (by default they have a a length of 255 chars) and also set descriptions for each field - so they look nicer in the administration, when you browse tokens, when creating [[Setting conditions|conditions]] based on attribute fields or even when you export results for non-anonymous surveys.&lt;br /&gt;
&lt;br /&gt;
Il est possible d&#039;ajouter un certains nombre de champs supplémentaires à la table des invitations pour enregistrer des données supplémentaires concernant les participants. En cliquant sur l&#039;icône [[File:token_manage.png]], vous pouvez gérer ces champs. Vous pouvez ajouter des champs d&#039;attributs (par défaut, ils ont une longueur de 255 caractères) et des descriptions pour chaque champ - pour qu&#039;ils soient plus explicite dans l&#039;interface d&#039;administration, lorsque vous consultez la tables des invitations, ou loirs de conditions basées sur des attributs ou lorsque vous exportez un questionnaire non anonyme.&lt;br /&gt;
&lt;br /&gt;
=Utilisation de l&#039;écran d&#039;affichage des invitations et édition des réponses=&lt;br /&gt;
&lt;br /&gt;
L&#039;écran d&#039;affichage montre une liste de toutes les entrées de la table des invitations, ainsi que des boutons d&#039;action pour effectuer des t&amp;amp;acirc;ches spécifiques sur une entrée individuelle.&lt;br /&gt;
&lt;br /&gt;
La ligne du haut du tableau est composée de 3 parties: celle de droite permet de sélectionner le nombre de lignes affichées, ainsi que le point de départ; au centre un formulaire de recherche; les boutons sur le coté gauche permettent de naviguer dans la liste.&lt;br /&gt;
&lt;br /&gt;
La deuxième ligne de la table comprend le nom du champ, et une flèche verte qui - s&#039;il est cliqué - permet de trier par rapport à ce champs.&lt;br /&gt;
&lt;br /&gt;
La colonne &amp;quot;Actions&amp;quot; donne une liste de t&amp;amp;acirc;ches spécifiques qui peuvent être effectuées sur cette entrée individuelle:&lt;br /&gt;
&lt;br /&gt;
[[File:token-actions.png]]&lt;br /&gt;
*Lancer le questionnaire pour cette invitation&lt;br /&gt;
*Éditer cette invitation&lt;br /&gt;
*Supprimer cette invitation&lt;br /&gt;
*Envoyer un courriel d&#039;invitation ou de rappel à cette netrée&lt;br /&gt;
*Si le questionnaire est non-anonyme, un bouton supplémentaire apparait pour visualiser la réponse correspondante.&lt;br /&gt;
&lt;br /&gt;
=Administration de la base de donnée=&lt;br /&gt;
&lt;br /&gt;
[[File:token-summary.png]][[File:token-db-mgt.png]]&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;91&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
En plus d&#039;afficher un bref résumé de l&#039;état de votre table d&#039;invitation, l&#039;écran d&#039;accueil vous permet aussi d&#039;effectuer quelques manipulations sur cette table.&lt;br /&gt;
*&#039;&#039;&#039;Mettre toutes les invitations à &#039;Non envoyée&#039;&#039;&#039;&#039; Défini l&#039;ensemble des invitations à &amp;quot;Non envoyée&amp;quot; ( à &#039;N&#039; ). Ne devrait normalment ne pas être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer tous les codes uniques&#039;&#039;&#039;: Efface tous les codes des invitations, n&#039;efface que les codes, pas les invitations. Ne devrait pas être utilisé en situation normale.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer toutes les invitations&#039;&#039;&#039;: Supprime complétement la table d&#039;invitation. Ouvre le sondage aux personnes connaissant l&#039;adresse du questionnaire.&lt;br /&gt;
&lt;br /&gt;
= Import/export des inviations=&lt;br /&gt;
&lt;br /&gt;
== Import via un fichier CSV==&lt;br /&gt;
&lt;br /&gt;
L&#039;import se fait via cet écran&lt;br /&gt;
&lt;br /&gt;
[[File:uploadtoken.jpg]]&lt;br /&gt;
&lt;br /&gt;
Votre fichier CSV doit être à la norme des [http://fr.wikipedia.org/wiki/Comma-separated_values fichiers CSV (&#039;Comma Separated Value&#039;)] , c&#039;est à dire séparé par des virgule (,). La première ligne de texte est toujours l&#039;en-tête et sera utilisé pour identifier les colonnes de la table. Les champs de données possibles sont:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email,emailstatus,token,language code,tid,attribute_1,attribute_2, attribute_...&lt;br /&gt;
&lt;br /&gt;
Pour obtenir une liste complète des noms de champs de la table d&#039;invitation, vous pouvez exporter une table existante.&lt;br /&gt;
&lt;br /&gt;
Les champs peuvent être dans n&#039;importe quel ordre, mais les colonnes pour le nom, pour le prénom et pour le courriel sont obligatoires. Vous pouvez importer les champs supplémentaire des attributs au même moment.&lt;br /&gt;
&lt;br /&gt;
Un fichier CSV au strict minimum pourrait ressembler à ceci:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    John,Doe,john@doe.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Date format for token import&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The date format for the &amp;quot;validfrom&amp;quot; and &amp;quot;validuntil&amp;quot; fields in the CSV token inport file is &amp;quot;YYYY-MM-DD HH:MM&amp;quot;, e.g.:&lt;br /&gt;
&lt;br /&gt;
    2012-01-01 00:00&lt;br /&gt;
&lt;br /&gt;
--would correspond to 1st January, 2012, at 12:00 AM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filtering duplicates&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En activant l&#039;option pour filtrer les doublons, vous pouvez définir les champs qui sont utilisés pour identifier les doublons. Par défaut le &#039;Nom, Prénom et Adresse de Courriel&#039; sont présélectionnés. Si un doublon est trouvé lors de l&#039;importation de la ligne liée est omise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dépannage pour l&#039;import des invitations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A common error when users try to import tokens is an invalid CSV file. This is often caused by Microsoft Excel. Many users have a list of e-mail addresses saved as an XLS document. A file can be saved as CSV in Excel, however, depending on the locale of the OS Microsoft may use semi-colon (;) as the comma separator, while a standard CSV file uses comma (,) as the separator. If not sure just open the file with a standard text editor and check what separator was used. Starting in version 2.00 can you select the used separator during import.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aussi utiliser [http://fr.libreoffice.org/libreoffice/calc/ Libre Office Calc] pour importer votre fichier xls et exporter un fichier CSV au bon format.&lt;br /&gt;
&lt;br /&gt;
You can use [http://www.libreoffice.org/features/calc/ LibreOffice Calc] to export import your xls file and export your csv file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Add additional attributes at import&#039;&#039;&#039;&lt;br /&gt;
It is also possible to add new custom attributes when import a CSV file. It is still needed to define what attributes will be added. The way to do this is:&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    attribute_1 &amp;lt;Casenr&amp;gt;; token; attribute_2 &amp;lt;Title&amp;gt;; attribute_3 &amp;lt;destination&amp;gt;; lastname; firstname; attribute_4 &amp;lt;Sender&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
== Creating CSV file with Excel on the Mac==&lt;br /&gt;
&lt;br /&gt;
When you create a CSV file with Excel 2011 on the MAC and use the standard &amp;quot;save as&amp;quot; option, you loose special characters such as ü, &amp;amp;euml;, é etc. when importing into LimeSurvey Token Table.&lt;br /&gt;
&lt;br /&gt;
To make this work properly choose to save the file as a Windows text CSV file (tested on the Dutch version of Excel, saved as &amp;quot;Door lijstscheidingstekens gescheiden Windows tekst (.CSV)&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Then when importing the file in the LimeSurvey token table, under &amp;quot;character set of file&amp;quot; choose &amp;quot;Mac West European&amp;quot;. The special characters will be imported correctly.&lt;br /&gt;
&lt;br /&gt;
Testé seulement sur la version 2.0 de LimeSurvey&lt;br /&gt;
&lt;br /&gt;
== Export au format CSV ==&lt;br /&gt;
&lt;br /&gt;
Quand vous exporter votre table au format CSV, les champs sont exportés dans l&#039;ordre suivant:&lt;br /&gt;
&lt;br /&gt;
tid,prénom,nom,email,emailstatus,invitation,langue,code,attribut_1,attribut_2,...&lt;br /&gt;
&lt;br /&gt;
== Import depuis un annuaire LDAP ==&lt;br /&gt;
&lt;br /&gt;
[[File:token-Ldap-import.png]]&lt;br /&gt;
* Les requêtes sont définies manuellement par administrateur du système dans le fichier config-ldap.php&lt;br /&gt;
* Les doublons sont identifiés par le prénom, le nom et l&#039;adresse de courriel. Si un doublon est trouvé, lors de l&#039;importation la ligne concernée est omise, sauf si vous avez décoché la case de filtre des doublons.&lt;br /&gt;
&lt;br /&gt;
== Un truc pour générer un nombre important de fausses adresses de courriels==&lt;br /&gt;
&lt;br /&gt;
Quelquefois, vous pouvez avoir besoin d&#039;un grand nombre d&#039;adresses de courriel et d&#039;invitations. Vous pouvez utiliser les fonctions de votre tableur ( par exemple OpenOffice Calc) pour les fabriquer. Supposons que vous souhaitiez des milliers d&#039;adresses de courriel de la forme : 1@test.com, 2@test.com,3@test.com,... Vous aller entrer une liste consécutive de nombres dans la colonne A en indiquant à partir de la ligne 2 : =A1+1, ensuite copier/coller A2 autant de fois que vous le souhaitez. Dans la colonne B, en entête, vous indiquez email et à partir de B2: =A2&amp;amp;&amp;quot;@example.org&amp;quot;. Vous pouvez ensuite enregistrer ce fichier au format CSV et l&#039;importer dans votre table d&#039;invitation.&lt;br /&gt;
&lt;br /&gt;
Depuis la version 1.91, vous pouvez directement utiliser la génération automatique de code factices.&lt;br /&gt;
&lt;br /&gt;
== Une astuce pour générer un grand nombre de liens individuels incluant l&#039;invitation ==&lt;br /&gt;
&lt;br /&gt;
La structure du lien pour un sondage est la suivante :&lt;br /&gt;
&lt;br /&gt;
Limesurvey 1.x: http://url-vers-votre-installation-limesurvey/index.php?sid=XXXX&amp;amp;lang=fr&amp;amp;token={TOKEN}&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2.x: http://url-vers-votre-installation-limesurvey/index.php/survey/index/sid/xxxx/newtest/Y/lang/FR/token/{TOKEN}&lt;br /&gt;
&lt;br /&gt;
So you proceed similar to the example above for generating email adresses.&lt;br /&gt;
*First column: http://url-to-your-limesurvey-installation/index.php?sid=XXXX&amp;amp;lang=en&amp;amp;token= (for version 1.x) OR http://url-to-your-limesurvey-installation/index.php/survey/index/sid/xxxx/newtest/Y/lang/EN/token/ (for version 2.x) (same URL for all, as long as the language is the same!)&lt;br /&gt;
*Second column: {TOKEN} (put your tokens here, of course they must be individual)&lt;br /&gt;
*Third column: use the CONCATENATE function to join the first column with the second column.&lt;br /&gt;
&lt;br /&gt;
= L&#039;envoi des courriels=&lt;br /&gt;
&lt;br /&gt;
== Les champs réservés des courriels==&lt;br /&gt;
&lt;br /&gt;
Les textes suivants sont autorisés dans des modèles des courriels d&#039;invitation ou de rappel et sont saisi dans les propriétés du sondage. Lors de l&#039;envoi des courriels ces champ seront déjà remplacé dans l&#039;aperçu de votre invitation ou de votre courriel de rappel.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{ADMINEMAIL}||courriel de l&#039;adminsitrateur&lt;br /&gt;
|-&lt;br /&gt;
|{ADMINNAME}||Nom de l&#039;administrateur&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYNAME}||Titre du questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYDESCRIPTION}||Description du questionnaire&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les champs suivants sont aussi permis dans les courriels d&#039;invitation ou de rappel et seraont remplacé lors de l&#039;envoi du courriel&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYURL}||L&#039;adresse URL pour démarrer le questionnaire - en cas d&#039;envoi au format HTML, ce sera un lien HTML complet&lt;br /&gt;
|-&lt;br /&gt;
|@@SURVEYURL@@||L&#039;adresse URL pour démarrer le questionnaire au format texte - c&#039;est l&#039;adresse brute. Utilisable dans le corps HTML par exemple (disponible à partie de la version 1.90)&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_2}||Attribute 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If your survey is NOT anonymous, the following field names are available to insert token data in survey text and javascript. You can use these fields in confirmation and notification email template, too.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{TOKEN:EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_2}||Attribut 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Additional hints===&lt;br /&gt;
*If your survey is using anonymized responses then token-related placeholders will not work in notification email templates.&lt;br /&gt;
*You can use [[Expression Manager|Expression Manager]] to use expressions for tailoring an email{{NewIn|1.92}}. Please have a look at the [[Expression Manager HowTos|Expression Manager HowTos]] for an example.&lt;br /&gt;
Also have a look at the examples on using [[Adding a question#Information from tokens table|information from tokens table]].&lt;br /&gt;
&lt;br /&gt;
==Paramètres des courriels==&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;invitation :&#039;&#039;&#039;: La ligne du sujet de votre courriel d&#039;invitation en cas de table d&#039;invitation.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;invitation :&#039;&#039;&#039;: C&#039;est le texte du courriel d&#039;invitation qui sera envoyé. Il est par défaut rempli par un message d&#039;invitation par défaut ( provenant du fichier de langue). Vous pouvez utiliser les champs suivants pour insérer des informations personnalisées dans chaque courriel.&lt;br /&gt;
**&#039;&#039;&#039;{FIRSTNAME}&#039;&#039;&#039; - sera remplacé par le prénom&lt;br /&gt;
**&#039;&#039;&#039;{LASTNAME}&#039;&#039;&#039; - sera remplacé par le nom&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYNAME}&#039;&#039;&#039; - sera remplacé par le titre du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYDESCRIPTION}&#039;&#039;&#039; - sera remplacé par la description du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_1}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 1&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_2}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 2, etc ...&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse d&#039;accès au sondage en HTML&lt;br /&gt;
**&#039;&#039;&#039;@@SURVEYURL@@&#039;&#039;&#039; - sera remplacé par l&#039;adresse brute d&#039;accès au sondage (à partir de la v1.90)&lt;br /&gt;
**&#039;&#039;&#039;{OPTOUTURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse peremattant au répondant de se désinscrire (opt-out) du questionnaire&lt;br /&gt;
&lt;br /&gt;
Noter que ses champs reservés sont possible dans les champs des courriels suivant.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de rappel&#039;&#039;&#039;: Le sujet du courriel de rappel&lt;br /&gt;
#&#039;&#039;&#039;Courriel de rappel&#039;&#039;&#039;: Texte du contenu du courriel de rappel, éventuellement en HTML&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de confirmation&#039;&#039;&#039; Quand les invitations sont utilisée, un courriel de confirmation est envoyé au participant à la validation du questionnaire. C&#039;est ici le sujet de ce courriel.&lt;br /&gt;
#&#039;&#039;&#039;Courriel de confirmation&#039;&#039;&#039;: Le texte du courriel de confirmation. Effacer ce texte permet de ne pas envoyer de confirmation.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le sujet envoyé suite à une inscription sur un questionnaire.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le texte du courrier de confirmation envoyé suite à une inscription, il contient le nécessaire pour accède r directement au questionnaire.&lt;br /&gt;
&lt;br /&gt;
==Envoi des courriels==&lt;br /&gt;
&lt;br /&gt;
=== Envoyer les invitations===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;88&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ignorer les invitations pour lesquelles le statut du courriel est différent de &amp;quot;OK&amp;quot;, en choisissant &amp;quot;Sauter les invitations avec une adresse de courriel invalide&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Renvoyez une invitation====&lt;br /&gt;
&lt;br /&gt;
Quelquefois vous voulez renvoyer des courriels d&#039;invitation à certaines personnes. Quand vous utilisez &#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039; seules les personnes auxquelles vous n&#039;avez pas encore envoyé d&#039;invitation vont recevoir un courriel.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez donc renvoyer aussi des invitations à des utilisateurs en particulier en éditant leur invitation et en indiquant &#039;&#039;&#039;N&#039;&#039;&#039; dans la case &#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;, en remplaçant la date existante.&lt;br /&gt;
&lt;br /&gt;
==== Désinscription d&#039;un participant (opt-out)====&lt;br /&gt;
&lt;br /&gt;
Lorsque vous utilisez le tag { OPTOUTURL} dans votre courriel d&#039;invitation ou de rappel , vos participants ont la possibilité de se retirer de cette enquête en particulier en cliquant simplement sur cette adresse URL. Cela permet de ne pas harceler les utilisateurs avec des courriels de rappel. Un participant qui a opté de votre enquête aura &#039;Opt Out&#039; l&#039;état électronique indiquée dans le jeton.&lt;br /&gt;
&lt;br /&gt;
=== Envoi des rapppels===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;92&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Quand vous envoyez des rappels, vous pouvez:&lt;br /&gt;
*Passer les invitations avec une adresse invalide&lt;br /&gt;
*Passer les invitations pour laquelle un courriel a été &#039;récemment&#039; envoyé.&lt;br /&gt;
*Passer les invitations pour lequel un nombre donné de courriels ont déjà été envoyés.&lt;br /&gt;
&lt;br /&gt;
Note: A reminder will only be send to tokens where the &amp;quot;completed&amp;quot; field is not &amp;quot;N&amp;quot; (this means the respondent has either not taken or has not completed the survey).&lt;br /&gt;
&lt;br /&gt;
=== Envoi groupé de courriel===&lt;br /&gt;
&lt;br /&gt;
Quand vous avez un grand nombre de courriel à envoyer en même temps, LimeSurvey va limiter les envois par groupe de N courriel ( ceci est paramétrable dans les options générales, par défaut à 50)&lt;br /&gt;
&lt;br /&gt;
Vous devez cliquer sur suivant jusque ce que l&#039;ensemble des courriels soient envoyés.&lt;br /&gt;
&lt;br /&gt;
=== Courriel de confirmations===&lt;br /&gt;
&lt;br /&gt;
Quand vous utiliser les invitations, un courriel de confirmation lui est envoyé à la validation du questionnaire.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want this message to be sent, just deactivate this in the General survey settings.&lt;br /&gt;
&lt;br /&gt;
=== Spam problems===&lt;br /&gt;
&lt;br /&gt;
Often users complain not having received an invitation/reminder email because the user&amp;amp;rsquo;s spam filter treated the email as spam.&lt;br /&gt;
&lt;br /&gt;
If an email is treated as spam mostly depends on the spam filter being used and its settings. A spam filter usually checks the sender address and the email subject and content, so there are ways and means to influence how they treat your LimeSurvey invitation and reminder emails.&lt;br /&gt;
&lt;br /&gt;
At [http://www.limesurvey-consulting.com/how-to-prevent-limesurvey-email-invitations-or-reminders-being-treated-as-spam/ this blog post] on limesurvey-consulting.com a lot of possible issues and solutions are listed.&lt;br /&gt;
&lt;br /&gt;
===Wrong domain in invitation/reminder email link===&lt;br /&gt;
&lt;br /&gt;
LimeSurvey automatically tries to determine the URL for the invitation link by looking at the URL by which you logged in to the LimeSurvey administration. However with some server (mis-)configurations this might not work properly and you will have to set this manually.&lt;br /&gt;
&lt;br /&gt;
You can edit application/config/config.php to change the default base URL value. Add hostInfo property like this to the existing &#039;components&#039; array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;    &#039;components&#039; =&amp;gt; array(&lt;br /&gt;
       ...&lt;br /&gt;
       &#039;request&#039; =&amp;gt; array(&lt;br /&gt;
           &#039;hostInfo&#039; =&amp;gt; &#039;http://www.example.com&#039;,&lt;br /&gt;
       ),&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regarding the source of the problem: LimeSurvey tried to determine the domain from the server PHP variable $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;HTTP_HOST&#039;] or $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;SERVER_NAME&#039;].&lt;br /&gt;
&lt;br /&gt;
Some web server software do not properly seem to provide this information or are mis-configured.&lt;br /&gt;
&lt;br /&gt;
= Enregistrement public=&lt;br /&gt;
&lt;br /&gt;
==Permettre l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vouloir ouvrir votre questionnaire à tous mais avoir le système de contrôle utilisable avec les invitations. Ceci est possible : si vous initialiser la table des invitations et que vous choisissez OUI à Permettre l&#039;enregistrement public? dans les paramètres du questionnaire alors les répondants vont pouvoir s&#039;inscrire avant de répondre à votre questionnaire. Aprèsn s&#039;éêtre inscrit, il recevront une adresse URL pour remplir le questionnaire.&lt;br /&gt;
&lt;br /&gt;
Tous les codes d&#039;invitations provenant d&#039;un enregistrement public commence par la lettre R.&lt;br /&gt;
&lt;br /&gt;
==Les &#039;captchas&#039; dans l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Pour protéger votre sondage d&#039;inscription par des robits, il y a une fonction de &#039;captcha&#039; pour l&#039;enregistrement, la sauvegardez et le chargelent des questionnaires (à partir de la version 1.48). Cette fonctionnalité n&#039;est disponible que si vous avez le support GD d&#039;activé dans votre configuration de PHP (voir [[Installation|Prérequis d&#039;Installation]] ).&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/19/fr&amp;diff=61310</id>
		<title>Translations:Survey participants/19/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/19/fr&amp;diff=61310"/>
		<updated>2014-04-06T21:43:12Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{IMG(attId=&amp;quot;85&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Nombres de jetons&#039;&#039;&#039;:  Nombre de codes d&#039;invitations à ajouter. Par défaut à 100.&lt;br /&gt;
*&#039;&#039;&#039;Longueur du code&#039;&#039;&#039;: Nombre de caractères ou la longueur des codes d&#039;invitations. Par défaut à 15.&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039;: .. des participants.&lt;br /&gt;
*&#039;&#039;&#039;Couriel&#039;&#039;&#039;: l&#039;adresse de courriel des participants&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: Si vous voulez configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois ou le code pourra être utilisé&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; jusqu&#039;à&#039;&#039;&#039; :  la plage de date / l&#039;heure où les codes pourront être utilisés.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Champs d&#039;attribut définissables par l’administrateur&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61309</id>
		<title>Survey participants/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Survey_participants/fr&amp;diff=61309"/>
		<updated>2014-04-06T21:42:08Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; __TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Remarque&#039;&#039;&#039;:  Le système des invitations a beaucoup changé depuis la version 1.85 et versions ultérieures. Donc, si vous utilisez une version antérieure, il y aura des différences entre votre version et la documentation. Nous vous recommandons de mettre à niveau dès que possible.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
En de nombreuses occasions, vous voulez inviter un groupe de personnes pour participer à votre sondage, garder la trace des répondants ayant terminé le sondage, et vous assurer que chaque personne ne peut participer qu&#039;une seule fois. Le système des invitations vous permet d&#039;effectuer les opérations suivantes:&lt;br /&gt;
*Créez manuellement des invitations (nom, adresse email, ...)&lt;br /&gt;
*Importer une liste de noms et d&#039;adresses email pour les participants (à partir d&#039;un fichier CSV ou une interrogations LDAP)&lt;br /&gt;
*Ajouter / Supprimer des invitations&lt;br /&gt;
*Générer un numéro unique pour le jeton de chaque participant (code d&#039;invitation)&lt;br /&gt;
*Envoyez une invitation par courriel à chaque personne de votre liste, par groupe ou individuellement&lt;br /&gt;
*Envoyer un courriel de rappel à chaque personne de votre liste qui n&#039;a pas encore répondu, par groupe ou individuellement&lt;br /&gt;
*Suivi les répondants de votre liste qui ont répondu&lt;br /&gt;
*Interdire l&#039;accès aux personnes qui n&#039;ont pas de ceode d&#039;invitation, et ceux qui ont déjà répondu&lt;br /&gt;
*Modifier / changer tous les détails dans votre liste d&#039;invitation&lt;br /&gt;
&lt;br /&gt;
Une fois le questionnaire en accès restreint (vous avez activé les invitations pour ce questionnaire), alors &#039;&#039;&#039;seules les personnes avec une invitation valide (pas encore utilisée) peuvent accéder au questionnaire&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Si vous activez &#039;&#039;Permettre l&#039;enregistrement public ?&#039;&#039; dans les propriétés du questionnaire, les participants pourront s&#039;inscrire à votre sondage et avoir leur code d&#039;invitation personnel généré automatiquement.&lt;br /&gt;
&lt;br /&gt;
{{Hint|Text=Some token settings are set in survey settings, see [[Creating a new survey#Tokens]]}} &lt;br /&gt;
&lt;br /&gt;
==Est-ce qu&#039;une sondage utilisant les invitations peut assurer des réponses anonymes?==&lt;br /&gt;
&lt;br /&gt;
La réponse à cette question est &#039;&#039;&#039;Oui&#039;&#039;&#039;. Les invitations peuvent être utilisées tant pour les sondages anonymes que non anonymes. Ceci est déterminé lors de la création du questionnaire. Si un questionnaire n&#039;est pas anonyme (ou &#039;suivi&#039;) alors le code d&#039;invitation peut être utilisé pour trouver les réponses que le répondant a faites au questionnaire. Si le sondage est anonyme, alors aucun lien n&#039;est disponible entre la table des invitations et la table des réponses (techniquement: pas de relation de clé étrangère).&lt;br /&gt;
&lt;br /&gt;
=Comment activer les invitations ?=&lt;br /&gt;
&lt;br /&gt;
Il y a deux manières d&#039;activer les invitations:&lt;br /&gt;
#Juste après l&#039;activation du questionnaire, il vous sera demandé si vous souhaitez activer les invitations: {IMG(attId=&amp;quot;84&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
# &#039;&#039;&#039;Ou&#039;&#039;&#039; vous pouvez cliquer sur le symbole de gestion des invitations [[File:tokens.png]] - avant même que le sondage soit activé.&lt;br /&gt;
&lt;br /&gt;
=Les outils de contrôle des invitations=&lt;br /&gt;
&lt;br /&gt;
[[File:token-menu2.png]]&lt;br /&gt;
&lt;br /&gt;
Après la création de la table des invitations, vous pouvez cliquer sur l&#039;icône pour administrer les codes d&#039;invitation. Voici un bref aperçu des options de menu de l&#039;écran de gestion des invitations:&lt;br /&gt;
*&#039;&#039;&#039;Administration&#039;&#039;&#039;: Retourne à l&#039;écran d&#039;administration principal du questionnaire&lt;br /&gt;
*&#039;&#039;&#039;Résumé&#039;&#039;&#039;: Affiche un résumé des invitations de la table nombre de codes d&#039;invitation, nombre d&#039;invitation envoyée, et nombre de réponse. Permet également d&#039;accéder aux fonctions de d&#039;administration de la base de données voir ci-dessous. C&#039;est l&#039;écran par défaut.&lt;br /&gt;
*&#039;&#039;&#039;Parcourir&#039;&#039;&#039;: Affiche la liste complète des participants de la table des invitations. Depuis l&#039;écran d&#039;affichage, vous pouvez modifier ou supprimer des entrées individuelles dans la table ainsi qu&#039;un certain nombre d&#039;autres fonctions utiles voir la section Parcourir ci-dessous&lt;br /&gt;
*&#039;&#039;&#039;Ajouter une nouvelle invitation&#039;&#039;&#039;: Permet d&#039;ajouter une entrée à la table des invitations&lt;br /&gt;
*&#039;&#039;&#039;Ajouter des codes factices&#039;&#039;&#039;: Permet d&#039;ajouter une ou plusieurs codes d&#039;invitations à la table des invitations trèsb rapidement.&lt;br /&gt;
*&#039;&#039;&#039;Gérer les champs des attributs supplémentaire:&#039;&#039;&#039;: Permet d&#039;ajouter des champs supplémentaires à la table des invitations pour stocker des données personnalisées liés aux participants&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir d&#039;un CSV&#039;&#039;&#039;: Permet d&#039;importer les informations des invitations depuis un fichier CSV&lt;br /&gt;
*&#039;&#039;&#039;Importer à partir de LDAP&#039;&#039;&#039;: Permet d&#039;importer les informations d&#039;une requête LDAP testé sur openLDAP, mais devrait fonctionner dans tous annuaire compatible LDAP, dont ActiveDirectory.&lt;br /&gt;
*&#039;&#039;&#039;Export les invitations vers un fichier CSV&#039;&#039;&#039;: Crée un fichier standard CSV (délimité par des virgules) avec la liste complète des participants de la table des invitations en cours.&lt;br /&gt;
*&#039;&#039;&#039;Éditer les modèles de courriel&#039;&#039;&#039;: Pour personnaliser les textes et contenus utilisés pour les invitations, les rappels, confirmations, et les courriels d&#039;inscription.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039;: Envoi global des invitations par courriel à tous les participants de la table des invitations qui n&#039;ont pas déjà reçu une invitation.&lt;br /&gt;
*&#039;&#039;&#039;Envoyer les courriels de rappel&#039;&#039;&#039;: Envoi global des courriels de rappel à tous les participants ayant reçu une invitation et n&#039;ayant pas encore répondu.&lt;br /&gt;
*&#039;&#039;&#039;Générer les codes&#039;&#039;&#039;: Crée les codes d&#039;invitation uniques pour toutes les entrées individuelles de la table des invitations qui n&#039;en disposent pas encore.&lt;br /&gt;
*&#039;&#039;&#039;Effacer la tabe des inviations&#039;&#039;&#039;: Supprimer la table des invitations et passer le questionnaire en accès libre ou ouvert.&lt;br /&gt;
*&#039;&#039;&#039;Paramètres de rejet&#039;&#039;&#039;:  Paramètrage du courriel recevant les courriels de rejet. Ces paramètres peuvent être modifié à ce niveau ou au niveau général. Ce dispositif a été ajouté dans la version 1.91.&lt;br /&gt;
&lt;br /&gt;
=Modification et ajout d&#039;une invitation=&lt;br /&gt;
&lt;br /&gt;
Une entrée typique d&#039;invitation contient les champs suivants:&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;83&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039; : ... du participant (peut être utilisé dans les courriels et les questionnaires).&lt;br /&gt;
*&#039;&#039;&#039;Courriel&#039;&#039;&#039;: l&#039;adresse courriel du participant&lt;br /&gt;
*&#039;&#039;&#039;Statut du courriel&#039;&#039;&#039;: un champ pour conserver une trace des mauvaises adresses de courriels. Par exemple, si l&#039;administrateur du sondage ont reçu des notifications d&#039;erreur par courriel à partir de ce courriel, ce qu&#039;il peut définir ce champ à autre chose que &#039;OK&#039; (par exemple &#039;utilisateur inconnu&#039;, ou &#039;quota dépassé&#039;). Le marquage cette invitation avec un autre statut que &#039;OK&#039;, permettra d&#039;ignorer cette entrée lors de l&#039;envoi d&#039;invitation ou de couriel de rappel. Notez que ceci est entièrement manuel à moins vous décidez de mettre en place un script qui met à jour ce champ automatiquement.&lt;br /&gt;
*&#039;&#039;&#039;Code&#039;&#039;&#039;: c&#039;est le code de l&#039;invitation. Il est généralement généré automatiquement avec le bouton &#039;Générer les codes d&#039;invitations&#039;.&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: pour configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle l&#039;invitation a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Rappel envoyé?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le rappel a été envoyée par courriel.&lt;br /&gt;
*&#039;&#039;&#039;Complété?&#039;&#039;&#039;: par défaut a &#039;N&#039;, sinon contient la date à laquelle le questionnaire a était validé pour les questionnaire non anonyme ou Y pour les questionnaires anonyme.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations restantes&#039;&#039;&#039;: compteur du nombre de fois que le code d&#039;invitation peut être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; Valide jusqu&#039;à&#039;&#039;&#039; : Vous pouvez définir une plage de date/heure durant laquelle ce code d&#039;invitation pourra être utilisé. Vous pouvez laisser ces champs vides si vous ne souhaitez pas limiter les dates pour certains utilisateurs. Remarque: Si l&#039;utilisateur répond au questionnaire au moment ou la date arrive à échéance,  l&#039;invitation est verrouillé immédiatement, le répondant ne pourra pas terminer le sondage.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Ce sont les champs d&#039;attribut définissables par administrateur - voir ci dessous.&lt;br /&gt;
&lt;br /&gt;
=Codes factices=&lt;br /&gt;
&lt;br /&gt;
Le système des codes factices a été ajouté à partir de la version 1.91.&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;85&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
*&#039;&#039;&#039;Nombres de jetons&#039;&#039;&#039;:  Nombre de codes d&#039;invitations à ajouté. Par défaut à 100.&lt;br /&gt;
*&#039;&#039;&#039;Longueur du code&#039;&#039;&#039;: Nombre de caractères ou la longueur des codes d&#039;invitations. Par défaut à 15.&lt;br /&gt;
*&#039;&#039;&#039;Prénom et Nom&#039;&#039;&#039;: .. des participants.&lt;br /&gt;
*&#039;&#039;&#039;Couriel&#039;&#039;&#039;: l&#039;adresse de courriel des participants&lt;br /&gt;
*&#039;&#039;&#039;Langue&#039;&#039;&#039;: Si vous voulez configurer la langue par défaut pour ce participant.&lt;br /&gt;
*&#039;&#039;&#039;Utilisations retantes&#039;&#039;&#039;: compteur du nombre de fois ou le code pourra être utilisé&lt;br /&gt;
*&#039;&#039;&#039;Valable à partir de &amp;amp; jusqu&#039;à&#039;&#039;&#039; :  la plage de date / l&#039;heure où les codes pourront être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Attribute 1 to Attribute X&#039;&#039;&#039;: Champs d&#039;attribut définissables par l&#039;adminitrateur&lt;br /&gt;
&lt;br /&gt;
Veuillez noter que le nom, l&#039;adresse de courriel, la langue seront fixés à la même valeur pour tous les codes factices.&lt;br /&gt;
&lt;br /&gt;
=Bounce Settings{{NewIn|1.91}}=&lt;br /&gt;
&lt;br /&gt;
Please also check out the [[Email bounce tracking system]] page for more information how to correctly configure this feature.&lt;br /&gt;
&lt;br /&gt;
[[File:surveyBounseSettings.png]]&lt;br /&gt;
*&#039;&#039;&#039;Survey bounce email&#039;&#039;&#039;:  A valid email address for return mail.   For faster bounce back processing, this email box should be limited to bounce back only.&lt;br /&gt;
*&#039;&#039;&#039;Bounce settings to be used&#039;&#039;&#039;: There are three options:  1- None (default) - no bounce back processing, 2- Use settings below - Will set bounce back processing at the survey level, or 3- Use global settings -- Settings based on the system level.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: Three options: 1- Off, 2- IMAP or 3- POP&lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;:  Host name and port number.   Port number isn&#039;t typically needed unless the email host uses a non-standard port. Example:  mail.example.net:25 or imap.gmail.com:995&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;:  User Name or User ID of the email account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;:  password of the email account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;:  Three options:  1- None (default), 2- SSL, or 3- TLS&lt;br /&gt;
&lt;br /&gt;
=Champs des attributs personnalisés=&lt;br /&gt;
&lt;br /&gt;
It is possible to add a number of additional fields to the tokens table to save additional data for a participant. By clicking on the [[File:token_manage.png]] icon you can manage these fields. You can add more attribute fields (by default they have a a length of 255 chars) and also set descriptions for each field - so they look nicer in the administration, when you browse tokens, when creating [[Setting conditions|conditions]] based on attribute fields or even when you export results for non-anonymous surveys.&lt;br /&gt;
&lt;br /&gt;
Il est possible d&#039;ajouter un certains nombre de champs supplémentaires à la table des invitations pour enregistrer des données supplémentaires concernant les participants. En cliquant sur l&#039;icône [[File:token_manage.png]], vous pouvez gérer ces champs. Vous pouvez ajouter des champs d&#039;attributs (par défaut, ils ont une longueur de 255 caractères) et des descriptions pour chaque champ - pour qu&#039;ils soient plus explicite dans l&#039;interface d&#039;administration, lorsque vous consultez la tables des invitations, ou loirs de conditions basées sur des attributs ou lorsque vous exportez un questionnaire non anonyme.&lt;br /&gt;
&lt;br /&gt;
=Utilisation de l&#039;écran d&#039;affichage des invitations et édition des réponses=&lt;br /&gt;
&lt;br /&gt;
L&#039;écran d&#039;affichage montre une liste de toutes les entrées de la table des invitations, ainsi que des boutons d&#039;action pour effectuer des t&amp;amp;acirc;ches spécifiques sur une entrée individuelle.&lt;br /&gt;
&lt;br /&gt;
La ligne du haut du tableau est composée de 3 parties: celle de droite permet de sélectionner le nombre de lignes affichées, ainsi que le point de départ; au centre un formulaire de recherche; les boutons sur le coté gauche permettent de naviguer dans la liste.&lt;br /&gt;
&lt;br /&gt;
La deuxième ligne de la table comprend le nom du champ, et une flèche verte qui - s&#039;il est cliqué - permet de trier par rapport à ce champs.&lt;br /&gt;
&lt;br /&gt;
La colonne &amp;quot;Actions&amp;quot; donne une liste de t&amp;amp;acirc;ches spécifiques qui peuvent être effectuées sur cette entrée individuelle:&lt;br /&gt;
&lt;br /&gt;
[[File:token-actions.png]]&lt;br /&gt;
*Lancer le questionnaire pour cette invitation&lt;br /&gt;
*Éditer cette invitation&lt;br /&gt;
*Supprimer cette invitation&lt;br /&gt;
*Envoyer un courriel d&#039;invitation ou de rappel à cette netrée&lt;br /&gt;
*Si le questionnaire est non-anonyme, un bouton supplémentaire apparait pour visualiser la réponse correspondante.&lt;br /&gt;
&lt;br /&gt;
=Administration de la base de donnée=&lt;br /&gt;
&lt;br /&gt;
[[File:token-summary.png]][[File:token-db-mgt.png]]&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;91&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
En plus d&#039;afficher un bref résumé de l&#039;état de votre table d&#039;invitation, l&#039;écran d&#039;accueil vous permet aussi d&#039;effectuer quelques manipulations sur cette table.&lt;br /&gt;
*&#039;&#039;&#039;Mettre toutes les invitations à &#039;Non envoyée&#039;&#039;&#039;&#039; Défini l&#039;ensemble des invitations à &amp;quot;Non envoyée&amp;quot; ( à &#039;N&#039; ). Ne devrait normalment ne pas être utilisé.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer tous les codes uniques&#039;&#039;&#039;: Efface tous les codes des invitations, n&#039;efface que les codes, pas les invitations. Ne devrait pas être utilisé en situation normale.&lt;br /&gt;
*&#039;&#039;&#039;Supprimer toutes les invitations&#039;&#039;&#039;: Supprime complétement la table d&#039;invitation. Ouvre le sondage aux personnes connaissant l&#039;adresse du questionnaire.&lt;br /&gt;
&lt;br /&gt;
= Import/export des inviations=&lt;br /&gt;
&lt;br /&gt;
== Import via un fichier CSV==&lt;br /&gt;
&lt;br /&gt;
L&#039;import se fait via cet écran&lt;br /&gt;
&lt;br /&gt;
[[File:uploadtoken.jpg]]&lt;br /&gt;
&lt;br /&gt;
Votre fichier CSV doit être à la norme des [http://fr.wikipedia.org/wiki/Comma-separated_values fichiers CSV (&#039;Comma Separated Value&#039;)] , c&#039;est à dire séparé par des virgule (,). La première ligne de texte est toujours l&#039;en-tête et sera utilisé pour identifier les colonnes de la table. Les champs de données possibles sont:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email,emailstatus,token,language code,tid,attribute_1,attribute_2, attribute_...&lt;br /&gt;
&lt;br /&gt;
Pour obtenir une liste complète des noms de champs de la table d&#039;invitation, vous pouvez exporter une table existante.&lt;br /&gt;
&lt;br /&gt;
Les champs peuvent être dans n&#039;importe quel ordre, mais les colonnes pour le nom, pour le prénom et pour le courriel sont obligatoires. Vous pouvez importer les champs supplémentaire des attributs au même moment.&lt;br /&gt;
&lt;br /&gt;
Un fichier CSV au strict minimum pourrait ressembler à ceci:&lt;br /&gt;
&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    John,Doe,john@doe.net&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Date format for token import&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The date format for the &amp;quot;validfrom&amp;quot; and &amp;quot;validuntil&amp;quot; fields in the CSV token inport file is &amp;quot;YYYY-MM-DD HH:MM&amp;quot;, e.g.:&lt;br /&gt;
&lt;br /&gt;
    2012-01-01 00:00&lt;br /&gt;
&lt;br /&gt;
--would correspond to 1st January, 2012, at 12:00 AM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filtering duplicates&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En activant l&#039;option pour filtrer les doublons, vous pouvez définir les champs qui sont utilisés pour identifier les doublons. Par défaut le &#039;Nom, Prénom et Adresse de Courriel&#039; sont présélectionnés. Si un doublon est trouvé lors de l&#039;importation de la ligne liée est omise.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Dépannage pour l&#039;import des invitations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A common error when users try to import tokens is an invalid CSV file. This is often caused by Microsoft Excel. Many users have a list of e-mail addresses saved as an XLS document. A file can be saved as CSV in Excel, however, depending on the locale of the OS Microsoft may use semi-colon (;) as the comma separator, while a standard CSV file uses comma (,) as the separator. If not sure just open the file with a standard text editor and check what separator was used. Starting in version 2.00 can you select the used separator during import.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez aussi utiliser [http://fr.libreoffice.org/libreoffice/calc/ Libre Office Calc] pour importer votre fichier xls et exporter un fichier CSV au bon format.&lt;br /&gt;
&lt;br /&gt;
You can use [http://www.libreoffice.org/features/calc/ LibreOffice Calc] to export import your xls file and export your csv file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Add additional attributes at import&#039;&#039;&#039;&lt;br /&gt;
It is also possible to add new custom attributes when import a CSV file. It is still needed to define what attributes will be added. The way to do this is:&lt;br /&gt;
    firstname,lastname,email&lt;br /&gt;
    attribute_1 &amp;lt;Casenr&amp;gt;; token; attribute_2 &amp;lt;Title&amp;gt;; attribute_3 &amp;lt;destination&amp;gt;; lastname; firstname; attribute_4 &amp;lt;Sender&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
== Creating CSV file with Excel on the Mac==&lt;br /&gt;
&lt;br /&gt;
When you create a CSV file with Excel 2011 on the MAC and use the standard &amp;quot;save as&amp;quot; option, you loose special characters such as ü, &amp;amp;euml;, é etc. when importing into LimeSurvey Token Table.&lt;br /&gt;
&lt;br /&gt;
To make this work properly choose to save the file as a Windows text CSV file (tested on the Dutch version of Excel, saved as &amp;quot;Door lijstscheidingstekens gescheiden Windows tekst (.CSV)&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Then when importing the file in the LimeSurvey token table, under &amp;quot;character set of file&amp;quot; choose &amp;quot;Mac West European&amp;quot;. The special characters will be imported correctly.&lt;br /&gt;
&lt;br /&gt;
Testé seulement sur la version 2.0 de LimeSurvey&lt;br /&gt;
&lt;br /&gt;
== Export au format CSV ==&lt;br /&gt;
&lt;br /&gt;
Quand vous exporter votre table au format CSV, les champs sont exportés dans l&#039;ordre suivant:&lt;br /&gt;
&lt;br /&gt;
tid,prénom,nom,email,emailstatus,invitation,langue,code,attribut_1,attribut_2,...&lt;br /&gt;
&lt;br /&gt;
== Import depuis un annuaire LDAP ==&lt;br /&gt;
&lt;br /&gt;
[[File:token-Ldap-import.png]]&lt;br /&gt;
* Les requêtes sont définies manuellement par administrateur du système dans le fichier config-ldap.php&lt;br /&gt;
* Les doublons sont identifiés par le prénom, le nom et l&#039;adresse de courriel. Si un doublon est trouvé, lors de l&#039;importation la ligne concernée est omise, sauf si vous avez décoché la case de filtre des doublons.&lt;br /&gt;
&lt;br /&gt;
== Un truc pour générer un nombre important de fausses adresses de courriels==&lt;br /&gt;
&lt;br /&gt;
Quelquefois, vous pouvez avoir besoin d&#039;un grand nombre d&#039;adresses de courriel et d&#039;invitations. Vous pouvez utiliser les fonctions de votre tableur ( par exemple OpenOffice Calc) pour les fabriquer. Supposons que vous souhaitiez des milliers d&#039;adresses de courriel de la forme : 1@test.com, 2@test.com,3@test.com,... Vous aller entrer une liste consécutive de nombres dans la colonne A en indiquant à partir de la ligne 2 : =A1+1, ensuite copier/coller A2 autant de fois que vous le souhaitez. Dans la colonne B, en entête, vous indiquez email et à partir de B2: =A2&amp;amp;&amp;quot;@example.org&amp;quot;. Vous pouvez ensuite enregistrer ce fichier au format CSV et l&#039;importer dans votre table d&#039;invitation.&lt;br /&gt;
&lt;br /&gt;
Depuis la version 1.91, vous pouvez directement utiliser la génération automatique de code factices.&lt;br /&gt;
&lt;br /&gt;
== Une astuce pour générer un grand nombre de liens individuels incluant l&#039;invitation ==&lt;br /&gt;
&lt;br /&gt;
La structure du lien pour un sondage est la suivante :&lt;br /&gt;
&lt;br /&gt;
Limesurvey 1.x: http://url-vers-votre-installation-limesurvey/index.php?sid=XXXX&amp;amp;lang=fr&amp;amp;token={TOKEN}&lt;br /&gt;
&lt;br /&gt;
Limesurvey 2.x: http://url-vers-votre-installation-limesurvey/index.php/survey/index/sid/xxxx/newtest/Y/lang/FR/token/{TOKEN}&lt;br /&gt;
&lt;br /&gt;
So you proceed similar to the example above for generating email adresses.&lt;br /&gt;
*First column: http://url-to-your-limesurvey-installation/index.php?sid=XXXX&amp;amp;lang=en&amp;amp;token= (for version 1.x) OR http://url-to-your-limesurvey-installation/index.php/survey/index/sid/xxxx/newtest/Y/lang/EN/token/ (for version 2.x) (same URL for all, as long as the language is the same!)&lt;br /&gt;
*Second column: {TOKEN} (put your tokens here, of course they must be individual)&lt;br /&gt;
*Third column: use the CONCATENATE function to join the first column with the second column.&lt;br /&gt;
&lt;br /&gt;
= L&#039;envoi des courriels=&lt;br /&gt;
&lt;br /&gt;
== Les champs réservés des courriels==&lt;br /&gt;
&lt;br /&gt;
Les textes suivants sont autorisés dans des modèles des courriels d&#039;invitation ou de rappel et sont saisi dans les propriétés du sondage. Lors de l&#039;envoi des courriels ces champ seront déjà remplacé dans l&#039;aperçu de votre invitation ou de votre courriel de rappel.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{ADMINEMAIL}||courriel de l&#039;adminsitrateur&lt;br /&gt;
|-&lt;br /&gt;
|{ADMINNAME}||Nom de l&#039;administrateur&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYNAME}||Titre du questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYDESCRIPTION}||Description du questionnaire&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Les champs suivants sont aussi permis dans les courriels d&#039;invitation ou de rappel et seraont remplacé lors de l&#039;envoi du courriel&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{SURVEYURL}||L&#039;adresse URL pour démarrer le questionnaire - en cas d&#039;envoi au format HTML, ce sera un lien HTML complet&lt;br /&gt;
|-&lt;br /&gt;
|@@SURVEYURL@@||L&#039;adresse URL pour démarrer le questionnaire au format texte - c&#039;est l&#039;adresse brute. Utilisable dans le corps HTML par exemple (disponible à partie de la version 1.90)&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{ATTRIBUTE_2}||Attribute 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If your survey is NOT anonymous, the following field names are available to insert token data in survey text and javascript. You can use these fields in confirmation and notification email template, too.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|{TOKEN:EMAIL}||Adresse de courriel de l&#039;invité&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:FIRSTNAME}||Prénom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:LASTNAME}||Nom&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN}||Le code pour accéder au questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_1}||Attribut 1&lt;br /&gt;
|-&lt;br /&gt;
|{TOKEN:ATTRIBUTE_2}||Attribut 2 (...continuant pour chaque attributs)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Additional hints===&lt;br /&gt;
*If your survey is using anonymized responses then token-related placeholders will not work in notification email templates.&lt;br /&gt;
*You can use [[Expression Manager|Expression Manager]] to use expressions for tailoring an email{{NewIn|1.92}}. Please have a look at the [[Expression Manager HowTos|Expression Manager HowTos]] for an example.&lt;br /&gt;
Also have a look at the examples on using [[Adding a question#Information from tokens table|information from tokens table]].&lt;br /&gt;
&lt;br /&gt;
==Paramètres des courriels==&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;invitation :&#039;&#039;&#039;: La ligne du sujet de votre courriel d&#039;invitation en cas de table d&#039;invitation.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;invitation :&#039;&#039;&#039;: C&#039;est le texte du courriel d&#039;invitation qui sera envoyé. Il est par défaut rempli par un message d&#039;invitation par défaut ( provenant du fichier de langue). Vous pouvez utiliser les champs suivants pour insérer des informations personnalisées dans chaque courriel.&lt;br /&gt;
**&#039;&#039;&#039;{FIRSTNAME}&#039;&#039;&#039; - sera remplacé par le prénom&lt;br /&gt;
**&#039;&#039;&#039;{LASTNAME}&#039;&#039;&#039; - sera remplacé par le nom&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYNAME}&#039;&#039;&#039; - sera remplacé par le titre du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYDESCRIPTION}&#039;&#039;&#039; - sera remplacé par la description du questionnaire&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_1}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 1&lt;br /&gt;
**&#039;&#039;&#039;{ATTRIBUTE_2}&#039;&#039;&#039; - sera remplacé par la valeur de l&#039;attribut 2, etc ...&lt;br /&gt;
**&#039;&#039;&#039;{SURVEYURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse d&#039;accès au sondage en HTML&lt;br /&gt;
**&#039;&#039;&#039;@@SURVEYURL@@&#039;&#039;&#039; - sera remplacé par l&#039;adresse brute d&#039;accès au sondage (à partir de la v1.90)&lt;br /&gt;
**&#039;&#039;&#039;{OPTOUTURL}&#039;&#039;&#039; - sera remplacé par l&#039;adresse peremattant au répondant de se désinscrire (opt-out) du questionnaire&lt;br /&gt;
&lt;br /&gt;
Noter que ses champs reservés sont possible dans les champs des courriels suivant.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de rappel&#039;&#039;&#039;: Le sujet du courriel de rappel&lt;br /&gt;
#&#039;&#039;&#039;Courriel de rappel&#039;&#039;&#039;: Texte du contenu du courriel de rappel, éventuellement en HTML&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel de confirmation&#039;&#039;&#039; Quand les invitations sont utilisée, un courriel de confirmation est envoyé au participant à la validation du questionnaire. C&#039;est ici le sujet de ce courriel.&lt;br /&gt;
#&#039;&#039;&#039;Courriel de confirmation&#039;&#039;&#039;: Le texte du courriel de confirmation. Effacer ce texte permet de ne pas envoyer de confirmation.&lt;br /&gt;
#&#039;&#039;&#039;Objet du courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le sujet envoyé suite à une inscription sur un questionnaire.&lt;br /&gt;
#&#039;&#039;&#039;Courriel d&#039;enregistrement public&#039;&#039;&#039;: C&#039;est le texte du courrier de confirmation envoyé suite à une inscription, il contient le nécessaire pour accède r directement au questionnaire.&lt;br /&gt;
&lt;br /&gt;
==Envoi des courriels==&lt;br /&gt;
&lt;br /&gt;
=== Envoyer les invitations===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;88&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ignorer les invitations pour lesquelles le statut du courriel est différent de &amp;quot;OK&amp;quot;, en choisissant &amp;quot;Sauter les invitations avec une adresse de courriel invalide&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Renvoyez une invitation====&lt;br /&gt;
&lt;br /&gt;
Quelquefois vous voulez renvoyer des courriels d&#039;invitation à certaines personnes. Quand vous utilisez &#039;&#039;&#039;Envoyer les courriels d&#039;invitation&#039;&#039;&#039; seules les personnes auxquelles vous n&#039;avez pas encore envoyé d&#039;invitation vont recevoir un courriel.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez donc renvoyer aussi des invitations à des utilisateurs en particulier en éditant leur invitation et en indiquant &#039;&#039;&#039;N&#039;&#039;&#039; dans la case &#039;&#039;&#039;Invitation envoyée?&#039;&#039;&#039;, en remplaçant la date existante.&lt;br /&gt;
&lt;br /&gt;
==== Désinscription d&#039;un participant (opt-out)====&lt;br /&gt;
&lt;br /&gt;
Lorsque vous utilisez le tag { OPTOUTURL} dans votre courriel d&#039;invitation ou de rappel , vos participants ont la possibilité de se retirer de cette enquête en particulier en cliquant simplement sur cette adresse URL. Cela permet de ne pas harceler les utilisateurs avec des courriels de rappel. Un participant qui a opté de votre enquête aura &#039;Opt Out&#039; l&#039;état électronique indiquée dans le jeton.&lt;br /&gt;
&lt;br /&gt;
=== Envoi des rapppels===&lt;br /&gt;
&lt;br /&gt;
{IMG(attId=&amp;quot;92&amp;quot;,imalign=&amp;quot;center&amp;quot;)}&lt;br /&gt;
&lt;br /&gt;
Quand vous envoyez des rappels, vous pouvez:&lt;br /&gt;
*Passer les invitations avec une adresse invalide&lt;br /&gt;
*Passer les invitations pour laquelle un courriel a été &#039;récemment&#039; envoyé.&lt;br /&gt;
*Passer les invitations pour lequel un nombre donné de courriels ont déjà été envoyés.&lt;br /&gt;
&lt;br /&gt;
Note: A reminder will only be send to tokens where the &amp;quot;completed&amp;quot; field is not &amp;quot;N&amp;quot; (this means the respondent has either not taken or has not completed the survey).&lt;br /&gt;
&lt;br /&gt;
=== Envoi groupé de courriel===&lt;br /&gt;
&lt;br /&gt;
Quand vous avez un grand nombre de courriel à envoyer en même temps, LimeSurvey va limiter les envois par groupe de N courriel ( ceci est paramétrable dans les options générales, par défaut à 50)&lt;br /&gt;
&lt;br /&gt;
Vous devez cliquer sur suivant jusque ce que l&#039;ensemble des courriels soient envoyés.&lt;br /&gt;
&lt;br /&gt;
=== Courriel de confirmations===&lt;br /&gt;
&lt;br /&gt;
Quand vous utiliser les invitations, un courriel de confirmation lui est envoyé à la validation du questionnaire.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t want this message to be sent, just deactivate this in the General survey settings.&lt;br /&gt;
&lt;br /&gt;
=== Spam problems===&lt;br /&gt;
&lt;br /&gt;
Often users complain not having received an invitation/reminder email because the user&amp;amp;rsquo;s spam filter treated the email as spam.&lt;br /&gt;
&lt;br /&gt;
If an email is treated as spam mostly depends on the spam filter being used and its settings. A spam filter usually checks the sender address and the email subject and content, so there are ways and means to influence how they treat your LimeSurvey invitation and reminder emails.&lt;br /&gt;
&lt;br /&gt;
At [http://www.limesurvey-consulting.com/how-to-prevent-limesurvey-email-invitations-or-reminders-being-treated-as-spam/ this blog post] on limesurvey-consulting.com a lot of possible issues and solutions are listed.&lt;br /&gt;
&lt;br /&gt;
===Wrong domain in invitation/reminder email link===&lt;br /&gt;
&lt;br /&gt;
LimeSurvey automatically tries to determine the URL for the invitation link by looking at the URL by which you logged in to the LimeSurvey administration. However with some server (mis-)configurations this might not work properly and you will have to set this manually.&lt;br /&gt;
&lt;br /&gt;
You can edit application/config/config.php to change the default base URL value. Add hostInfo property like this to the existing &#039;components&#039; array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;    &#039;components&#039; =&amp;gt; array(&lt;br /&gt;
       ...&lt;br /&gt;
       &#039;request&#039; =&amp;gt; array(&lt;br /&gt;
           &#039;hostInfo&#039; =&amp;gt; &#039;http://www.example.com&#039;,&lt;br /&gt;
       ),&lt;br /&gt;
   )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Regarding the source of the problem: LimeSurvey tried to determine the domain from the server PHP variable $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;HTTP_HOST&#039;] or $_SERVER&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;&#039;SERVER_NAME&#039;].&lt;br /&gt;
&lt;br /&gt;
Some web server software do not properly seem to provide this information or are mis-configured.&lt;br /&gt;
&lt;br /&gt;
= Enregistrement public=&lt;br /&gt;
&lt;br /&gt;
==Permettre l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vouloir ouvrir votre questionnaire à tous mais avoir le système de contrôle utilisable avec les invitations. Ceci est possible : si vous initialiser la table des invitations et que vous choisissez OUI à Permettre l&#039;enregistrement public? dans les paramètres du questionnaire alors les répondants vont pouvoir s&#039;inscrire avant de répondre à votre questionnaire. Aprèsn s&#039;éêtre inscrit, il recevront une adresse URL pour remplir le questionnaire.&lt;br /&gt;
&lt;br /&gt;
Tous les codes d&#039;invitations provenant d&#039;un enregistrement public commence par la lettre R.&lt;br /&gt;
&lt;br /&gt;
==Les &#039;captchas&#039; dans l&#039;enregistrement public==&lt;br /&gt;
&lt;br /&gt;
Pour protéger votre sondage d&#039;inscription par des robits, il y a une fonction de &#039;captcha&#039; pour l&#039;enregistrement, la sauvegardez et le chargelent des questionnaires (à partir de la version 1.48). Cette fonctionnalité n&#039;est disponible que si vous avez le support GD d&#039;activé dans votre configuration de PHP (voir [[Installation|Prérequis d&#039;Installation]] ).&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/18/fr&amp;diff=61308</id>
		<title>Translations:Survey participants/18/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Survey_participants/18/fr&amp;diff=61308"/>
		<updated>2014-04-06T21:42:07Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le système des codes factices a été ajouté à partir de la version 1.91.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61226</id>
		<title>Upgrading from a previous version/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61226"/>
		<updated>2014-03-26T21:47:39Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Vérifications après une mise à jour&amp;#039;&amp;#039;&amp;#039;: *&amp;#039;&amp;#039;&amp;#039;depuis n&amp;#039;importe quelle version précédent la 2.xx&amp;#039;&amp;#039;&amp;#039;: Les &amp;#039;&amp;#039;&amp;#039;gabarits&amp;#039;&amp;#039;&amp;#039; ont subit de nombreux chang...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;La traduction de cette page n&#039;est pas terminée.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avant de commencer...=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;... lisez ceci car c&#039;est très important: &#039;&#039;&#039;Ne jamais oublier de faire une sauvegarde des fichiers et de la base de données de votre installation actuelle!!&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vous pouvez le faire en utilisant les outils d&#039;administration de la base de données comme [http://www.phpmyadmin.net phpMyAdmin] etc. et un gestionnaire de fichiers! Si vous ne savez pas comment procéder pour faire les sauvegardes des fichiers et de la base, alors vous devez demander à quelqu&#039;un de le faire pour vous ou de vous l&#039;apprendre ou alors utilisez la méthode [[ComfortUpdate]] qui est censée tout faire pour vous.&lt;br /&gt;
&lt;br /&gt;
=Méthode rapide (pour les changements mineurs de version)=&lt;br /&gt;
&lt;br /&gt;
You can use these instructions if you are doing a minor upgrade  (for example from 2.00 to 2.01)&lt;br /&gt;
*Backup your files and database (did we already mention that?)&lt;br /&gt;
*Delete all the old files/directory except for&lt;br /&gt;
**/application/config/config.php&lt;br /&gt;
**/upload directory&lt;br /&gt;
*Copy the new files from the new LimeSurvey package to the existing location.&lt;br /&gt;
*&#039;&#039;&#039;After the upgrade: Clear your browser cache and cookies!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=La méthode complète (pour les grands sauts de version)=&lt;br /&gt;
&lt;br /&gt;
Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&lt;br /&gt;
&lt;br /&gt;
==Mettre à jour depuis une version 1.50 ou plus vers n&#039;importe quelle version supérieure à 2.xx ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Vérifications après une mise à jour&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;depuis n&#039;importe quelle version précédent la 2.xx&#039;&#039;&#039;: Les &#039;&#039;&#039;gabarits&#039;&#039;&#039; ont subit de nombreux changements. Veuillez vérifier que vos gabarits personnels continuent à vous convenir. Sinon vous devez les ré-éditer (vérifier par rapport aux gabarits originaux ce qui a changé). Le processus de mise à jour tente de remplacer l&#039;inclusion de template.js par l&#039;espace réservé {TEMPLATEJS}. Si vous avez des problèmes javascript avec vos gabarits personnels, vérifier si votre gabarit a l&#039;espace réservé {TEMPLATEJS} dans startpage.pstpl.&lt;br /&gt;
*&#039;&#039;&#039;depuis une version précédent la v1.53&#039;&#039;&#039;: Lors de la mise à jour depuis une version antérieure à la 1.53 vers la dernière version, vérifier les &#039;&#039;&#039;droit globaux de l&#039;utilisateur&#039;&#039;&#039; de chaque utilisateur. Il y a un nouveau droit &#039;&#039;&#039;superadmin&#039;&#039;&#039; introduit dans la version 1.53 qui peut donner à un utilisateur les mêmes droits que le compte d&#039;administrateur créé pendant l&#039;installation. Le script de mise à jour devine à qui donner ces droits dans l&#039;ancienne version. Comme il n&#039;est pas parfait, le résultat doit être soigneusement vérifié.&lt;br /&gt;
&lt;br /&gt;
==Upgrading from version 1.50 or later to any later 1.xx version==&lt;br /&gt;
#[http://www.limesurvey.org/download Download] the desired version of LimeSurvey.&lt;br /&gt;
# Prepare and backup the old installation&lt;br /&gt;
## Backup your installation directory files and SQL-based database just in case.&lt;br /&gt;
### At the command-line level, make a &#039;&#039;&#039;.zip&#039;&#039;&#039; or similar archive of the whole installation directory tree of files. e.g. tar cvzf foo.tgz cps100 will tar and zip the whole of the cps100 directory&lt;br /&gt;
### Using phpMyAdmin or similar to export all tables; or using the &#039;&#039;&#039;LimeSurvey Administration&#039;&#039;&#039; button [[File:button-export-sql.png]] to backup the entire database&lt;br /&gt;
## Copy your &#039;&#039;&#039;config.php&#039;&#039;&#039; file ,modified &#039;&#039;&#039;template&#039;&#039;&#039; directories and the /upload directory separately for quick access later.&lt;br /&gt;
# Replace all the installation directory files&lt;br /&gt;
## Delete all old files in the existing installation directory&lt;br /&gt;
## Upload and unpack the new code version into the same installation directory&lt;br /&gt;
## Edit or replace the &#039;&#039;&#039;config.php&#039;&#039;&#039; file:&lt;br /&gt;
### If your previous version was &amp;lt; 1.70: Edit the new &#039;&#039;&#039;config.php&#039;&#039;&#039; to reflect changed settings in the backup &#039;&#039;&#039;config.php&#039;&#039;&#039; file. &#039;&#039;&#039;Do not just overwrite the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your old one!&#039;&#039;&#039;&lt;br /&gt;
### If your previous version was &amp;gt;= 1.70: Simply replace the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your backup &#039;&#039;&#039;config.php&#039;&#039;&#039; (as the file format has not changed).&lt;br /&gt;
## If your previous version was older than 1.90: Copy any customized templates to /upload/templates - you will also need to rename each template directory whose name matches an existing template in /templates.&lt;br /&gt;
## Copy your /upload directory back to the old location&lt;br /&gt;
## Double check the &#039;&#039;&#039;permissions&#039;&#039;&#039; set on the directories (write access to &#039;&#039;&#039;/tmp&#039;&#039;&#039;, &#039;&#039;&#039;/upload&#039;&#039;&#039; and and their subdirectories is required) as described in [[Installation#Set Directory permissions|Installation]]&lt;br /&gt;
# Finishing the installation&lt;br /&gt;
## Once you open the URL to your LimeSurvey administration the database tables will be updated after confirmation&lt;br /&gt;
## Remove or rename the &#039;&#039;&#039;/admin/install&#039;&#039;&#039; directory as/if instructed by the installation script&lt;br /&gt;
## Check if any special, manual checks apply as listed below&lt;br /&gt;
# You are done (:biggrin:). If you notice any problems after the upgrade: Clear your browser cache and cookies!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Special checks after an upgrade&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;from any earlier version to 1.92&#039;&#039;&#039;: The &#039;&#039;&#039;templates&#039;&#039;&#039; have been changed in a lot of places. Please check your customized templates if they are still looking right. If not you will have to edit your templates accordingly (check out the original templates to see what was changed)&amp;lt;br /&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;from a version earlier than v1.53&#039;&#039;&#039;: When upgrading from a version before v1.53 to the latest version, please check the &#039;&#039;&#039;global user rights&#039;&#039;&#039; of each user. There was a new &#039;&#039;&#039;superadmin&#039;&#039;&#039; right introduced in v1.53 that can give a user the same privilege as the master administration account created during the install. The upgrade script is guessing who to give this right to in the older versions.  As this is not perfect, it should be carefully checked.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Upgrading from a version earlier than v1.50 (v1.0 through v1.44)==&lt;br /&gt;
&lt;br /&gt;
Since the data structure and a lot of other things were changed, &#039;&#039;&#039;upgrading from any version previous to v1.50 is NOT possible&#039;&#039;&#039;.  If you have old survey structure files with a *.sql extension the only way to get these into a newer version is to install [http://www.limesurvey.org/en/archived-releases/289-limesurvey150zip version 1.50], import the .sql file(s) there, then upgrade that version to the most recent LimeSurvey version. See the also then page [[Transferring an installation]] for more details.&lt;br /&gt;
&lt;br /&gt;
=Upgrade FAQ=&lt;br /&gt;
&lt;br /&gt;
==What is the most actual LimeSurvey version that still supports PHP4?==&lt;br /&gt;
&lt;br /&gt;
The last release offering PHP4 support was version 1.82+.&lt;br /&gt;
&lt;br /&gt;
==Can I upgrade even if I have active surveys?==&lt;br /&gt;
&lt;br /&gt;
Yes, you can. Exceptions may be mentioned in the thorough instructions above. We strongly advise to test your surveys after upgrade to check if your design templates still work alright.&lt;br /&gt;
&lt;br /&gt;
==What is best way to port LimeSurvey *.sql survey structure files to the latest version?==&lt;br /&gt;
&lt;br /&gt;
Install version 1.50, import the file and export the survey structure to the newer .csv format. The latest version still can read the .csv survey structure format.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/10/fr&amp;diff=61225</id>
		<title>Translations:Upgrading from a previous version/10/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/10/fr&amp;diff=61225"/>
		<updated>2014-03-26T21:47:38Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Vérifications après une mise à jour&amp;#039;&amp;#039;&amp;#039;: *&amp;#039;&amp;#039;&amp;#039;depuis n&amp;#039;importe quelle version précédent la 2.xx&amp;#039;&amp;#039;&amp;#039;: Les &amp;#039;&amp;#039;&amp;#039;gabarits&amp;#039;&amp;#039;&amp;#039; ont subit de nombreux chang...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Vérifications après une mise à jour&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;depuis n&#039;importe quelle version précédent la 2.xx&#039;&#039;&#039;: Les &#039;&#039;&#039;gabarits&#039;&#039;&#039; ont subit de nombreux changements. Veuillez vérifier que vos gabarits personnels continuent à vous convenir. Sinon vous devez les ré-éditer (vérifier par rapport aux gabarits originaux ce qui a changé). Le processus de mise à jour tente de remplacer l&#039;inclusion de template.js par l&#039;espace réservé {TEMPLATEJS}. Si vous avez des problèmes javascript avec vos gabarits personnels, vérifier si votre gabarit a l&#039;espace réservé {TEMPLATEJS} dans startpage.pstpl.&lt;br /&gt;
*&#039;&#039;&#039;depuis une version précédent la v1.53&#039;&#039;&#039;: Lors de la mise à jour depuis une version antérieure à la 1.53 vers la dernière version, vérifier les &#039;&#039;&#039;droit globaux de l&#039;utilisateur&#039;&#039;&#039; de chaque utilisateur. Il y a un nouveau droit &#039;&#039;&#039;superadmin&#039;&#039;&#039; introduit dans la version 1.53 qui peut donner à un utilisateur les mêmes droits que le compte d&#039;administrateur créé pendant l&#039;installation. Le script de mise à jour devine à qui donner ces droits dans l&#039;ancienne version. Comme il n&#039;est pas parfait, le résultat doit être soigneusement vérifié.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61224</id>
		<title>Upgrading from a previous version/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61224"/>
		<updated>2014-03-26T21:31:31Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;==Mettre à jour depuis une version 1.50 ou plus vers n&amp;#039;importe quelle version supérieure à 2.xx ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;La traduction de cette page n&#039;est pas terminée.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avant de commencer...=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;... lisez ceci car c&#039;est très important: &#039;&#039;&#039;Ne jamais oublier de faire une sauvegarde des fichiers et de la base de données de votre installation actuelle!!&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vous pouvez le faire en utilisant les outils d&#039;administration de la base de données comme [http://www.phpmyadmin.net phpMyAdmin] etc. et un gestionnaire de fichiers! Si vous ne savez pas comment procéder pour faire les sauvegardes des fichiers et de la base, alors vous devez demander à quelqu&#039;un de le faire pour vous ou de vous l&#039;apprendre ou alors utilisez la méthode [[ComfortUpdate]] qui est censée tout faire pour vous.&lt;br /&gt;
&lt;br /&gt;
=Méthode rapide (pour les changements mineurs de version)=&lt;br /&gt;
&lt;br /&gt;
You can use these instructions if you are doing a minor upgrade  (for example from 2.00 to 2.01)&lt;br /&gt;
*Backup your files and database (did we already mention that?)&lt;br /&gt;
*Delete all the old files/directory except for&lt;br /&gt;
**/application/config/config.php&lt;br /&gt;
**/upload directory&lt;br /&gt;
*Copy the new files from the new LimeSurvey package to the existing location.&lt;br /&gt;
*&#039;&#039;&#039;After the upgrade: Clear your browser cache and cookies!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=La méthode complète (pour les grands sauts de version)=&lt;br /&gt;
&lt;br /&gt;
Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&lt;br /&gt;
&lt;br /&gt;
==Mettre à jour depuis une version 1.50 ou plus vers n&#039;importe quelle version supérieure à 2.xx ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Special checks after an upgrade&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;from any earlier version to 2.xx&#039;&#039;&#039;: The &#039;&#039;&#039;templates&#039;&#039;&#039; have been changed in a lot of places. Please check your customized templates if they are still looking right. If not you will have to edit your templates accordingly (check out the original templates to see what was changed). The upgrade process tries to replace the template.js inclusion by the placeholder {TEMPLATEJS}. If you have javascript issue with your custom template, verify if your template have the placeholder {TEMPLATEJS} in startpage.pstpl.&lt;br /&gt;
*&#039;&#039;&#039;from a version earlier than v1.53&#039;&#039;&#039;: When upgrading from a version before v1.53 to the latest version, please check the &#039;&#039;&#039;global user rights&#039;&#039;&#039; of each user. There was a new &#039;&#039;&#039;superadmin&#039;&#039;&#039; right introduced in v1.53 that can give a user the same privilege as the master administration account created during the install. The upgrade script is guessing who to give this right to in the older versions.  As this is not perfect, it should be carefully checked.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Upgrading from version 1.50 or later to any later 1.xx version==&lt;br /&gt;
#[http://www.limesurvey.org/download Download] the desired version of LimeSurvey.&lt;br /&gt;
# Prepare and backup the old installation&lt;br /&gt;
## Backup your installation directory files and SQL-based database just in case.&lt;br /&gt;
### At the command-line level, make a &#039;&#039;&#039;.zip&#039;&#039;&#039; or similar archive of the whole installation directory tree of files. e.g. tar cvzf foo.tgz cps100 will tar and zip the whole of the cps100 directory&lt;br /&gt;
### Using phpMyAdmin or similar to export all tables; or using the &#039;&#039;&#039;LimeSurvey Administration&#039;&#039;&#039; button [[File:button-export-sql.png]] to backup the entire database&lt;br /&gt;
## Copy your &#039;&#039;&#039;config.php&#039;&#039;&#039; file ,modified &#039;&#039;&#039;template&#039;&#039;&#039; directories and the /upload directory separately for quick access later.&lt;br /&gt;
# Replace all the installation directory files&lt;br /&gt;
## Delete all old files in the existing installation directory&lt;br /&gt;
## Upload and unpack the new code version into the same installation directory&lt;br /&gt;
## Edit or replace the &#039;&#039;&#039;config.php&#039;&#039;&#039; file:&lt;br /&gt;
### If your previous version was &amp;lt; 1.70: Edit the new &#039;&#039;&#039;config.php&#039;&#039;&#039; to reflect changed settings in the backup &#039;&#039;&#039;config.php&#039;&#039;&#039; file. &#039;&#039;&#039;Do not just overwrite the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your old one!&#039;&#039;&#039;&lt;br /&gt;
### If your previous version was &amp;gt;= 1.70: Simply replace the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your backup &#039;&#039;&#039;config.php&#039;&#039;&#039; (as the file format has not changed).&lt;br /&gt;
## If your previous version was older than 1.90: Copy any customized templates to /upload/templates - you will also need to rename each template directory whose name matches an existing template in /templates.&lt;br /&gt;
## Copy your /upload directory back to the old location&lt;br /&gt;
## Double check the &#039;&#039;&#039;permissions&#039;&#039;&#039; set on the directories (write access to &#039;&#039;&#039;/tmp&#039;&#039;&#039;, &#039;&#039;&#039;/upload&#039;&#039;&#039; and and their subdirectories is required) as described in [[Installation#Set Directory permissions|Installation]]&lt;br /&gt;
# Finishing the installation&lt;br /&gt;
## Once you open the URL to your LimeSurvey administration the database tables will be updated after confirmation&lt;br /&gt;
## Remove or rename the &#039;&#039;&#039;/admin/install&#039;&#039;&#039; directory as/if instructed by the installation script&lt;br /&gt;
## Check if any special, manual checks apply as listed below&lt;br /&gt;
# You are done (:biggrin:). If you notice any problems after the upgrade: Clear your browser cache and cookies!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Special checks after an upgrade&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;from any earlier version to 1.92&#039;&#039;&#039;: The &#039;&#039;&#039;templates&#039;&#039;&#039; have been changed in a lot of places. Please check your customized templates if they are still looking right. If not you will have to edit your templates accordingly (check out the original templates to see what was changed)&amp;lt;br /&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;from a version earlier than v1.53&#039;&#039;&#039;: When upgrading from a version before v1.53 to the latest version, please check the &#039;&#039;&#039;global user rights&#039;&#039;&#039; of each user. There was a new &#039;&#039;&#039;superadmin&#039;&#039;&#039; right introduced in v1.53 that can give a user the same privilege as the master administration account created during the install. The upgrade script is guessing who to give this right to in the older versions.  As this is not perfect, it should be carefully checked.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Upgrading from a version earlier than v1.50 (v1.0 through v1.44)==&lt;br /&gt;
&lt;br /&gt;
Since the data structure and a lot of other things were changed, &#039;&#039;&#039;upgrading from any version previous to v1.50 is NOT possible&#039;&#039;&#039;.  If you have old survey structure files with a *.sql extension the only way to get these into a newer version is to install [http://www.limesurvey.org/en/archived-releases/289-limesurvey150zip version 1.50], import the .sql file(s) there, then upgrade that version to the most recent LimeSurvey version. See the also then page [[Transferring an installation]] for more details.&lt;br /&gt;
&lt;br /&gt;
=Upgrade FAQ=&lt;br /&gt;
&lt;br /&gt;
==What is the most actual LimeSurvey version that still supports PHP4?==&lt;br /&gt;
&lt;br /&gt;
The last release offering PHP4 support was version 1.82+.&lt;br /&gt;
&lt;br /&gt;
==Can I upgrade even if I have active surveys?==&lt;br /&gt;
&lt;br /&gt;
Yes, you can. Exceptions may be mentioned in the thorough instructions above. We strongly advise to test your surveys after upgrade to check if your design templates still work alright.&lt;br /&gt;
&lt;br /&gt;
==What is best way to port LimeSurvey *.sql survey structure files to the latest version?==&lt;br /&gt;
&lt;br /&gt;
Install version 1.50, import the file and export the survey structure to the newer .csv format. The latest version still can read the .csv survey structure format.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/9/fr&amp;diff=61223</id>
		<title>Translations:Upgrading from a previous version/9/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/9/fr&amp;diff=61223"/>
		<updated>2014-03-26T21:31:30Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;==Mettre à jour depuis une version 1.50 ou plus vers n&amp;#039;importe quelle version supérieure à 2.xx ==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Mettre à jour depuis une version 1.50 ou plus vers n&#039;importe quelle version supérieure à 2.xx ==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61222</id>
		<title>Upgrading from a previous version/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Upgrading_from_a_previous_version/fr&amp;diff=61222"/>
		<updated>2014-03-26T21:29:52Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;La traduction de cette page n&#039;est pas terminée.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Avant de commencer...=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;... lisez ceci car c&#039;est très important: &#039;&#039;&#039;Ne jamais oublier de faire une sauvegarde des fichiers et de la base de données de votre installation actuelle!!&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vous pouvez le faire en utilisant les outils d&#039;administration de la base de données comme [http://www.phpmyadmin.net phpMyAdmin] etc. et un gestionnaire de fichiers! Si vous ne savez pas comment procéder pour faire les sauvegardes des fichiers et de la base, alors vous devez demander à quelqu&#039;un de le faire pour vous ou de vous l&#039;apprendre ou alors utilisez la méthode [[ComfortUpdate]] qui est censée tout faire pour vous.&lt;br /&gt;
&lt;br /&gt;
=Méthode rapide (pour les changements mineurs de version)=&lt;br /&gt;
&lt;br /&gt;
You can use these instructions if you are doing a minor upgrade  (for example from 2.00 to 2.01)&lt;br /&gt;
*Backup your files and database (did we already mention that?)&lt;br /&gt;
*Delete all the old files/directory except for&lt;br /&gt;
**/application/config/config.php&lt;br /&gt;
**/upload directory&lt;br /&gt;
*Copy the new files from the new LimeSurvey package to the existing location.&lt;br /&gt;
*&#039;&#039;&#039;After the upgrade: Clear your browser cache and cookies!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=La méthode complète (pour les grands sauts de version)=&lt;br /&gt;
&lt;br /&gt;
Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&lt;br /&gt;
&lt;br /&gt;
==Upgrading from version 1.50 or later to any later 2.xx version==&lt;br /&gt;
#[http://www.limesurvey.org/download Download] the latest version of LimeSurvey.&lt;br /&gt;
# Prepare and backup the old installation&lt;br /&gt;
## Backup your installation directory files and SQL-based database just in case.&lt;br /&gt;
### At the command-line level, make a &#039;&#039;&#039;.zip&#039;&#039;&#039; or similar archive of the whole installation directory tree of files. For example in Linux tar cvzf foo.tgz cps100 will tar and zip the whole of the cps100 directory.&lt;br /&gt;
### Using phpMyAdmin or similar to export all tables; or use the according &#039;&#039;&#039;LimeSurvey Administration&#039;&#039;&#039; button [[File:button-export-sql.png]] to backup the entire database&lt;br /&gt;
## Copy your &#039;&#039;&#039;config.php&#039;&#039;&#039; file, modified &#039;&#039;&#039;template&#039;&#039;&#039; directories and the /upload directory separately for quick access later.&lt;br /&gt;
# Replace all the installation directory files&lt;br /&gt;
## Delete all old files in the existing installation directory&lt;br /&gt;
## Upload and unpack the new code version into the same installation directory&lt;br /&gt;
## If your previous version was older than 1.90: Copy any customized templates to /upload/templates - you will also need to rename each template directory whose name matches an existing template in /templates.&lt;br /&gt;
## Copy your /upload directory back to the old location&lt;br /&gt;
## Double check the &#039;&#039;&#039;permissions&#039;&#039;&#039; set on the directories (write access to &#039;&#039;&#039;/tmp&#039;&#039;&#039;, &#039;&#039;&#039;/upload&#039;&#039;&#039; and and their subdirectories is required) as described in [[Installation#Set_Directory_permissions|Installation]]&lt;br /&gt;
## Open http://&amp;lt;yourdomain&amp;gt;/&amp;lt;yourlimesurveydir&amp;gt;/admin in your browser and follow the instructions (you can use the old config.php as reference). The existing database will be automatically detected and , if necessary, upgraded after confirmation.&lt;br /&gt;
# Check if any special manual checks apply as listed below&lt;br /&gt;
# &#039;&#039;&#039;Now clear your browser cache and cookies!&#039;&#039;&#039;&lt;br /&gt;
# You are done (:biggrin:).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Special checks after an upgrade&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;from any earlier version to 2.xx&#039;&#039;&#039;: The &#039;&#039;&#039;templates&#039;&#039;&#039; have been changed in a lot of places. Please check your customized templates if they are still looking right. If not you will have to edit your templates accordingly (check out the original templates to see what was changed). The upgrade process tries to replace the template.js inclusion by the placeholder {TEMPLATEJS}. If you have javascript issue with your custom template, verify if your template have the placeholder {TEMPLATEJS} in startpage.pstpl.&lt;br /&gt;
*&#039;&#039;&#039;from a version earlier than v1.53&#039;&#039;&#039;: When upgrading from a version before v1.53 to the latest version, please check the &#039;&#039;&#039;global user rights&#039;&#039;&#039; of each user. There was a new &#039;&#039;&#039;superadmin&#039;&#039;&#039; right introduced in v1.53 that can give a user the same privilege as the master administration account created during the install. The upgrade script is guessing who to give this right to in the older versions.  As this is not perfect, it should be carefully checked.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Upgrading from version 1.50 or later to any later 1.xx version==&lt;br /&gt;
#[http://www.limesurvey.org/download Download] the desired version of LimeSurvey.&lt;br /&gt;
# Prepare and backup the old installation&lt;br /&gt;
## Backup your installation directory files and SQL-based database just in case.&lt;br /&gt;
### At the command-line level, make a &#039;&#039;&#039;.zip&#039;&#039;&#039; or similar archive of the whole installation directory tree of files. e.g. tar cvzf foo.tgz cps100 will tar and zip the whole of the cps100 directory&lt;br /&gt;
### Using phpMyAdmin or similar to export all tables; or using the &#039;&#039;&#039;LimeSurvey Administration&#039;&#039;&#039; button [[File:button-export-sql.png]] to backup the entire database&lt;br /&gt;
## Copy your &#039;&#039;&#039;config.php&#039;&#039;&#039; file ,modified &#039;&#039;&#039;template&#039;&#039;&#039; directories and the /upload directory separately for quick access later.&lt;br /&gt;
# Replace all the installation directory files&lt;br /&gt;
## Delete all old files in the existing installation directory&lt;br /&gt;
## Upload and unpack the new code version into the same installation directory&lt;br /&gt;
## Edit or replace the &#039;&#039;&#039;config.php&#039;&#039;&#039; file:&lt;br /&gt;
### If your previous version was &amp;lt; 1.70: Edit the new &#039;&#039;&#039;config.php&#039;&#039;&#039; to reflect changed settings in the backup &#039;&#039;&#039;config.php&#039;&#039;&#039; file. &#039;&#039;&#039;Do not just overwrite the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your old one!&#039;&#039;&#039;&lt;br /&gt;
### If your previous version was &amp;gt;= 1.70: Simply replace the new &#039;&#039;&#039;config.php&#039;&#039;&#039; with your backup &#039;&#039;&#039;config.php&#039;&#039;&#039; (as the file format has not changed).&lt;br /&gt;
## If your previous version was older than 1.90: Copy any customized templates to /upload/templates - you will also need to rename each template directory whose name matches an existing template in /templates.&lt;br /&gt;
## Copy your /upload directory back to the old location&lt;br /&gt;
## Double check the &#039;&#039;&#039;permissions&#039;&#039;&#039; set on the directories (write access to &#039;&#039;&#039;/tmp&#039;&#039;&#039;, &#039;&#039;&#039;/upload&#039;&#039;&#039; and and their subdirectories is required) as described in [[Installation#Set Directory permissions|Installation]]&lt;br /&gt;
# Finishing the installation&lt;br /&gt;
## Once you open the URL to your LimeSurvey administration the database tables will be updated after confirmation&lt;br /&gt;
## Remove or rename the &#039;&#039;&#039;/admin/install&#039;&#039;&#039; directory as/if instructed by the installation script&lt;br /&gt;
## Check if any special, manual checks apply as listed below&lt;br /&gt;
# You are done (:biggrin:). If you notice any problems after the upgrade: Clear your browser cache and cookies!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Special checks after an upgrade&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;from any earlier version to 1.92&#039;&#039;&#039;: The &#039;&#039;&#039;templates&#039;&#039;&#039; have been changed in a lot of places. Please check your customized templates if they are still looking right. If not you will have to edit your templates accordingly (check out the original templates to see what was changed)&amp;lt;br /&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;from a version earlier than v1.53&#039;&#039;&#039;: When upgrading from a version before v1.53 to the latest version, please check the &#039;&#039;&#039;global user rights&#039;&#039;&#039; of each user. There was a new &#039;&#039;&#039;superadmin&#039;&#039;&#039; right introduced in v1.53 that can give a user the same privilege as the master administration account created during the install. The upgrade script is guessing who to give this right to in the older versions.  As this is not perfect, it should be carefully checked.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Upgrading from a version earlier than v1.50 (v1.0 through v1.44)==&lt;br /&gt;
&lt;br /&gt;
Since the data structure and a lot of other things were changed, &#039;&#039;&#039;upgrading from any version previous to v1.50 is NOT possible&#039;&#039;&#039;.  If you have old survey structure files with a *.sql extension the only way to get these into a newer version is to install [http://www.limesurvey.org/en/archived-releases/289-limesurvey150zip version 1.50], import the .sql file(s) there, then upgrade that version to the most recent LimeSurvey version. See the also then page [[Transferring an installation]] for more details.&lt;br /&gt;
&lt;br /&gt;
=Upgrade FAQ=&lt;br /&gt;
&lt;br /&gt;
==What is the most actual LimeSurvey version that still supports PHP4?==&lt;br /&gt;
&lt;br /&gt;
The last release offering PHP4 support was version 1.82+.&lt;br /&gt;
&lt;br /&gt;
==Can I upgrade even if I have active surveys?==&lt;br /&gt;
&lt;br /&gt;
Yes, you can. Exceptions may be mentioned in the thorough instructions above. We strongly advise to test your surveys after upgrade to check if your design templates still work alright.&lt;br /&gt;
&lt;br /&gt;
==What is best way to port LimeSurvey *.sql survey structure files to the latest version?==&lt;br /&gt;
&lt;br /&gt;
Install version 1.50, import the file and export the survey structure to the newer .csv format. The latest version still can read the .csv survey structure format.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/8/fr&amp;diff=61221</id>
		<title>Translations:Upgrading from a previous version/8/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Upgrading_from_a_previous_version/8/fr&amp;diff=61221"/>
		<updated>2014-03-26T21:29:52Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Malheureusement il y a quelques petites choses à faire, par conséquent veuillez suivre attentivement les instructions suivantes&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61220</id>
		<title>Global settings/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61220"/>
		<updated>2014-03-26T21:22:27Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Description générale=&lt;br /&gt;
&lt;br /&gt;
Si vous cliquez sur l&#039;icône [[File:global.png]] dans la barre d&#039;outils principale vous arriverez sur les paramètres généraux. L&#039;accès aux paramètres généraux est réservé aux utilisateurs avec des droits de &amp;quot;Super administrateur&amp;quot;. Ceux-ci peuvent permettre d&#039;ajuster certains réglages de LimeSurvey d&#039;une manière globale. Dans les versions antérieures à 1.87, ces [[réglages optionnels]] n&#039;étaient disponibles qu&#039;en modifiant le fichier config.php ou config-default.php. Depuis la version 1.87, les valeurs dans ces fichiers sont simplement les valeurs utilisées par défaut. Une fois que vous serez entré dans l&#039;écran des paramètres généraux et que vous aurez fait une première sauvegarde, ces valeurs seront remplacées par celles dans les paramètres généraux&lt;br /&gt;
&lt;br /&gt;
=Paramètres et leurs explications=&lt;br /&gt;
&lt;br /&gt;
==Overview &amp;amp; Update==&lt;br /&gt;
*&#039;&#039;&#039;System overview&#039;&#039;&#039;: This is pretty much self explaining. Here you can get a short insight on the number of surveys and other statistics in your LimeSurvey installation. For debug purposes you can also find a button to show your PHP Info.&lt;br /&gt;
*&#039;&#039;&#039;Updates&#039;&#039;&#039;:&lt;br /&gt;
:[[File:Update_check_settings.jpg]]&lt;br /&gt;
&lt;br /&gt;
:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Actualiser à partir d&#039;une version précédente|Instructions de mise à jour]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Donnez un nom à votre questionnaire. Ce nom apparaîtra dans la liste des questionnaires et dans l&#039;en-tête de l&#039;administration.&lt;br /&gt;
*&#039;&#039;&#039;Default language&#039;&#039;&#039;: La langue qui sera utilisée par défaut aussi bien pour votre administration de l&#039;enquête que pour le public qui va y répondre si aucune autre langue n&#039;est choisie.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: Le choix de cette préférence indiquera quel gabarit(&amp;quot;template&amp;quot;) sera utilisé par les répondants de votre enquête ou questionnaire ainsi que pour l&#039;élaboration des nouveaux questionnaires si aucun autre gabarit n&#039;est choisi.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Spécifie le mode par défaut pour l&#039;éditeur HTML intégré. Les choix possibles sont: éditeur HTML en ligne (default), éditeur HTML dans une popup et aucun:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Lent mais facile et pratique&lt;br /&gt;
** &#039;&#039;éditeur HTML dans une popup&#039;&#039;: Ajoute une icône permettant d&#039;ouvrir une fenêtre avec l&#039;éditeur HTML. Plus rapide mais le code HTML est affiché on the form.&lt;br /&gt;
** &#039;&#039;aucun&#039;&#039;: Pas d&#039;éditeur HTML&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;PDF export available:&#039;&#039;&#039; This feature activates the PDF export for the &#039;Printable survey&#039; feature and data export.&lt;br /&gt;
*&#039;&#039;&#039;Screen reader compatibility mode&#039;&#039;&#039;: If this option is set to true, then LimeSurvey will add &#039;title&#039; html element to all links used in menus. This will help screen reader to analyze the menus. Only set this to true if you&#039;re using a screen reader because it overlaps with tool tips.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. Depending on your server configuration LimeSurvey may not be allowed to override the server setting - in that case you have to set the session timeout value in your PHP configuration.&lt;br /&gt;
&lt;br /&gt;
==Paramètre de messagerie==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: C&#039;est l&#039;adresse par défaut de l&#039;administrateur du site, utilisée pour les messages système et les options de contact.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: Le nom &amp;quot;réel&amp;quot; de l&#039;administrateur du site.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  Détermine comment les emails sont envoyés. Les options suivantes sont disponibles:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; utilise les fonctions PHP internes&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; utilise sendmail&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;utilise un relai smtp. Il faut utiliser cette option si on fait tourner Limesurvey sur une machine qui n&#039;est pas notre serveur de mail.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: Si vous activer ceci alors au moment d&#039;envoyer les invitations ou les rappels un log détaillé de connection et un message d&#039;erreur (si une erreru se produit) vous sont fournis. Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Généralement ce switch reste à Off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;br /&gt;
&lt;br /&gt;
==Bounce settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site bounce email&#039;&#039;&#039;: This is the email address where bounced emails will be sent to.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: If set to &#039;Off&#039; no bounce processing functions will be available. Set this to POP or IMAP to check a related account for bounces. &lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;: Name of the server and (if needed) the port separated by a colon.&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;: The user name for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;: The password for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;: If encrpytion is used please set the right one here (SSL or TLS)&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
*&#039;&#039;&#039;Survey preview only for administration users&#039;&#039;&#039;: By default, preview of inactive survey is restricted to authenticated users only. If you set this to &#039;No&#039; any person can test your survey using the survey URL - without logging in to the administration and without having to activate the survey first.&lt;br /&gt;
*&#039;&#039;&#039;Filter HTML for XSS&#039;&#039;&#039;: By default you survey manager will not be authorized to use dangerous HTML tags in their survey/group/question/labels texts (for instance JavaScript code). This is intended to prevent a survey operator to add malicious script in order to have a true admin raise his permissions on the system. &#039;&#039;&#039;If you want to use any script objects like Javascript scripts of Flash applets in your surveys you will need to switch this off.&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Group member can only see own group&#039;&#039;&#039;: By default non-admin users defined in the LimeSurvey management interface will only be able to see other users if they belong to at least one group this user belongs to. If you set this to &#039;No&#039; they can see all users (for example in [[Survey security settings]] )&lt;br /&gt;
*&#039;&#039;&#039;Force HTTPS&#039;&#039;&#039;: By default this is set to &amp;quot;Don&#039;t force on or off&amp;quot;. Switch the setting to &amp;quot;on&amp;quot; to force the connection to use HTTPS. &#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; If your server doesn&#039;t support HTTPS properly, you can lock yourself from the system! Therefor test the &amp;quot;check if this link works&amp;quot; link first. If the link does not work and you turn on HTTPS, LimeSurvey will break and you won&#039;t be able to access it.&lt;br /&gt;
&lt;br /&gt;
==Presentation==&lt;br /&gt;
*&#039;&#039;&#039;Show &#039;no answer&#039; option for non-mandatory questions&#039;&#039;&#039;: When a question of a radio button/select type that contains editable answers (i.e.: List &amp;amp; array questions) is not mandatory and this is set to &#039;Yes&#039; (default), an additional entry &#039;No answer&#039; is shown for each subquestion - so that participants may choose to not answer the question. Some people prefer this not to be available. Set this to &#039;No&#039; to turn this off.&lt;br /&gt;
*&#039;&#039;&#039;Repeating headings in array questions every X subquestions&#039;&#039;&#039;: With array type question, often you&#039;ll have a lot of subquestions, which - when displayed on screen - take up more than one page. The repeat-headers setting lets you decide how many answers should be displayed before repeating the header information for the question. A good setting for this is around 25. If you don&#039;t want the headings to repeat at all, set this to 0.&lt;br /&gt;
*&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question group name and/or description&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question number and/or question code&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==Language==&lt;br /&gt;
*&#039;&#039;&#039;Default site language&#039;&#039;&#039;: This is the default language to be used in your administration , and also the default language for the public survey list if none is given.&lt;br /&gt;
*&#039;&#039;&#039;Available languages&#039;&#039;&#039;: If you don&#039;t want all languages to be available in the administration language select boxes you can here define the language that should be available only.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
*&#039;&#039;&#039;RPC interface enabled&#039;&#039;&#039;: Using this feature you can activate/deactivate the LimeSurvey [[RemoteControl 2 API|RemoteControl2]] interface API, either using JSON-RPC (recommended) or XML-RPC.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61219</id>
		<title>Translations:Global settings/13/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61219"/>
		<updated>2014-03-26T21:22:26Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Actualiser à partir d&#039;une version précédente|Instructions de mise à jour]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61218</id>
		<title>Global settings/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61218"/>
		<updated>2014-03-26T18:00:55Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;==Paramètre de messagerie== *&amp;#039;&amp;#039;&amp;#039;Default site admin email&amp;#039;&amp;#039;&amp;#039;: C&amp;#039;est l&amp;#039;adresse par défaut de l&amp;#039;administrateur du site, utilisée pour les messages système et les options de c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Description générale=&lt;br /&gt;
&lt;br /&gt;
Si vous cliquez sur l&#039;icône [[File:global.png]] dans la barre d&#039;outils principale vous arriverez sur les paramètres généraux. L&#039;accès aux paramètres généraux est réservé aux utilisateurs avec des droits de &amp;quot;Super administrateur&amp;quot;. Ceux-ci peuvent permettre d&#039;ajuster certains réglages de LimeSurvey d&#039;une manière globale. Dans les versions antérieures à 1.87, ces [[réglages optionnels]] n&#039;étaient disponibles qu&#039;en modifiant le fichier config.php ou config-default.php. Depuis la version 1.87, les valeurs dans ces fichiers sont simplement les valeurs utilisées par défaut. Une fois que vous serez entré dans l&#039;écran des paramètres généraux et que vous aurez fait une première sauvegarde, ces valeurs seront remplacées par celles dans les paramètres généraux&lt;br /&gt;
&lt;br /&gt;
=Paramètres et leurs explications=&lt;br /&gt;
&lt;br /&gt;
==Overview &amp;amp; Update==&lt;br /&gt;
*&#039;&#039;&#039;System overview&#039;&#039;&#039;: This is pretty much self explaining. Here you can get a short insight on the number of surveys and other statistics in your LimeSurvey installation. For debug purposes you can also find a button to show your PHP Info.&lt;br /&gt;
*&#039;&#039;&#039;Updates&#039;&#039;&#039;:&lt;br /&gt;
:[[File:Update_check_settings.jpg]]&lt;br /&gt;
&lt;br /&gt;
:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Donnez un nom à votre questionnaire. Ce nom apparaîtra dans la liste des questionnaires et dans l&#039;en-tête de l&#039;administration.&lt;br /&gt;
*&#039;&#039;&#039;Default language&#039;&#039;&#039;: La langue qui sera utilisée par défaut aussi bien pour votre administration de l&#039;enquête que pour le public qui va y répondre si aucune autre langue n&#039;est choisie.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: Le choix de cette préférence indiquera quel gabarit(&amp;quot;template&amp;quot;) sera utilisé par les répondants de votre enquête ou questionnaire ainsi que pour l&#039;élaboration des nouveaux questionnaires si aucun autre gabarit n&#039;est choisi.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Spécifie le mode par défaut pour l&#039;éditeur HTML intégré. Les choix possibles sont: éditeur HTML en ligne (default), éditeur HTML dans une popup et aucun:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Lent mais facile et pratique&lt;br /&gt;
** &#039;&#039;éditeur HTML dans une popup&#039;&#039;: Ajoute une icône permettant d&#039;ouvrir une fenêtre avec l&#039;éditeur HTML. Plus rapide mais le code HTML est affiché on the form.&lt;br /&gt;
** &#039;&#039;aucun&#039;&#039;: Pas d&#039;éditeur HTML&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;PDF export available:&#039;&#039;&#039; This feature activates the PDF export for the &#039;Printable survey&#039; feature and data export.&lt;br /&gt;
*&#039;&#039;&#039;Screen reader compatibility mode&#039;&#039;&#039;: If this option is set to true, then LimeSurvey will add &#039;title&#039; html element to all links used in menus. This will help screen reader to analyze the menus. Only set this to true if you&#039;re using a screen reader because it overlaps with tool tips.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. Depending on your server configuration LimeSurvey may not be allowed to override the server setting - in that case you have to set the session timeout value in your PHP configuration.&lt;br /&gt;
&lt;br /&gt;
==Paramètre de messagerie==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: C&#039;est l&#039;adresse par défaut de l&#039;administrateur du site, utilisée pour les messages système et les options de contact.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: Le nom &amp;quot;réel&amp;quot; de l&#039;administrateur du site.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  Détermine comment les emails sont envoyés. Les options suivantes sont disponibles:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; utilise les fonctions PHP internes&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; utilise sendmail&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;utilise un relai smtp. Il faut utiliser cette option si on fait tourner Limesurvey sur une machine qui n&#039;est pas notre serveur de mail.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: Si vous activer ceci alors au moment d&#039;envoyer les invitations ou les rappels un log détaillé de connection et un message d&#039;erreur (si une erreru se produit) vous sont fournis. Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Généralement ce switch reste à Off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;br /&gt;
&lt;br /&gt;
==Bounce settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site bounce email&#039;&#039;&#039;: This is the email address where bounced emails will be sent to.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: If set to &#039;Off&#039; no bounce processing functions will be available. Set this to POP or IMAP to check a related account for bounces. &lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;: Name of the server and (if needed) the port separated by a colon.&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;: The user name for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;: The password for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;: If encrpytion is used please set the right one here (SSL or TLS)&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
*&#039;&#039;&#039;Survey preview only for administration users&#039;&#039;&#039;: By default, preview of inactive survey is restricted to authenticated users only. If you set this to &#039;No&#039; any person can test your survey using the survey URL - without logging in to the administration and without having to activate the survey first.&lt;br /&gt;
*&#039;&#039;&#039;Filter HTML for XSS&#039;&#039;&#039;: By default you survey manager will not be authorized to use dangerous HTML tags in their survey/group/question/labels texts (for instance JavaScript code). This is intended to prevent a survey operator to add malicious script in order to have a true admin raise his permissions on the system. &#039;&#039;&#039;If you want to use any script objects like Javascript scripts of Flash applets in your surveys you will need to switch this off.&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Group member can only see own group&#039;&#039;&#039;: By default non-admin users defined in the LimeSurvey management interface will only be able to see other users if they belong to at least one group this user belongs to. If you set this to &#039;No&#039; they can see all users (for example in [[Survey security settings]] )&lt;br /&gt;
*&#039;&#039;&#039;Force HTTPS&#039;&#039;&#039;: By default this is set to &amp;quot;Don&#039;t force on or off&amp;quot;. Switch the setting to &amp;quot;on&amp;quot; to force the connection to use HTTPS. &#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; If your server doesn&#039;t support HTTPS properly, you can lock yourself from the system! Therefor test the &amp;quot;check if this link works&amp;quot; link first. If the link does not work and you turn on HTTPS, LimeSurvey will break and you won&#039;t be able to access it.&lt;br /&gt;
&lt;br /&gt;
==Presentation==&lt;br /&gt;
*&#039;&#039;&#039;Show &#039;no answer&#039; option for non-mandatory questions&#039;&#039;&#039;: When a question of a radio button/select type that contains editable answers (i.e.: List &amp;amp; array questions) is not mandatory and this is set to &#039;Yes&#039; (default), an additional entry &#039;No answer&#039; is shown for each subquestion - so that participants may choose to not answer the question. Some people prefer this not to be available. Set this to &#039;No&#039; to turn this off.&lt;br /&gt;
*&#039;&#039;&#039;Repeating headings in array questions every X subquestions&#039;&#039;&#039;: With array type question, often you&#039;ll have a lot of subquestions, which - when displayed on screen - take up more than one page. The repeat-headers setting lets you decide how many answers should be displayed before repeating the header information for the question. A good setting for this is around 25. If you don&#039;t want the headings to repeat at all, set this to 0.&lt;br /&gt;
*&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question group name and/or description&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question number and/or question code&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==Language==&lt;br /&gt;
*&#039;&#039;&#039;Default site language&#039;&#039;&#039;: This is the default language to be used in your administration , and also the default language for the public survey list if none is given.&lt;br /&gt;
*&#039;&#039;&#039;Available languages&#039;&#039;&#039;: If you don&#039;t want all languages to be available in the administration language select boxes you can here define the language that should be available only.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
*&#039;&#039;&#039;RPC interface enabled&#039;&#039;&#039;: Using this feature you can activate/deactivate the LimeSurvey [[RemoteControl 2 API|RemoteControl2]] interface API, either using JSON-RPC (recommended) or XML-RPC.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/7/fr&amp;diff=61217</id>
		<title>Translations:Global settings/7/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/7/fr&amp;diff=61217"/>
		<updated>2014-03-26T18:00:55Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;==Paramètre de messagerie== *&amp;#039;&amp;#039;&amp;#039;Default site admin email&amp;#039;&amp;#039;&amp;#039;: C&amp;#039;est l&amp;#039;adresse par défaut de l&amp;#039;administrateur du site, utilisée pour les messages système et les options de c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Paramètre de messagerie==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: C&#039;est l&#039;adresse par défaut de l&#039;administrateur du site, utilisée pour les messages système et les options de contact.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: Le nom &amp;quot;réel&amp;quot; de l&#039;administrateur du site.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  Détermine comment les emails sont envoyés. Les options suivantes sont disponibles:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; utilise les fonctions PHP internes&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; utilise sendmail&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;utilise un relai smtp. Il faut utiliser cette option si on fait tourner Limesurvey sur une machine qui n&#039;est pas notre serveur de mail.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: Si vous activer ceci alors au moment d&#039;envoyer les invitations ou les rappels un log détaillé de connection et un message d&#039;erreur (si une erreru se produit) vous sont fournis. Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Généralement ce switch reste à Off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61216</id>
		<title>Global settings/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61216"/>
		<updated>2014-03-26T16:26:34Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Description générale=&lt;br /&gt;
&lt;br /&gt;
Si vous cliquez sur l&#039;icône [[File:global.png]] dans la barre d&#039;outils principale vous arriverez sur les paramètres généraux. L&#039;accès aux paramètres généraux est réservé aux utilisateurs avec des droits de &amp;quot;Super administrateur&amp;quot;. Ceux-ci peuvent permettre d&#039;ajuster certains réglages de LimeSurvey d&#039;une manière globale. Dans les versions antérieures à 1.87, ces [[réglages optionnels]] n&#039;étaient disponibles qu&#039;en modifiant le fichier config.php ou config-default.php. Depuis la version 1.87, les valeurs dans ces fichiers sont simplement les valeurs utilisées par défaut. Une fois que vous serez entré dans l&#039;écran des paramètres généraux et que vous aurez fait une première sauvegarde, ces valeurs seront remplacées par celles dans les paramètres généraux&lt;br /&gt;
&lt;br /&gt;
=Paramètres et leurs explications=&lt;br /&gt;
&lt;br /&gt;
==Overview &amp;amp; Update==&lt;br /&gt;
*&#039;&#039;&#039;System overview&#039;&#039;&#039;: This is pretty much self explaining. Here you can get a short insight on the number of surveys and other statistics in your LimeSurvey installation. For debug purposes you can also find a button to show your PHP Info.&lt;br /&gt;
*&#039;&#039;&#039;Updates&#039;&#039;&#039;:&lt;br /&gt;
:[[File:Update_check_settings.jpg]]&lt;br /&gt;
&lt;br /&gt;
:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Donnez un nom à votre questionnaire. Ce nom apparaîtra dans la liste des questionnaires et dans l&#039;en-tête de l&#039;administration.&lt;br /&gt;
*&#039;&#039;&#039;Default language&#039;&#039;&#039;: La langue qui sera utilisée par défaut aussi bien pour votre administration de l&#039;enquête que pour le public qui va y répondre si aucune autre langue n&#039;est choisie.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: Le choix de cette préférence indiquera quel gabarit(&amp;quot;template&amp;quot;) sera utilisé par les répondants de votre enquête ou questionnaire ainsi que pour l&#039;élaboration des nouveaux questionnaires si aucun autre gabarit n&#039;est choisi.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Spécifie le mode par défaut pour l&#039;éditeur HTML intégré. Les choix possibles sont: éditeur HTML en ligne (default), éditeur HTML dans une popup et aucun:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Lent mais facile et pratique&lt;br /&gt;
** &#039;&#039;éditeur HTML dans une popup&#039;&#039;: Ajoute une icône permettant d&#039;ouvrir une fenêtre avec l&#039;éditeur HTML. Plus rapide mais le code HTML est affiché on the form.&lt;br /&gt;
** &#039;&#039;aucun&#039;&#039;: Pas d&#039;éditeur HTML&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;PDF export available:&#039;&#039;&#039; This feature activates the PDF export for the &#039;Printable survey&#039; feature and data export.&lt;br /&gt;
*&#039;&#039;&#039;Screen reader compatibility mode&#039;&#039;&#039;: If this option is set to true, then LimeSurvey will add &#039;title&#039; html element to all links used in menus. This will help screen reader to analyze the menus. Only set this to true if you&#039;re using a screen reader because it overlaps with tool tips.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. Depending on your server configuration LimeSurvey may not be allowed to override the server setting - in that case you have to set the session timeout value in your PHP configuration.&lt;br /&gt;
&lt;br /&gt;
==Email settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: This is the default email address of the site administrator and used for system messages and contact options.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: The real name of the site administrator.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  This determines how e-mail messages are being sent. The following options are available:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; use internal PHP mailer&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; use sendmail mailer&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;use SMTP relaying. Use this setting when you are running LimeSurvey on a host that is not your mail server.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: If you switch this on then on sending invitations or reminders a detailed connection log and error message will be given (if an error occurs). Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Usually you want this to be off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;br /&gt;
&lt;br /&gt;
==Bounce settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site bounce email&#039;&#039;&#039;: This is the email address where bounced emails will be sent to.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: If set to &#039;Off&#039; no bounce processing functions will be available. Set this to POP or IMAP to check a related account for bounces. &lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;: Name of the server and (if needed) the port separated by a colon.&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;: The user name for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;: The password for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;: If encrpytion is used please set the right one here (SSL or TLS)&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
*&#039;&#039;&#039;Survey preview only for administration users&#039;&#039;&#039;: By default, preview of inactive survey is restricted to authenticated users only. If you set this to &#039;No&#039; any person can test your survey using the survey URL - without logging in to the administration and without having to activate the survey first.&lt;br /&gt;
*&#039;&#039;&#039;Filter HTML for XSS&#039;&#039;&#039;: By default you survey manager will not be authorized to use dangerous HTML tags in their survey/group/question/labels texts (for instance JavaScript code). This is intended to prevent a survey operator to add malicious script in order to have a true admin raise his permissions on the system. &#039;&#039;&#039;If you want to use any script objects like Javascript scripts of Flash applets in your surveys you will need to switch this off.&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Group member can only see own group&#039;&#039;&#039;: By default non-admin users defined in the LimeSurvey management interface will only be able to see other users if they belong to at least one group this user belongs to. If you set this to &#039;No&#039; they can see all users (for example in [[Survey security settings]] )&lt;br /&gt;
*&#039;&#039;&#039;Force HTTPS&#039;&#039;&#039;: By default this is set to &amp;quot;Don&#039;t force on or off&amp;quot;. Switch the setting to &amp;quot;on&amp;quot; to force the connection to use HTTPS. &#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; If your server doesn&#039;t support HTTPS properly, you can lock yourself from the system! Therefor test the &amp;quot;check if this link works&amp;quot; link first. If the link does not work and you turn on HTTPS, LimeSurvey will break and you won&#039;t be able to access it.&lt;br /&gt;
&lt;br /&gt;
==Presentation==&lt;br /&gt;
*&#039;&#039;&#039;Show &#039;no answer&#039; option for non-mandatory questions&#039;&#039;&#039;: When a question of a radio button/select type that contains editable answers (i.e.: List &amp;amp; array questions) is not mandatory and this is set to &#039;Yes&#039; (default), an additional entry &#039;No answer&#039; is shown for each subquestion - so that participants may choose to not answer the question. Some people prefer this not to be available. Set this to &#039;No&#039; to turn this off.&lt;br /&gt;
*&#039;&#039;&#039;Repeating headings in array questions every X subquestions&#039;&#039;&#039;: With array type question, often you&#039;ll have a lot of subquestions, which - when displayed on screen - take up more than one page. The repeat-headers setting lets you decide how many answers should be displayed before repeating the header information for the question. A good setting for this is around 25. If you don&#039;t want the headings to repeat at all, set this to 0.&lt;br /&gt;
*&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question group name and/or description&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question number and/or question code&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==Language==&lt;br /&gt;
*&#039;&#039;&#039;Default site language&#039;&#039;&#039;: This is the default language to be used in your administration , and also the default language for the public survey list if none is given.&lt;br /&gt;
*&#039;&#039;&#039;Available languages&#039;&#039;&#039;: If you don&#039;t want all languages to be available in the administration language select boxes you can here define the language that should be available only.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
*&#039;&#039;&#039;RPC interface enabled&#039;&#039;&#039;: Using this feature you can activate/deactivate the LimeSurvey [[RemoteControl 2 API|RemoteControl2]] interface API, either using JSON-RPC (recommended) or XML-RPC.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/6/fr&amp;diff=61215</id>
		<title>Translations:Global settings/6/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/6/fr&amp;diff=61215"/>
		<updated>2014-03-26T16:26:34Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Donnez un nom à votre questionnaire. Ce nom apparaîtra dans la liste des questionnaires et dans l&#039;en-tête de l&#039;administration.&lt;br /&gt;
*&#039;&#039;&#039;Default language&#039;&#039;&#039;: La langue qui sera utilisée par défaut aussi bien pour votre administration de l&#039;enquête que pour le public qui va y répondre si aucune autre langue n&#039;est choisie.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: Le choix de cette préférence indiquera quel gabarit(&amp;quot;template&amp;quot;) sera utilisé par les répondants de votre enquête ou questionnaire ainsi que pour l&#039;élaboration des nouveaux questionnaires si aucun autre gabarit n&#039;est choisi.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Spécifie le mode par défaut pour l&#039;éditeur HTML intégré. Les choix possibles sont: éditeur HTML en ligne (default), éditeur HTML dans une popup et aucun:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Lent mais facile et pratique&lt;br /&gt;
** &#039;&#039;éditeur HTML dans une popup&#039;&#039;: Ajoute une icône permettant d&#039;ouvrir une fenêtre avec l&#039;éditeur HTML. Plus rapide mais le code HTML est affiché on the form.&lt;br /&gt;
** &#039;&#039;aucun&#039;&#039;: Pas d&#039;éditeur HTML&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;PDF export available:&#039;&#039;&#039; This feature activates the PDF export for the &#039;Printable survey&#039; feature and data export.&lt;br /&gt;
*&#039;&#039;&#039;Screen reader compatibility mode&#039;&#039;&#039;: If this option is set to true, then LimeSurvey will add &#039;title&#039; html element to all links used in menus. This will help screen reader to analyze the menus. Only set this to true if you&#039;re using a screen reader because it overlaps with tool tips.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. Depending on your server configuration LimeSurvey may not be allowed to override the server setting - in that case you have to set the session timeout value in your PHP configuration.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61214</id>
		<title>Global settings/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61214"/>
		<updated>2014-03-26T14:53:28Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Description générale=&lt;br /&gt;
&lt;br /&gt;
Si vous cliquez sur l&#039;icône [[File:global.png]] dans la barre d&#039;outils principale vous arriverez sur les paramètres généraux. L&#039;accès aux paramètres généraux est réservé aux utilisateurs avec des droits de &amp;quot;Super administrateur&amp;quot;. Ceux-ci peuvent permettre d&#039;ajuster certains réglages de LimeSurvey d&#039;une manière globale. Dans les versions antérieures à 1.87, ces [[réglages optionnels]] n&#039;étaient disponibles qu&#039;en modifiant le fichier config.php ou config-default.php. Depuis la version 1.87, les valeurs dans ces fichiers sont simplement les valeurs utilisées par défaut. Une fois que vous serez entré dans l&#039;écran des paramètres généraux et que vous aurez fait une première sauvegarde, ces valeurs seront remplacées par celles dans les paramètres généraux&lt;br /&gt;
&lt;br /&gt;
=Paramètres et leurs explications=&lt;br /&gt;
&lt;br /&gt;
==Overview &amp;amp; Update==&lt;br /&gt;
*&#039;&#039;&#039;System overview&#039;&#039;&#039;: This is pretty much self explaining. Here you can get a short insight on the number of surveys and other statistics in your LimeSurvey installation. For debug purposes you can also find a button to show your PHP Info.&lt;br /&gt;
*&#039;&#039;&#039;Updates&#039;&#039;&#039;:&lt;br /&gt;
:[[File:Update_check_settings.jpg]]&lt;br /&gt;
&lt;br /&gt;
:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Give your survey site a name. This name will appear in the survey list overview and in the administration header.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: This setting specifies the default design template used for the &#039;public list&#039; of surveys and for new surveys or surveys using a non-existing template.&lt;br /&gt;
*&#039;&#039;&#039;Administration template&#039;&#039;&#039;: This setting specifies the default design template used for the LimeSurvey administration.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Sets the default mode for integrated HTML editor. Valid settings are: inline (default), popup and none:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Slow but convenient and user friendly&lt;br /&gt;
** &#039;&#039;popup&#039;&#039;: Adds an icon that opens a popup window with the HTML editor. Faster, but HTML code is displayed on the form.&lt;br /&gt;
** &#039;&#039;none&#039;&#039;: No HTML editor&lt;br /&gt;
*&#039;&#039;&#039;Question type selector&#039;&#039;&#039;: Choose &#039;Full selector&#039; to get a question type selector with preview and &#039;Simple&#039; to get a plain select box.&lt;br /&gt;
*&#039;&#039;&#039;Template editor:&#039;&#039;&#039;: Choose &#039;Full template editor&#039; to get a enhanced editor (with syntax-highlighting) when editing survey templates  and &#039;Simple template editor&#039; to get a plain editor field&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. This setting is only available when LimeSurvey is configured to store sessions in a database. When using regular, file-based sessions, it is up to the system administrator to define the right values for &amp;quot;session.gc_maxlifetime&amp;quot;, &amp;quot;session.save_path&amp;quot;, etc. in the PHP configuration. This only sets the lifetime of sessions in surveys, it doesn&#039;t affect the administration interface sessions, which have to be configured with PHP configuration in all cases.&lt;br /&gt;
*&#039;&#039;&#039;IP Info DB API Key&#039;&#039;&#039;: Allows integration with the IP-Info-DB service that let&#039;s you determine the geographic location of survey takers based on their IP.&lt;br /&gt;
*&#039;&#039;&#039;Google Maps API Key&#039;&#039;&#039;: Allows for integration with Google Maps.&lt;br /&gt;
*&#039;&#039;&#039;Google Analytics API Key&#039;&#039;&#039;: Allows for integration with Google Analytics. Surveys can over-ride this  site-level value.  The API key can be inserted into templates using {GOOGLE_ANALYTICS_API_KEY}.  The full JavaScript that Google Analytics expects (including the key) can be included in templates via {GOOGLE_ANALYTICS_JAVASCRIPT}.&lt;br /&gt;
*&#039;&#039;&#039;Google API howto&#039;&#039;&#039;:&lt;br /&gt;
# Register/login on Google Analytics (GA): [http://www.google.com/analytics/ www.google.com/analytics/]&lt;br /&gt;
# Create a key (the site should not point to the survey, but to the part before &#039;index.php?&#039;) The key should be UA-xxxxx.&lt;br /&gt;
# Go to your survey&#039;s global settings in LimeSurvey.&lt;br /&gt;
# Put the key in appropriate field (Google Analytics API Key). It&#039;s probably the best to set GA to track all pages as you can have more info.&lt;br /&gt;
# You don&#039;t need to do anything in shipped templates, as the {GOOGLE_ANALYTICS_JAVASCRIPT} part is already there.&lt;br /&gt;
# Activate the survey.&lt;br /&gt;
# Do the survey.&lt;br /&gt;
# Go to GA panel mainsite. (select appropriate account in left-hand upper corner if you have more than one). You should see some graphs with the statistics. Beware of the dates in upper right corner.&lt;br /&gt;
*&#039;&#039;&#039;Google Translate API Key&#039;&#039;&#039;:  As of version 1.92, the Auto Translate feature is now using the new version 2 of  Google Translate&#039;s API.  Google now charges for this service.  In order for the Auto Translate feature to work, you get an API key from [https://code.google.com/apis/console/?api=translate this site], and enter the key in this field.  Please note that this is currently a global feature, so any installation that has an assigned Translate API key will all charge translations to the same account.&lt;br /&gt;
*&#039;&#039;&#039;Google Analytics Event Tracking Code&#039;&#039;&#039;: Some LimeSurvey {KEYWORDS} can be used inside [http://code.google.com/intl/en-EN/apis/analytics/docs/tracking/eventTrackerGuide.html GG Analytics Event Tracking Code], e.g, &#039;_trackEvent&#039;, &#039;MyEvent&#039;, &#039;{SID}&#039;&lt;br /&gt;
&lt;br /&gt;
==Email settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: This is the default email address of the site administrator and used for system messages and contact options.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: The real name of the site administrator.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  This determines how e-mail messages are being sent. The following options are available:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; use internal PHP mailer&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; use sendmail mailer&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;use SMTP relaying. Use this setting when you are running LimeSurvey on a host that is not your mail server.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: If you switch this on then on sending invitations or reminders a detailed connection log and error message will be given (if an error occurs). Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Usually you want this to be off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;br /&gt;
&lt;br /&gt;
==Bounce settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site bounce email&#039;&#039;&#039;: This is the email address where bounced emails will be sent to.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: If set to &#039;Off&#039; no bounce processing functions will be available. Set this to POP or IMAP to check a related account for bounces. &lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;: Name of the server and (if needed) the port separated by a colon.&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;: The user name for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;: The password for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;: If encrpytion is used please set the right one here (SSL or TLS)&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
*&#039;&#039;&#039;Survey preview only for administration users&#039;&#039;&#039;: By default, preview of inactive survey is restricted to authenticated users only. If you set this to &#039;No&#039; any person can test your survey using the survey URL - without logging in to the administration and without having to activate the survey first.&lt;br /&gt;
*&#039;&#039;&#039;Filter HTML for XSS&#039;&#039;&#039;: By default you survey manager will not be authorized to use dangerous HTML tags in their survey/group/question/labels texts (for instance JavaScript code). This is intended to prevent a survey operator to add malicious script in order to have a true admin raise his permissions on the system. &#039;&#039;&#039;If you want to use any script objects like Javascript scripts of Flash applets in your surveys you will need to switch this off.&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Group member can only see own group&#039;&#039;&#039;: By default non-admin users defined in the LimeSurvey management interface will only be able to see other users if they belong to at least one group this user belongs to. If you set this to &#039;No&#039; they can see all users (for example in [[Survey security settings]] )&lt;br /&gt;
*&#039;&#039;&#039;Force HTTPS&#039;&#039;&#039;: By default this is set to &amp;quot;Don&#039;t force on or off&amp;quot;. Switch the setting to &amp;quot;on&amp;quot; to force the connection to use HTTPS. &#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; If your server doesn&#039;t support HTTPS properly, you can lock yourself from the system! Therefor test the &amp;quot;check if this link works&amp;quot; link first. If the link does not work and you turn on HTTPS, LimeSurvey will break and you won&#039;t be able to access it.&lt;br /&gt;
&lt;br /&gt;
==Presentation==&lt;br /&gt;
*&#039;&#039;&#039;Show &#039;no answer&#039; option for non-mandatory questions&#039;&#039;&#039;: When a question of a radio button/select type that contains editable answers (i.e.: List &amp;amp; array questions) is not mandatory and this is set to &#039;Yes&#039; (default), an additional entry &#039;No answer&#039; is shown for each subquestion - so that participants may choose to not answer the question. Some people prefer this not to be available. Set this to &#039;No&#039; to turn this off.&lt;br /&gt;
*&#039;&#039;&#039;Repeating headings in array questions every X subquestions&#039;&#039;&#039;: With array type question, often you&#039;ll have a lot of subquestions, which - when displayed on screen - take up more than one page. The repeat-headers setting lets you decide how many answers should be displayed before repeating the header information for the question. A good setting for this is around 25. If you don&#039;t want the headings to repeat at all, set this to 0.&lt;br /&gt;
*&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question group name and/or description&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question number and/or question code&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==Language==&lt;br /&gt;
*&#039;&#039;&#039;Default site language&#039;&#039;&#039;: This is the default language to be used in your administration , and also the default language for the public survey list if none is given.&lt;br /&gt;
*&#039;&#039;&#039;Available languages&#039;&#039;&#039;: If you don&#039;t want all languages to be available in the administration language select boxes you can here define the language that should be available only.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
*&#039;&#039;&#039;RPC interface enabled&#039;&#039;&#039;: Using this feature you can activate/deactivate the LimeSurvey [[RemoteControl 2 API|RemoteControl2]] interface API, either using JSON-RPC (recommended) or XML-RPC.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61213</id>
		<title>Translations:Global settings/13/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61213"/>
		<updated>2014-03-26T14:53:27Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:{{Arrow|1}} Vous pouvez paramétrer si, et à quelle fréquence, Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61212</id>
		<title>Global settings/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Global_settings/fr&amp;diff=61212"/>
		<updated>2014-03-26T14:52:53Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;:{{Arrow|1}} Vous pouvez paramétrer si et à quelle fréquence Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée, vous pouvez, soit eff...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=Description générale=&lt;br /&gt;
&lt;br /&gt;
Si vous cliquez sur l&#039;icône [[File:global.png]] dans la barre d&#039;outils principale vous arriverez sur les paramètres généraux. L&#039;accès aux paramètres généraux est réservé aux utilisateurs avec des droits de &amp;quot;Super administrateur&amp;quot;. Ceux-ci peuvent permettre d&#039;ajuster certains réglages de LimeSurvey d&#039;une manière globale. Dans les versions antérieures à 1.87, ces [[réglages optionnels]] n&#039;étaient disponibles qu&#039;en modifiant le fichier config.php ou config-default.php. Depuis la version 1.87, les valeurs dans ces fichiers sont simplement les valeurs utilisées par défaut. Une fois que vous serez entré dans l&#039;écran des paramètres généraux et que vous aurez fait une première sauvegarde, ces valeurs seront remplacées par celles dans les paramètres généraux&lt;br /&gt;
&lt;br /&gt;
=Paramètres et leurs explications=&lt;br /&gt;
&lt;br /&gt;
==Overview &amp;amp; Update==&lt;br /&gt;
*&#039;&#039;&#039;System overview&#039;&#039;&#039;: This is pretty much self explaining. Here you can get a short insight on the number of surveys and other statistics in your LimeSurvey installation. For debug purposes you can also find a button to show your PHP Info.&lt;br /&gt;
*&#039;&#039;&#039;Updates&#039;&#039;&#039;:&lt;br /&gt;
:[[File:Update_check_settings.jpg]]&lt;br /&gt;
&lt;br /&gt;
:{{Arrow|1}} Vous pouvez paramétrer si et à quelle fréquence Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée, vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;br /&gt;
&lt;br /&gt;
==General==&lt;br /&gt;
*&#039;&#039;&#039;Site name&#039;&#039;&#039;: Give your survey site a name. This name will appear in the survey list overview and in the administration header.&lt;br /&gt;
*&#039;&#039;&#039;Default template&#039;&#039;&#039;: This setting specifies the default design template used for the &#039;public list&#039; of surveys and for new surveys or surveys using a non-existing template.&lt;br /&gt;
*&#039;&#039;&#039;Administration template&#039;&#039;&#039;: This setting specifies the default design template used for the LimeSurvey administration.&lt;br /&gt;
*&#039;&#039;&#039;Default HTML editor mode:&#039;&#039;&#039; Sets the default mode for integrated HTML editor. Valid settings are: inline (default), popup and none:&lt;br /&gt;
** &#039;&#039;inline&#039;&#039;: Inline replacement of fields by an HTML editor. Slow but convenient and user friendly&lt;br /&gt;
** &#039;&#039;popup&#039;&#039;: Adds an icon that opens a popup window with the HTML editor. Faster, but HTML code is displayed on the form.&lt;br /&gt;
** &#039;&#039;none&#039;&#039;: No HTML editor&lt;br /&gt;
*&#039;&#039;&#039;Question type selector&#039;&#039;&#039;: Choose &#039;Full selector&#039; to get a question type selector with preview and &#039;Simple&#039; to get a plain select box.&lt;br /&gt;
*&#039;&#039;&#039;Template editor:&#039;&#039;&#039;: Choose &#039;Full template editor&#039; to get a enhanced editor (with syntax-highlighting) when editing survey templates  and &#039;Simple template editor&#039; to get a plain editor field&lt;br /&gt;
*&#039;&#039;&#039;Time difference (in hours)&#039;&#039;&#039;: If your web server is in a different time zone to the location where your surveys will be based, put the difference between your server and your home time zone here. For example, I live in Australia but use a US web server. The web server is 14 hours behind my local time zone. So my setting here is &amp;quot;+14&amp;quot;. In other words, it adds 14 hours to the web servers time. This setting is particularly important when surveys timestamp the responses.&lt;br /&gt;
*&#039;&#039;&#039;Session lifetime&#039;&#039;&#039;: Defines the time in seconds after which a survey session expires (provided there is no action from the participant). The maximum value on this is 65000 (seconds). Please use a reasonable value. This setting is only available when LimeSurvey is configured to store sessions in a database. When using regular, file-based sessions, it is up to the system administrator to define the right values for &amp;quot;session.gc_maxlifetime&amp;quot;, &amp;quot;session.save_path&amp;quot;, etc. in the PHP configuration. This only sets the lifetime of sessions in surveys, it doesn&#039;t affect the administration interface sessions, which have to be configured with PHP configuration in all cases.&lt;br /&gt;
*&#039;&#039;&#039;IP Info DB API Key&#039;&#039;&#039;: Allows integration with the IP-Info-DB service that let&#039;s you determine the geographic location of survey takers based on their IP.&lt;br /&gt;
*&#039;&#039;&#039;Google Maps API Key&#039;&#039;&#039;: Allows for integration with Google Maps.&lt;br /&gt;
*&#039;&#039;&#039;Google Analytics API Key&#039;&#039;&#039;: Allows for integration with Google Analytics. Surveys can over-ride this  site-level value.  The API key can be inserted into templates using {GOOGLE_ANALYTICS_API_KEY}.  The full JavaScript that Google Analytics expects (including the key) can be included in templates via {GOOGLE_ANALYTICS_JAVASCRIPT}.&lt;br /&gt;
*&#039;&#039;&#039;Google API howto&#039;&#039;&#039;:&lt;br /&gt;
# Register/login on Google Analytics (GA): [http://www.google.com/analytics/ www.google.com/analytics/]&lt;br /&gt;
# Create a key (the site should not point to the survey, but to the part before &#039;index.php?&#039;) The key should be UA-xxxxx.&lt;br /&gt;
# Go to your survey&#039;s global settings in LimeSurvey.&lt;br /&gt;
# Put the key in appropriate field (Google Analytics API Key). It&#039;s probably the best to set GA to track all pages as you can have more info.&lt;br /&gt;
# You don&#039;t need to do anything in shipped templates, as the {GOOGLE_ANALYTICS_JAVASCRIPT} part is already there.&lt;br /&gt;
# Activate the survey.&lt;br /&gt;
# Do the survey.&lt;br /&gt;
# Go to GA panel mainsite. (select appropriate account in left-hand upper corner if you have more than one). You should see some graphs with the statistics. Beware of the dates in upper right corner.&lt;br /&gt;
*&#039;&#039;&#039;Google Translate API Key&#039;&#039;&#039;:  As of version 1.92, the Auto Translate feature is now using the new version 2 of  Google Translate&#039;s API.  Google now charges for this service.  In order for the Auto Translate feature to work, you get an API key from [https://code.google.com/apis/console/?api=translate this site], and enter the key in this field.  Please note that this is currently a global feature, so any installation that has an assigned Translate API key will all charge translations to the same account.&lt;br /&gt;
*&#039;&#039;&#039;Google Analytics Event Tracking Code&#039;&#039;&#039;: Some LimeSurvey {KEYWORDS} can be used inside [http://code.google.com/intl/en-EN/apis/analytics/docs/tracking/eventTrackerGuide.html GG Analytics Event Tracking Code], e.g, &#039;_trackEvent&#039;, &#039;MyEvent&#039;, &#039;{SID}&#039;&lt;br /&gt;
&lt;br /&gt;
==Email settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site admin email&#039;&#039;&#039;: This is the default email address of the site administrator and used for system messages and contact options.&lt;br /&gt;
*&#039;&#039;&#039;Administrator name&#039;&#039;&#039;: The real name of the site administrator.&lt;br /&gt;
*&#039;&#039;&#039;Email method:&#039;&#039;&#039;  This determines how e-mail messages are being sent. The following options are available:&lt;br /&gt;
**&#039;&#039;&#039;PHP:&#039;&#039;&#039; use internal PHP mailer&lt;br /&gt;
**&#039;&#039;&#039;Sendmail:&#039;&#039;&#039; use sendmail mailer&lt;br /&gt;
**&#039;&#039;&#039;SMTP:&#039;&#039;&#039;use SMTP relaying. Use this setting when you are running LimeSurvey on a host that is not your mail server.&lt;br /&gt;
***Make sure that you are using your SMTP configured e-mail (Global settings -&amp;gt; E-mail settings) at the survey settings (At the moment you create a survey or after you create it Edit Survey Settings -&amp;gt; General)  if you use SMTP, otherwise there might be a chance that the following error is displayed: SMTP -&amp;gt; ERROR: RCPT not accepted from server: 553 5.7.1 : Sender address rejected: not owned by user.&lt;br /&gt;
**&#039;&#039;&#039;Qmail:&#039;&#039;&#039;Set this if you are running the Qmail mailer&lt;br /&gt;
*&#039;&#039;&#039;SMTP host:&#039;&#039;&#039; If you use &#039;SMTP &#039; as email method then you have to put your SMTP-server here. If you are using a different part than port 25 (standard for SMPT) then you have to add the port number separated be a colon (example: &#039;smtp.gmail.com:465&#039;)&lt;br /&gt;
*&#039;&#039;&#039;SMTP username:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your user name, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP password:&#039;&#039;&#039; If your SMTP-server needs authentication then set this to your password, otherwise it must be blank.&lt;br /&gt;
*&#039;&#039;&#039;SMTP SSL/TLS:&#039;&#039;&#039; Set this to &#039;SSL&#039; or &#039;TLS&#039; to use SSL/TLS for your SMTP connection&lt;br /&gt;
*&#039;&#039;&#039;SMTP debug mode&#039;&#039;&#039;: If you switch this on then on sending invitations or reminders a detailed connection log and error message will be given (if an error occurs). Not for the faint of heart, but this can give valuable information why a SMTP relay does not work. Usually you want this to be off.&lt;br /&gt;
*&#039;&#039;&#039;Email batch size:&#039;&#039;&#039; When sending invitations or reminders to survey participants, this setting is used to determine how many emails can be sent in one bunch. Different web servers have different email capacities, and if your script takes too long to send a bunch of emails, the script could time out and cause errors. Most web servers can send 100 emails at a time within the default 30 second time limit for a PHP script. If you get script timeout errors when sending large numbers of emails, reduce the number in this setting.  Clicking the &#039;send email invitation&#039; button on the token control toolbar, (not the button on the right of each token), sends the maxemails number of invitations, then displays a list of the addresses sent to and a warning that &amp;quot;There are more emails pending than could be sent in one batch. Continue sending emails by clicking below. There are ### emails still to be sent.&amp;quot; and provides a &amp;quot;continue button&amp;quot; to proceed with the next batch. I.e., the user determines when to send the next batch after each batch gets emailed.  It is not necessary to wait with this screen active.  The admin could log off and come back at a later time to send the next batch of invites.&lt;br /&gt;
&lt;br /&gt;
==Bounce settings==&lt;br /&gt;
*&#039;&#039;&#039;Default site bounce email&#039;&#039;&#039;: This is the email address where bounced emails will be sent to.&lt;br /&gt;
*&#039;&#039;&#039;Server type&#039;&#039;&#039;: If set to &#039;Off&#039; no bounce processing functions will be available. Set this to POP or IMAP to check a related account for bounces. &lt;br /&gt;
*&#039;&#039;&#039;Server name &amp;amp; port&#039;&#039;&#039;: Name of the server and (if needed) the port separated by a colon.&lt;br /&gt;
*&#039;&#039;&#039;User name&#039;&#039;&#039;: The user name for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Password&#039;&#039;&#039;: The password for the POP/IMAP account&lt;br /&gt;
*&#039;&#039;&#039;Encryption type&#039;&#039;&#039;: If encrpytion is used please set the right one here (SSL or TLS)&lt;br /&gt;
&lt;br /&gt;
==Security==&lt;br /&gt;
*&#039;&#039;&#039;Survey preview only for administration users&#039;&#039;&#039;: By default, preview of inactive survey is restricted to authenticated users only. If you set this to &#039;No&#039; any person can test your survey using the survey URL - without logging in to the administration and without having to activate the survey first.&lt;br /&gt;
*&#039;&#039;&#039;Filter HTML for XSS&#039;&#039;&#039;: By default you survey manager will not be authorized to use dangerous HTML tags in their survey/group/question/labels texts (for instance JavaScript code). This is intended to prevent a survey operator to add malicious script in order to have a true admin raise his permissions on the system. &#039;&#039;&#039;If you want to use any script objects like Javascript scripts of Flash applets in your surveys you will need to switch this off.&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;Group member can only see own group&#039;&#039;&#039;: By default non-admin users defined in the LimeSurvey management interface will only be able to see other users if they belong to at least one group this user belongs to. If you set this to &#039;No&#039; they can see all users (for example in [[Survey security settings]] )&lt;br /&gt;
*&#039;&#039;&#039;Force HTTPS&#039;&#039;&#039;: By default this is set to &amp;quot;Don&#039;t force on or off&amp;quot;. Switch the setting to &amp;quot;on&amp;quot; to force the connection to use HTTPS. &#039;&#039;&#039;&#039;&#039;Note:&#039;&#039;&#039;&#039;&#039; If your server doesn&#039;t support HTTPS properly, you can lock yourself from the system! Therefor test the &amp;quot;check if this link works&amp;quot; link first. If the link does not work and you turn on HTTPS, LimeSurvey will break and you won&#039;t be able to access it.&lt;br /&gt;
&lt;br /&gt;
==Presentation==&lt;br /&gt;
*&#039;&#039;&#039;Show &#039;no answer&#039; option for non-mandatory questions&#039;&#039;&#039;: When a question of a radio button/select type that contains editable answers (i.e.: List &amp;amp; array questions) is not mandatory and this is set to &#039;Yes&#039; (default), an additional entry &#039;No answer&#039; is shown for each subquestion - so that participants may choose to not answer the question. Some people prefer this not to be available. Set this to &#039;No&#039; to turn this off.&lt;br /&gt;
*&#039;&#039;&#039;Repeating headings in array questions every X subquestions&#039;&#039;&#039;: With array type question, often you&#039;ll have a lot of subquestions, which - when displayed on screen - take up more than one page. The repeat-headers setting lets you decide how many answers should be displayed before repeating the header information for the question. A good setting for this is around 25. If you don&#039;t want the headings to repeat at all, set this to 0.&lt;br /&gt;
*&#039;&#039;&#039;Show &amp;quot;There are X questions in this survey&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question group name and/or description&#039;&#039;&#039;:&lt;br /&gt;
*&#039;&#039;&#039;Show question number and/or question code&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
==Language==&lt;br /&gt;
*&#039;&#039;&#039;Default site language&#039;&#039;&#039;: This is the default language to be used in your administration , and also the default language for the public survey list if none is given.&lt;br /&gt;
*&#039;&#039;&#039;Available languages&#039;&#039;&#039;: If you don&#039;t want all languages to be available in the administration language select boxes you can here define the language that should be available only.&lt;br /&gt;
&lt;br /&gt;
==Interfaces==&lt;br /&gt;
*&#039;&#039;&#039;RPC interface enabled&#039;&#039;&#039;: Using this feature you can activate/deactivate the LimeSurvey [[RemoteControl 2 API|RemoteControl2]] interface API, either using JSON-RPC (recommended) or XML-RPC.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61211</id>
		<title>Translations:Global settings/13/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Global_settings/13/fr&amp;diff=61211"/>
		<updated>2014-03-26T14:52:53Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;:{{Arrow|1}} Vous pouvez paramétrer si et à quelle fréquence Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée, vous pouvez, soit eff...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;:{{Arrow|1}} Vous pouvez paramétrer si et à quelle fréquence Limesurvey vérifie la disponibilité de mises à jour. Si une mise à jour est trouvée, vous pouvez, soit effectuer la mise à jour manuellement (en téléchargeant le nouveau package de Limesurvey et en suivant les [[Upgrading from a previous version|Update instructions]]) ou utiliser la fonctionnalité [[ComfortUpdate]]&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=SGQA_identifier/fr&amp;diff=60885</id>
		<title>SGQA identifier/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=SGQA_identifier/fr&amp;diff=60885"/>
		<updated>2014-02-27T17:59:25Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; __TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&#039;avez plus besoin d&#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec [[Expression Manager|Expression Manager]]. Vous trouverez ici les informations concernant leur  [[Expression Manager#Access to Variables|syntaxe]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Hint:&#039;&#039;&#039; This page describes how you can find out an SGQA identifier. For information how to use it please refer to the page [[Adding a question]]. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description générale===&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant SGQA (pour Survey/Group/Question/Answer en français, Questionnaire/Groupe/Question/Réponse mais seule la notation anglaise est interprétée par LimeSurvey) est un raccourci vers une réponse à une question. Chaque questionnaire, chaque groupe et chaque question que vous créez se voit attribuer un code unique dans la base de données. Vous pouvez retrouver ces nombres (appelés aussi xID) dans l&#039;écran d&#039;administration dans les barres de titres de questionnaire, de groupe et de question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SGQA.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour déterminer l&#039;identifiant SGQA vous devez rassembler ces nombres en les séparant par la lettre &amp;quot;X&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Note:&#039;&#039;&#039; Always use capital letters (&amp;quot;X&amp;quot; instead of &amp;quot;x&amp;quot;)!&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use editor to add placeholder=&lt;br /&gt;
&lt;br /&gt;
The integrated editor has a feature to select the placeholder for a certain question. The icon is called &amp;quot;LimeSurvey replacement fields properties&amp;quot;. This feature always lists questions of previous survey pages only, so it depends on the survey mode.&lt;br /&gt;
&lt;br /&gt;
[[File:lime_replacement_editor.png]]&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix unique :===&lt;br /&gt;
&lt;br /&gt;
Par exemple, le questionnaire a l&#039;ID 1, le groupe a l&#039;ID 6 et la question a l&#039;ID 12. L&#039;identifiant pour ce genre de question à choix unique doit ressembler à quelque chose comme ceci :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix unique utilisant un jeu d&#039;étiquettes===&lt;br /&gt;
&lt;br /&gt;
Puisque cela reste une question à choix unique qui utilise des étiquettes pour les réponses, cette réponse particulière doit elle-aussi être identifiée. Pour cela, ajoutez simplement le code de cette étiquette sans le &amp;quot;X&amp;quot;. Par exemple, questionnaire d&#039;ID 1, groupe d&#039;ID 6, question d&#039;ID 12. La réponse qui nous intéresse possède le code &amp;quot;lab1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant ressemblera donc à ça~hs~:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12lab1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix multiples===&lt;br /&gt;
&lt;br /&gt;
Comme il s&#039;agit d&#039;une question à choix multiples, la réponse recherchée doit aussi être identifiée. Ajoutez simplement le code de cette réponse sans le &amp;quot;X&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Par exemple, questionnaire d&#039;ID 1, groupe dD 6, question d&#039;ID 12. La réponse recherchée possède le code &amp;quot;ber1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant ressemblera donc à ça~hs~:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12ber1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Identifier for Array (Text) or Array (Number) Questions=&lt;br /&gt;
&lt;br /&gt;
Since it is a combined array question the particular answer within the cell must be identified too. Add the subquestion code of the row without an X, then append the underscore char and finally add the subquestion code that indentifies the column. For example: Survey has ID 1, Group has ID 6, Question has ID 12. The particular subquestion has code &#039;ber1&#039;, and the column is identified by the subquestion with code &#039;lab1&#039;&lt;br /&gt;
&lt;br /&gt;
Your identifier for this &amp;quot;Array (Text)&amp;quot; question answer would look like this:&lt;br /&gt;
&lt;br /&gt;
1X6X12ber1_lab1&lt;br /&gt;
&lt;br /&gt;
=Uses of the SGQA identifier=&lt;br /&gt;
&lt;br /&gt;
The SGQA identifier can be used to load the answers to previously saved questions into the question text of later questions. (See [[Adding a question#Information from previous answers|Information from previous answers]])&lt;br /&gt;
&lt;br /&gt;
It can also be used in the query URL of a survey to &amp;quot;prefill&amp;quot; answers to a survey. eg: for SGQA 1X6X121ab1, your query URL could include &amp;quot;&amp;amp;1X6X121ab1=Y&amp;quot; to prefill that answer with a &amp;quot;Y&amp;quot;. (See  [[Workarounds: Survey behaviour#Prefilling_survey_answers_using_the_survey_URL|Prefilling survey answers using the survey URL]])&lt;br /&gt;
&lt;br /&gt;
The SGQA identifier is also the field name where the data for each question is stored in the database survey responses table.&lt;br /&gt;
&lt;br /&gt;
=Dynamically reference the SGQ identifier=&lt;br /&gt;
&lt;br /&gt;
Some people may find a need to reference a question dynamically. For instance, if you would like to [[Workarounds: Manipulating a survey at runtime using Javascript#General|hide the input text field]] of a short text answer. You can now do this (as of SVN build 9755) by using the {SGQ} identifier. LimeSurvey will replace the {SGQ} with the full Id of that question, ex: 3583X84X249&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/2/fr&amp;diff=60884</id>
		<title>Translations:SGQA identifier/2/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/2/fr&amp;diff=60884"/>
		<updated>2014-02-27T17:59:25Z</updated>

		<summary type="html">&lt;p&gt;Courtm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&#039;avez plus besoin d&#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec [[Expression Manager|Expression Manager]]. Vous trouverez ici les informations concernant leur  [[Expression Manager#Access to Variables|syntaxe]]&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/1/fr&amp;diff=60883</id>
		<title>Translations:SGQA identifier/1/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/1/fr&amp;diff=60883"/>
		<updated>2014-02-27T17:58:36Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;__TOC__&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=SGQA_identifier/fr&amp;diff=60882</id>
		<title>SGQA identifier/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=SGQA_identifier/fr&amp;diff=60882"/>
		<updated>2014-02-27T17:57:33Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&amp;#039;avez plus besoin d&amp;#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; __TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&#039;avez plus besoin d&#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec [[Expression Manager|Expression Manager]]. Vous trouverez ici &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Hint:&#039;&#039;&#039; This page describes how you can find out an SGQA identifier. For information how to use it please refer to the page [[Adding a question]]. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Description générale===&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant SGQA (pour Survey/Group/Question/Answer en français, Questionnaire/Groupe/Question/Réponse mais seule la notation anglaise est interprétée par LimeSurvey) est un raccourci vers une réponse à une question. Chaque questionnaire, chaque groupe et chaque question que vous créez se voit attribuer un code unique dans la base de données. Vous pouvez retrouver ces nombres (appelés aussi xID) dans l&#039;écran d&#039;administration dans les barres de titres de questionnaire, de groupe et de question.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[File:SGQA.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pour déterminer l&#039;identifiant SGQA vous devez rassembler ces nombres en les séparant par la lettre &amp;quot;X&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;&#039;&#039;&#039;Note:&#039;&#039;&#039; Always use capital letters (&amp;quot;X&amp;quot; instead of &amp;quot;x&amp;quot;)!&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Use editor to add placeholder=&lt;br /&gt;
&lt;br /&gt;
The integrated editor has a feature to select the placeholder for a certain question. The icon is called &amp;quot;LimeSurvey replacement fields properties&amp;quot;. This feature always lists questions of previous survey pages only, so it depends on the survey mode.&lt;br /&gt;
&lt;br /&gt;
[[File:lime_replacement_editor.png]]&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix unique :===&lt;br /&gt;
&lt;br /&gt;
Par exemple, le questionnaire a l&#039;ID 1, le groupe a l&#039;ID 6 et la question a l&#039;ID 12. L&#039;identifiant pour ce genre de question à choix unique doit ressembler à quelque chose comme ceci :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix unique utilisant un jeu d&#039;étiquettes===&lt;br /&gt;
&lt;br /&gt;
Puisque cela reste une question à choix unique qui utilise des étiquettes pour les réponses, cette réponse particulière doit elle-aussi être identifiée. Pour cela, ajoutez simplement le code de cette étiquette sans le &amp;quot;X&amp;quot;. Par exemple, questionnaire d&#039;ID 1, groupe d&#039;ID 6, question d&#039;ID 12. La réponse qui nous intéresse possède le code &amp;quot;lab1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant ressemblera donc à ça~hs~:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12lab1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Identifiant pour une question à choix multiples===&lt;br /&gt;
&lt;br /&gt;
Comme il s&#039;agit d&#039;une question à choix multiples, la réponse recherchée doit aussi être identifiée. Ajoutez simplement le code de cette réponse sans le &amp;quot;X&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Par exemple, questionnaire d&#039;ID 1, groupe dD 6, question d&#039;ID 12. La réponse recherchée possède le code &amp;quot;ber1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
L&#039;identifiant ressemblera donc à ça~hs~:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1X6X12ber1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Identifier for Array (Text) or Array (Number) Questions=&lt;br /&gt;
&lt;br /&gt;
Since it is a combined array question the particular answer within the cell must be identified too. Add the subquestion code of the row without an X, then append the underscore char and finally add the subquestion code that indentifies the column. For example: Survey has ID 1, Group has ID 6, Question has ID 12. The particular subquestion has code &#039;ber1&#039;, and the column is identified by the subquestion with code &#039;lab1&#039;&lt;br /&gt;
&lt;br /&gt;
Your identifier for this &amp;quot;Array (Text)&amp;quot; question answer would look like this:&lt;br /&gt;
&lt;br /&gt;
1X6X12ber1_lab1&lt;br /&gt;
&lt;br /&gt;
=Uses of the SGQA identifier=&lt;br /&gt;
&lt;br /&gt;
The SGQA identifier can be used to load the answers to previously saved questions into the question text of later questions. (See [[Adding a question#Information from previous answers|Information from previous answers]])&lt;br /&gt;
&lt;br /&gt;
It can also be used in the query URL of a survey to &amp;quot;prefill&amp;quot; answers to a survey. eg: for SGQA 1X6X121ab1, your query URL could include &amp;quot;&amp;amp;1X6X121ab1=Y&amp;quot; to prefill that answer with a &amp;quot;Y&amp;quot;. (See  [[Workarounds: Survey behaviour#Prefilling_survey_answers_using_the_survey_URL|Prefilling survey answers using the survey URL]])&lt;br /&gt;
&lt;br /&gt;
The SGQA identifier is also the field name where the data for each question is stored in the database survey responses table.&lt;br /&gt;
&lt;br /&gt;
=Dynamically reference the SGQ identifier=&lt;br /&gt;
&lt;br /&gt;
Some people may find a need to reference a question dynamically. For instance, if you would like to [[Workarounds: Manipulating a survey at runtime using Javascript#General|hide the input text field]] of a short text answer. You can now do this (as of SVN build 9755) by using the {SGQ} identifier. LimeSurvey will replace the {SGQ} with the full Id of that question, ex: 3583X84X249&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/2/fr&amp;diff=60881</id>
		<title>Translations:SGQA identifier/2/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:SGQA_identifier/2/fr&amp;diff=60881"/>
		<updated>2014-02-27T17:57:33Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&amp;#039;avez plus besoin d&amp;#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Depuis la version 1.92, vous n&#039;avez plus besoin d&#039;utiliser les identifiants SGQA. A la place vous pouvez utiliser des codes de questions compatible avec [[Expression Manager|Expression Manager]]. Vous trouverez ici &amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60880</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60880"/>
		<updated>2014-02-27T17:52:31Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;IMC calcule la formule du poids comme {weight_kg / (height_m * height_m)}.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;br /&gt;
&lt;br /&gt;
===Equations Conditionnelles===&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple de l&#039;Indice de Masse Corporel montre la capacité à calculer l&#039;IMC d&#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou non métriques.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ici weight_kg est {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}. La fonction if() signifie que si le sujet a entré son poids en utilisant les kilogrammes alors utilise cette valeur, sinon multiplie la valeur entrée (donc en livres) par 0.453592 pour la convertir en kilogrammes. La variable height_m utilise une approche similaire pour calculer la taille de la personne en mètres, même si elle l&#039;a entré en pouces.&lt;br /&gt;
&lt;br /&gt;
IMC calcule la formule du poids comme {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/32/fr&amp;diff=60879</id>
		<title>Translations:Expression Manager/32/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/32/fr&amp;diff=60879"/>
		<updated>2014-02-27T17:52:30Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;IMC calcule la formule du poids comme {weight_kg / (height_m * height_m)}.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;IMC calcule la formule du poids comme {weight_kg / (height_m * height_m)}.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60878</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60878"/>
		<updated>2014-02-27T17:51:51Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Ici weight_kg est {if(weight_units == &amp;#039;kg&amp;#039;, weight, weight * .453592)}. La fonction if() signifie que si le sujet a entré son poids en utilisant les kilogrammes alors utilise...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;br /&gt;
&lt;br /&gt;
===Equations Conditionnelles===&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple de l&#039;Indice de Masse Corporel montre la capacité à calculer l&#039;IMC d&#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou non métriques.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ici weight_kg est {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}. La fonction if() signifie que si le sujet a entré son poids en utilisant les kilogrammes alors utilise cette valeur, sinon multiplie la valeur entrée (donc en livres) par 0.453592 pour la convertir en kilogrammes. La variable height_m utilise une approche similaire pour calculer la taille de la personne en mètres, même si elle l&#039;a entré en pouces.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/31/fr&amp;diff=60877</id>
		<title>Translations:Expression Manager/31/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/31/fr&amp;diff=60877"/>
		<updated>2014-02-27T17:51:51Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Ici weight_kg est {if(weight_units == &amp;#039;kg&amp;#039;, weight, weight * .453592)}. La fonction if() signifie que si le sujet a entré son poids en utilisant les kilogrammes alors utilise...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ici weight_kg est {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}. La fonction if() signifie que si le sujet a entré son poids en utilisant les kilogrammes alors utilise cette valeur, sinon multiplie la valeur entrée (donc en livres) par 0.453592 pour la convertir en kilogrammes. La variable height_m utilise une approche similaire pour calculer la taille de la personne en mètres, même si elle l&#039;a entré en pouces.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60876</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60876"/>
		<updated>2014-02-27T17:47:32Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;L&amp;#039;exemple de l&amp;#039;Indice de Masse Corporel montre la capacité à calculer l&amp;#039;IMC d&amp;#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;br /&gt;
&lt;br /&gt;
===Equations Conditionnelles===&lt;br /&gt;
&lt;br /&gt;
L&#039;exemple de l&#039;Indice de Masse Corporel montre la capacité à calculer l&#039;IMC d&#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou non métriques.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/29/fr&amp;diff=60875</id>
		<title>Translations:Expression Manager/29/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/29/fr&amp;diff=60875"/>
		<updated>2014-02-27T17:47:31Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;L&amp;#039;exemple de l&amp;#039;Indice de Masse Corporel montre la capacité à calculer l&amp;#039;IMC d&amp;#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;L&#039;exemple de l&#039;Indice de Masse Corporel montre la capacité à calculer l&#039;IMC d&#039;une personne même en la laissant entrer sa taille et son poids dans des unités métriques ou non métriques.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60874</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60874"/>
		<updated>2014-02-27T17:45:29Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;===Equations Conditionnelles===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;br /&gt;
&lt;br /&gt;
===Equations Conditionnelles===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/28/fr&amp;diff=60873</id>
		<title>Translations:Expression Manager/28/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/28/fr&amp;diff=60873"/>
		<updated>2014-02-27T17:45:28Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;===Equations Conditionnelles===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Equations Conditionnelles===&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60872</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60872"/>
		<updated>2014-02-27T17:45:05Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&amp;#039;une simple substitution, comme quand vous dites ,...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/27/fr&amp;diff=60871</id>
		<title>Translations:Expression Manager/27/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/27/fr&amp;diff=60871"/>
		<updated>2014-02-27T17:45:04Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&amp;#039;une simple substitution, comme quand vous dites ,...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;EM vous permet facilement de réaliser des conditions simples et complexes de vos questions. Parfois vous avez juste besoin d&#039;une simple substitution, comme quand vous dites , &amp;quot;Vous nous avez dit que vous aviez acheté [Produit]. Qu&#039;avez vous particulièrement apprécié en lui ?&amp;quot;.&lt;br /&gt;
Parfois vous avez besoin d&#039;une substitution conditionnelle comme &amp;quot;[M/Mme] [Nom], seriez vous prêt à remplir notre sondage ?. Dans ce cas vous voulez utiliser M ou Mme en fonction du sexe de la personne. D&#039;autres fois vous avez besoin de substitutions encore plus complexes (basées par exemple sur un calcul mathématique). Em supporte tous ces types de customisations.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60870</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60870"/>
		<updated>2014-02-27T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Notez que vous n&amp;#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/25/fr&amp;diff=60869</id>
		<title>Translations:Expression Manager/25/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/25/fr&amp;diff=60869"/>
		<updated>2014-02-27T17:35:04Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Notez que vous n&amp;#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60868</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60868"/>
		<updated>2014-02-27T17:34:00Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Voici l&amp;#039;écran pour éditer la pertinence de niveau groupe pour cette question.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that you do not use the curly braces when you enter a Relevance Equation.&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/23/fr&amp;diff=60867</id>
		<title>Translations:Expression Manager/23/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/23/fr&amp;diff=60867"/>
		<updated>2014-02-27T17:33:57Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Voici l&amp;#039;écran pour éditer la pertinence de niveau groupe pour cette question.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Voici l&#039;écran pour éditer la pertinence de niveau groupe pour cette question.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60866</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60866"/>
		<updated>2014-02-27T17:33:21Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez ré...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;br /&gt;
&lt;br /&gt;
Here is the screen for editing the group-level relevance for that question:&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that you do not use the curly braces when you enter a Relevance Equation.&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/22/fr&amp;diff=60865</id>
		<title>Translations:Expression Manager/22/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/22/fr&amp;diff=60865"/>
		<updated>2014-02-27T17:33:20Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez ré...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Comme vous pouvez le voir, le groupe aussi possède des critères de pertinence du niveau question, de telle façon que chaque question n’apparaît que lorsque vous avez répondu à la question précédente (e.g.{!is_empty(p1_sex)}). EM combine pour vous les équations de pertinence du niveau Groupe et Question pour vous. Les questions dans un groupe sont posées uniquement si le groupe dans son ensemble est pertinent. Ensuite , seulement le sous-ensemble de questions du groupe qui sont pertinentes sont effectivement posées.&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60864</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60864"/>
		<updated>2014-02-27T17:00:38Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&amp;#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affic...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, the group also has question-level relevance criteria, such that each question only appears once you have answered the question before it (e.g. {!is_empty(p1_sex)}).  EM combines the Group and Question-level relevance for you.  Questions in a group are only asked  if the group as a whole is relevant.  Then, only the subset of questions within the group that are relevant are asked.&lt;br /&gt;
&lt;br /&gt;
Here is the screen for editing the group-level relevance for that question:&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that you do not use the curly braces when you enter a Relevance Equation.&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/20/fr&amp;diff=60863</id>
		<title>Translations:Expression Manager/20/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/20/fr&amp;diff=60863"/>
		<updated>2014-02-27T17:00:37Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&amp;#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affic...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ceci est une exemple de sondage de recensement; La première page demande combien de personnes vivent avec vous et l&#039;enregistre dans la variable &amp;quot;cohabs&amp;quot;. Cette page est affiché seulement si vous avez plus d&#039;un co-habitant (elle est donc affichée pour la deuxième personne qui co-habite avec vous), et également seulement affiché si vous avez spécifié quelle est votre relation avec Person One (p1_rel).&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60862</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60862"/>
		<updated>2014-02-27T16:56:47Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;=== Voir / Modifier l&amp;#039;équation de filtre conditionnel au niveau du groupe ===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;br /&gt;
&lt;br /&gt;
This is a sample census survey.  The first page asks how many people live with you and stores that in the &amp;quot;cohabs&amp;quot; variable.  This page is only shown if you have more than one cohabitant (so it is shown for the second person cohabitating with you), and also only shows if you specified how Person One is related to you (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, the group also has question-level relevance criteria, such that each question only appears once you have answered the question before it (e.g. {!is_empty(p1_sex)}).  EM combines the Group and Question-level relevance for you.  Questions in a group are only asked  if the group as a whole is relevant.  Then, only the subset of questions within the group that are relevant are asked.&lt;br /&gt;
&lt;br /&gt;
Here is the screen for editing the group-level relevance for that question:&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that you do not use the curly braces when you enter a Relevance Equation.&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/19/fr&amp;diff=60861</id>
		<title>Translations:Expression Manager/19/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Translations:Expression_Manager/19/fr&amp;diff=60861"/>
		<updated>2014-02-27T16:56:46Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;=== Voir / Modifier l&amp;#039;équation de filtre conditionnel au niveau du groupe ===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau du groupe ===&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
	<entry>
		<id>https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60860</id>
		<title>Expression Manager/fr</title>
		<link rel="alternate" type="text/html" href="https://www.limesurvey.org/manual/index.php?title=Expression_Manager/fr&amp;diff=60860"/>
		<updated>2014-02-27T16:56:24Z</updated>

		<summary type="html">&lt;p&gt;Courtm: Created page with &amp;quot;Notez que vous n&amp;#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;languages /&amp;gt; &lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt; Remarque: Cette fonction est uniquement disponible dans LimeSurvey 1.92 ou plus tard. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Démarrage rapide=&lt;br /&gt;
&lt;br /&gt;
=Vue d&#039;ensemble=&lt;br /&gt;
&lt;br /&gt;
Quand vous paramétrez vos enquêtes, vous avez souvent besoin de pouvoir spécifier:&lt;br /&gt;
#&#039;&#039;&#039;Navigation/branchement&#039;&#039;&#039; - permet de modifier l&#039;ordre dans lequel sont posées les questions en fonction de la réponse du sondé&lt;br /&gt;
#&#039;&#039;&#039;Peaufiner&#039;&#039;&#039; - comment poser la question (en se référant aux réponses précédentes, ou en conjuguant les phrases de votre question en fonction du nombre ou du genre de votre sondé), ou comment générer des rapports personnalisés (comme des évaluations ou des conseils sur mesure).&lt;br /&gt;
#&#039;&#039;&#039;Validation&#039;&#039;&#039; - être sur que la question valide certains critères, comme des valeurs min et max, ou corresponde à un motif précis.&lt;br /&gt;
&lt;br /&gt;
L&#039;Expression Manager (EM) procure une façon intuitive de spécifier la logique de toutes ces fonctionnalités. Presque tout ce que vous pouvez écrire comme équation mathématique standard est une expression valide, même en appelant des fonctions. EM procure l&#039;accès à 70 fonctions et peut facilement être étendu pour en supporter d&#039;avantage. Il vous permet également d’accéder à vos variables avec des noms de variables lisibles (plutôt qu&#039;avec la notation SGQA).&lt;br /&gt;
&lt;br /&gt;
Les sections suivantes montrent quelles sont les principales circonstances où l&#039;Expression Manager (EM) est utilisé&lt;br /&gt;
&lt;br /&gt;
==Filtre conditionnel (Contrôle De Navigation/Branchement)==&lt;br /&gt;
&lt;br /&gt;
Certaines enquêtes utilisent une logique &amp;quot;aller à (&amp;quot;Goto Logic&amp;quot;), par exemple si vous répondez à la Question1 avec la réponse C, alors sautez à la Question5. Cette approche est très limitée, car il est très difficile de valider et de maintenir la cohérence si vous avez à ré-ordonner les questions. EM utilise une équation booléenne pour spécifier toutes les conditions sous lesquelles une question peut être valide. Si la question est pertinente, alors la question est posée, sinon elle n&#039;est pas applicable et la valeur NULL est stockée dans la base. C&#039;est similaire à ce qui peut être fait par l&#039;intermédiaire de l&#039;éditeur de conditions, mais EM vous permet de spécifier facilement des critères bien plus complexes et puissants (et vous permet d&#039;utiliser des noms de variables plutôt que la notation SGQA)&lt;br /&gt;
&lt;br /&gt;
Cette image montre une façon d&#039;appréhender la logique de la pertinence pour un questionnaire. Il calcule l&#039;Indice de Masse Corporelle. L&#039;équation de la pertinence est indiquée dans les crochets juste après le nom de la variable (qui est en vert). Donc, la pertinence du poids (weight), des unités de poids (weight_units), de la taille (height) et des unités de taille (height_units) sont toutes à 1, cela signifie que ces questions sont toujours posées. Cependant, la pertinence pour l&#039;IMC est {!is_empty(height) and !is_empty(weight)}, ce qui veut dire que l&#039;IMC sera calculé seulement si le sujet entre une valeur à la fois pour la taille et le poids (évitant ainsi le risque de division par 0). De même la question de rapport est montré seulement si le sujet répond aux quatre questions (taille, unité de taille, poids, unités de poids).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial1.jpg]]&lt;br /&gt;
&lt;br /&gt;
La pertinence est affichée et modifiables aux endroits suivants :&lt;br /&gt;
&lt;br /&gt;
=== Voir / Modifier l&#039;équation de filtre conditionnel au niveau de la question ===&lt;br /&gt;
&lt;br /&gt;
Cette équation calcule l&#039;Indice de Masse Corporelle (IMC). Elle est posée uniquement si la personne entre d&#039;abord sa taille et son poid&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial2.jpg]]&lt;br /&gt;
&lt;br /&gt;
Ceci est l&#039;écran d&#039;édition pour la question sur l&#039;IMC&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Notez que vous n&#039;avez pas à utiliser les accolades quand vous entrez une équation de pertinence&lt;br /&gt;
&lt;br /&gt;
===Viewing / Editing Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
This is a sample census survey.  The first page asks how many people live with you and stores that in the &amp;quot;cohabs&amp;quot; variable.  This page is only shown if you have more than one cohabitant (so it is shown for the second person cohabitating with you), and also only shows if you specified how Person One is related to you (p1_rel).&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial4.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, the group also has question-level relevance criteria, such that each question only appears once you have answered the question before it (e.g. {!is_empty(p1_sex)}).  EM combines the Group and Question-level relevance for you.  Questions in a group are only asked  if the group as a whole is relevant.  Then, only the subset of questions within the group that are relevant are asked.&lt;br /&gt;
&lt;br /&gt;
Here is the screen for editing the group-level relevance for that question:&lt;br /&gt;
&lt;br /&gt;
[[File:tutorial5.jpg]]&lt;br /&gt;
&lt;br /&gt;
Note that you do not use the curly braces when you enter a Relevance Equation.&lt;br /&gt;
&lt;br /&gt;
==Tailoring/Piping==&lt;br /&gt;
&lt;br /&gt;
EM lets you easily do simple and complex conditional tailoring of your questions.  Sometimes you just need simple substitution, like saying, &amp;quot;You said you purchased &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Product].  What did you like best about it?&amp;quot;.  Sometimes you need conditional substitution like &amp;quot;&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;LastName], would you be willing to complete our survey?&amp;quot;.  In this case,  you want to use Mr. or Mrs. based upon the person&#039;s gender.  Other times you need even more complex substitution (such as based upon a mathematical computation).  EM supports each of these types of tailoring/piping.&lt;br /&gt;
&lt;br /&gt;
===Conditional Equations===&lt;br /&gt;
&lt;br /&gt;
The Body Mass Index example shows the ability to compute a person&#039;s BMI, even while letting them enter their height in weight in metric or non-metric units.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring7.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here weight_kg is {if(weight_units == &#039;kg&#039;, weight, weight * .453592)}.  This if() function means that if the subject entered the weight using kilograms, use that value, otherwise multiple the entered value (which was in pounds) by .453592 to convert it to kilograms.  The height_m variable uses a similar approach to compute the person&#039;s height in meters, even if he entered his height in inches.&lt;br /&gt;
&lt;br /&gt;
BMI computes the weight formula as {weight_kg / (height_m * height_m)}.&lt;br /&gt;
&lt;br /&gt;
Lastly, the report conditionally tailors the message for the subject, telling him what he entered. (&amp;quot;You said you are 2 meters tall and weight 70 kg.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Although not well shown in the above image, weight_status uses nested if() statements to categorize the person as underweight to severely obese.  You can see its equation in the Show Logic View&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring8.jpg]]&lt;br /&gt;
&lt;br /&gt;
From the edit window for this question, you can see two things:&lt;br /&gt;
#Tailoring must surround expressions with Curly Braces&lt;br /&gt;
#Expressions can span multiple lines if, as in this case, you want to make it easier to read the nested conditional logic.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring9.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Tailored Questions, Answers, and Reports===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;simplebox&amp;quot;&amp;gt;Note: Dynamic tailoring may not work if answer options are made available in select boxes on the same question page. This results from the fact that tailoring inserts a &amp;lt;nowiki&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/nowiki&amp;gt; tag which is not valid inside select options.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example shows the BMI report.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring10.jpg]]&lt;br /&gt;
&lt;br /&gt;
Here is the edit window for the same question.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring11.jpg]]&lt;br /&gt;
&lt;br /&gt;
As you can see, anything in curly braces is treated as an expression, so is syntax-highlighted (color coded) in the prior image.  If you had any typos (such as misspelled or undefined variable names or functions), EM would show an error, such as this, showing that height_unit is an undefined variable name (it is actually height_units), and rnd() is an undefined function (the proper function name is round()).  In both cases, the errors are surrounded by a red box to make it easier to spot and fix them.&lt;br /&gt;
&lt;br /&gt;
[[File:tailoring12.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can also see that you can quickly create complex reports, such as a table of entered values or tailored advice.&lt;br /&gt;
&lt;br /&gt;
Please remember that all tailoring must surround expressions with Curly Braces, so that LimeSurvey knows which parts of the question are free text and which should be parsed through Expression Manager.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
EM controls how most of the advanced question options work.  These control aspects like min/max numbers of answers; min/max individual values; min/max sum values; and checking that entered values match specified string patterns.  You continue to enter those advanced question options as usual.  However, now any value in one of those fields is considered an expression, so you can have min/max criteria with complex conditional relationships to other questions.&lt;br /&gt;
&lt;br /&gt;
In all of these cases, since the advanced question option is always considered an expression, you do not use curly braces when specifying it.&lt;br /&gt;
&lt;br /&gt;
The [[Expression Manager Sample Surveys|Sample Surveys]] pages shows many working examples of using expressions for validations.&lt;br /&gt;
&lt;br /&gt;
=Introduction=&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 and later uses the new Expression Manager (EM) module which will let LimeSurvey support more complex branching, assessments, validation, and tailoring.  It will replace how LimeSurvey manages Replacements, Conditions, and Assessments on the back-end.  It will also speed up processing considerably since it eliminates most run-time database reads.  EM was developed by Dr. Thomas White (TMSWhite).&lt;br /&gt;
&lt;br /&gt;
This wiki page is the definitive reference for Expression Manager syntax and functionality.&lt;br /&gt;
&lt;br /&gt;
==Key Definitions==&lt;br /&gt;
#&#039;&#039;&#039;Expression&#039;&#039;&#039;:  Anything surrounded by curly braces&lt;br /&gt;
#*As long as there is no white space immediately after the opening brace or before the closing curly brace&lt;br /&gt;
#*The contents of Expressions are evaluted by EM, so they can contain mathematical formulas, functions, and complex string and date processing.&lt;br /&gt;
#&#039;&#039;&#039;Tailoring&#039;&#039;&#039;: Sometimes called &amp;quot;piping&amp;quot;, this is the process of conditionally modifying text&lt;br /&gt;
#*You have access to all &#039;replacement fields&#039;, TOKENs, and INSERTANS values&lt;br /&gt;
#*You also have easier access to questions, answers, and their properties.&lt;br /&gt;
#&#039;&#039;&#039;Relevance&#039;&#039;&#039; Equation:  A new question attribute controlling question visiblity&lt;br /&gt;
#*If there is a relevance equation, then the question is only shown if the relevance evaluates to true.&lt;br /&gt;
#*Internally, all array_filter and array_filter_exclude commands become sub-question-level relevance&lt;br /&gt;
#&#039;&#039;&#039;Equation&#039;&#039;&#039; Question Type:  A new question type that saves calculations or reports to the database&lt;br /&gt;
#*It is like a Boilerplate question, but its contents are saved to the database even if you set &amp;quot;Always Hide this Question&amp;quot;&lt;br /&gt;
#&#039;&#039;&#039;SGQA&#039;&#039;&#039;:  This is how variables are named in LimeSurvey &amp;lt;= 1.91+&lt;br /&gt;
#*Stands for Survey-Group-Question-Answer&lt;br /&gt;
#*SGQA variable names look like 123X5X382X971, and may have sub-question suffixes.&lt;br /&gt;
#*These variable names are specific to the underlying S/Q/G/A database codes, so often need to be changed&lt;br /&gt;
#&#039;&#039;&#039;Question Code&#039;&#039;&#039;:  This is the preferred variable name for EM&lt;br /&gt;
#*This can be a descriptive name indicating the purpose of the question, making it easier to read complex logic&lt;br /&gt;
#*Although not required to be unique in &amp;lt;= 1.91+, it must be unique if you want to use EM&lt;br /&gt;
#*Valid question codes should NOT start with a number, so when using the question code to number your questions, simply use &amp;quot;q1&amp;quot;, or &amp;quot;q1a&amp;quot; or &amp;quot;g1q2&amp;quot;.&lt;br /&gt;
#*This is what currently becomes the variable name if you export data to SPSS or R, so if you do statistical analysis, you probably already made this unique.&lt;br /&gt;
&lt;br /&gt;
==Do I have to use EM?==&lt;br /&gt;
&lt;br /&gt;
The short answer is No (but also yes).&lt;br /&gt;
&lt;br /&gt;
EM is fully backwards-compatible with existing surveys.  So, if you are happy to use Conditions and Assessments in the style that LimeSurvey used in versions &amp;lt;= 1.91+, you can continue to do so.&lt;br /&gt;
&lt;br /&gt;
However, EM completely replaces how LimeSurvey internally deals with Conditions.  Although you can still use the Conditions Editor to create and manage conditions, LimeSurvey 1.92 will convert those to the equivalent Relevance Equations.  As part of the upgrade, LimeSurvey 1.92 will auto-convert all existing Conditions to Relevance Equations.&lt;br /&gt;
&lt;br /&gt;
This should give you the best of both worlds - you can continue using LimeSurvey as you are used to, but will see the Relevance Equation equivalent so you can gradually migrate to Relevance Equations directly whenever you see fit.&lt;br /&gt;
&lt;br /&gt;
==Can I mix use of Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Yes. You can use the Conditions editor for some questions and the Relevance editor for others.  Conditions are auto-converted to Relevance when you save the question.&lt;br /&gt;
&lt;br /&gt;
Note, we assume that if you are using the Conditions editor, that you want those Conditions to over-write any manually entered Relevance equation.  So, if you have existing Conditions and want to manually edit the Relevance, please delete the Conditions for that question first.  Specifically, copy the generated relevance equation to a text editor, use the Conditions menu to delete all of the conditions for that question (which will also delete the relevance), then edit the question and paste the generated relevance equation from the text editor back into the relevance field for that question (and save the question).  If there is enough demand for deleting conditions without deleting the generated relevance equation, we could add a bulk conversion process.&lt;br /&gt;
&lt;br /&gt;
==How should I choose between Conditions and Relevance?==&lt;br /&gt;
&lt;br /&gt;
Here is a list of pros and cons of each style:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Style!!Pros!!Cons&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||1. Nice GUI for creating simple conditions &amp;lt;br/&amp;gt;2. GUI well documented and understood by support team||1. Only supports simple comparisons and does not AND/OR conditions well &amp;lt;br/&amp;gt;2. Cascading conditions work erratically &amp;lt;br/&amp;gt;3. Slow - database intensive, so can slow down long surveys &amp;lt;br/&amp;gt;4. Some reported problems with re-loading conditions &amp;lt;br/&amp;gt;5. GUI doesn&#039;t scale well when there are dozens, hundreds, or thousands of questions &amp;lt;br/&amp;gt;6. May be slow to convert paper-based surveys since must use SGQA names &amp;lt;br/&amp;gt;7. Often need a programmer to custom-code logic needed for complex branching&lt;br /&gt;
|-&lt;br /&gt;
|Relevance||1. Supports very complex logic, including 80+ functions and math/string operators &amp;lt;br/&amp;gt;2. Perfect support for cascading logic &amp;lt;br/&amp;gt;3. Fast - no extra database calls, so supports 1000+ question surveys &amp;lt;br/&amp;gt;4. No problems with re-loading logic since does not require SGQA codes &amp;lt;br/&amp;gt;5. Syntax-highlighting scales to 1000+ question surveys &amp;lt;br/&amp;gt;6. Easy and fast to use for groups wanting to computerize existing paper-based suveys.  &amp;lt;br/&amp;gt;7. Easily supports semi-structured interviews and epidemiological surveys without needing a programmers||1. No GUI for simple conditions - use syntax-highlighting instead &amp;lt;br/&amp;gt;2. New, so support teams have not mastered EM yet.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The bottom is that if you are happy with how LimeSurvey 1.91+ works, there is no reason to change what you do.&lt;br /&gt;
&lt;br /&gt;
==What are some other benefits of using EM?==&lt;br /&gt;
&lt;br /&gt;
Here are some of the other reasons you might want to use EM.&lt;br /&gt;
#Calculations - you can create any calculation you can think of:&lt;br /&gt;
#*You have access to all common mathematical operators and functions&lt;br /&gt;
#*You have access to 70+ mathematical, date, and string processing functions&lt;br /&gt;
#*It is fairly easy for developers to add new functions if users need them&lt;br /&gt;
#Storing Calculations to Database&lt;br /&gt;
#*You can now compute simple and complex calculations and/or scale scores AND have them stored in the database without needing JavaScript.&lt;br /&gt;
#*You use the Equation question type to accomplish this.&lt;br /&gt;
#Assessments&lt;br /&gt;
#*You can now create assessments or scale scores from any question type, not just the subset that used to be supported&lt;br /&gt;
#*You can use Tailoring to show running or total assessment scores anywhere needed - even on the same page&lt;br /&gt;
#*You have more control over the reports generated based upon those assessment scores&lt;br /&gt;
#*You can store assessment scores in the database without needing JavaScript&lt;br /&gt;
#*You can hide assessment scores without needing JavaScript or CSS&lt;br /&gt;
#Replacement Fields&lt;br /&gt;
#*Instead of using {INSERTANS:SGQA}, you can just use the Question Code - this makes it easier to read and validate.&lt;br /&gt;
#*This also avoids the common need to edit questions to change the SGQA code to make everything work.&lt;br /&gt;
#Tailoring - you can conditionally display text based upon other values&lt;br /&gt;
#*Use the appropriate title for a subject, like (e.g. &amp;quot;Hello &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;Mr./Mrs.] Smith&amp;quot;)&lt;br /&gt;
#*Output gramatically correct sentences based when singular/plural matter:  (e.g. &amp;quot;You have 1 child&amp;quot; vs. &amp;quot;You have 2 children&amp;quot;)&lt;br /&gt;
#*Appropriately conjugate verbs and decline nouns based upon subject&#039;s gender and plurality.&lt;br /&gt;
#New Variable Attributes - you can access the following to do your tailoring:&lt;br /&gt;
#* (no suffix) -  an alias for qcode.code&lt;br /&gt;
#*.code - the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.NAOK - same as .code, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.value - the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question&lt;br /&gt;
#*.valueNAOK - same as .value, but can be part of calculations or lists even if irrelevant&lt;br /&gt;
#*.shown - the answer as displayed to the user (this is what {INSERTANS:xxx}  does)&lt;br /&gt;
#*.qid - the question ID&lt;br /&gt;
#*.gid - the group ID&lt;br /&gt;
#*.sgqa - the SGQA value for the question&lt;br /&gt;
#*.jsName - the correct javascript variable name for the question, regardless whether defined on this page or another&lt;br /&gt;
#*.qseq - the question sequence (starting from 0)&lt;br /&gt;
#*.gseq - the group sequence (starting from 0)&lt;br /&gt;
#*.mandatory - whether the question is mandatory (Y/N)&lt;br /&gt;
#*.question - the text of the question&lt;br /&gt;
#*.relevance - the relevance equation for the question&lt;br /&gt;
#*.grelevance - the relevance equation for the group&lt;br /&gt;
#*.relevanceStatus - whether or not the question is currently relevant (1 if true, 0 if false)&lt;br /&gt;
#*.type - the question type (the one character code)&lt;br /&gt;
#Dynamic On-Page Changes&lt;br /&gt;
#*All Relevance, Calculation, and Tailoring works dynamically on a page - so changes in values instantly update the page&lt;br /&gt;
#*So, you have questions dynamically appear/disappear based upon whether they are relevant&lt;br /&gt;
#*Questions are also dynamically tailored based upon responses on the page, so you can see running totals, tailored sentences and customized reports.&lt;br /&gt;
#New Data Entry Screen&lt;br /&gt;
#*In addition to using the current data-entry system, you can just use Survey-All-In-One.&lt;br /&gt;
#*This supports the on-page relevance and tailoring, so data entry clerks can quickly tab through and they will only have to enter the relevant responses&lt;br /&gt;
#*This can be critical if your data entry person needs to see the tailoring, which is also dynamic.&lt;br /&gt;
#Eliminates the need for most custom JavaScript&lt;br /&gt;
#*EM easily supports complicated computations, scoring, tailoring and conditional logic.&lt;br /&gt;
#*Some things will still need JavaScript (like custom layouts and conditionally hiding question sub-elements), but your JavaScript can use the EM functions so that you can access questions by their Qcode instead of SGQA, and access any of the question properties listed above.&lt;br /&gt;
&lt;br /&gt;
==What are some other helpful new features enabled by EM?==&lt;br /&gt;
&lt;br /&gt;
Regardless of whether you continue to use the Conditions Editor or manually compose Relevance Equations, you get these additional benefits:&lt;br /&gt;
#You can create more complex validation criteria&lt;br /&gt;
#*All of the advanced question attribute (like max_answers, min_num_value_n, max_num_value) can use Expressions.  So, you min/max criteria can be easily adjusted based upon prior responses, even if they are on the same page.&lt;br /&gt;
#*EM also handles all regular-expression-based validation, so you can robustly combine preg and equation-based question attributes.&lt;br /&gt;
#Easy Re-ordering (or deleting) of Questions and Groups&lt;br /&gt;
#*Prior to version 1.92, you could not re-order questions or groups if LimeSurvey thought that such-re-ordering could break conditions in which they were used.  Similarly, you could not delete questions if any other questions depended upon them.&lt;br /&gt;
#*With EM&#039;s syntax highlighting, it is easy to see and validate whether you try to use questions before they are declared.  So, we now let you re-order or delete questions and groups whenever you like.  EM will update all of the syntax highlighting to show you potential errors.&lt;br /&gt;
#*The re-order questions view has been enhanced to help with such review.  It now shows the question&#039;s relevance equation and tailoring, so you can immediately see whether any variables become pink (meaning they are used before being declared).&lt;br /&gt;
#The Question/Group Navigation Index is always available and accurate&lt;br /&gt;
#*Prior to version 1.92, these indexes were not available if there were complex conditions&lt;br /&gt;
#*With EM, we can guarantee that they are accurate.&lt;br /&gt;
#*Subjects can even jump back, to a prior question, change the answer, then jump forward (or submit)&lt;br /&gt;
#**When jumping forwards, EM will re-validate all of the intervening questions/groups.&lt;br /&gt;
#**If any questions become irrelevant, they will be NULLed in the database so that your data is internally consistent&lt;br /&gt;
#**If any questions become relevant or newly fail mandatory or validation rules, EM will stop on that page and force the user to answer those questions before jumping to their final destination.&lt;br /&gt;
#Auto-conversion of Conditions to Relevance&lt;br /&gt;
#*When you upgrade your database, all existing surveys that have conditions will have relevance equations generated for them&lt;br /&gt;
#*Whenever you import a survey, relevance equations will be created as needed&lt;br /&gt;
#*Whenever you add, delete, or modify conditions, EM will generate the appropriate relevance equation.&lt;br /&gt;
#Convenient Syntax Highlighting&lt;br /&gt;
#*When EM shows the relevance equation, it will show the Qcode, even if you entered an SGQA code, as we assume this will be easier to read.&lt;br /&gt;
#*All variables are color coded to show whether they were declared before or after the current question (or before or after the current group).  This lets you quickly detect and fix cases where you try to use variables for relevance (including array_filter), tailoring, or validation equations prior to declaring them.&lt;br /&gt;
#*In addition, if you hover your mouse over the color-coded variable, you will see the most important metadata about that question.   This includes the Group Sequence #, Question Sequence #, Qcode, Text of the question, and all available answer choices (if it is a question type with enumerated answer choices).&lt;br /&gt;
#**The list of answer choices uses this syntax:  &#039;answers&#039;:{key:val, ... }.&lt;br /&gt;
#**&#039;&#039;key&#039;&#039; has the syntax &#039;&#039;&#039;&#039;scale~code&#039;&#039;&#039;&#039; where &#039;&#039;scale&#039;&#039; is the answer scale (e.g. for dual scale), and &#039;&#039;code&#039;&#039; is the answer code.&lt;br /&gt;
#**&#039;&#039;val&#039;&#039; has the syntax &#039;&#039;&#039;&#039;value~shown&#039;&#039;&#039;&#039; where &#039;&#039;value&#039;&#039; is the assessment value (if using assessments, otherwise &#039;&#039;code&#039;&#039;)(e.g. Qcode.value), and &#039;&#039;shown&#039;&#039; is the display value as seen by the subject (e.g. Qcode.shown)&lt;br /&gt;
#**This means that many surveys can use calculations without needing assessment mode.  If you have enumerated answer options  that are unique, non-decimal, and non-negative, you can simply do calculations on the Qcode.code values.&lt;br /&gt;
#Easy review of entire survey logic and content&lt;br /&gt;
#*There is a new Show Survey Logic feature that lets you see everything about the survey (or group or question) on a single page.&lt;br /&gt;
#*It shows the Group, Question, Sub-Question, and Answer-level details for the selected scope (survey vs. group vs. question)&lt;br /&gt;
#*It also shows the relevance, sub-question-level relevance (for array_filter and array_filter_exclude), and generated validation equation (for preg and any validation rules like min/max sum/number of values), and all non-blank question attributes.&lt;br /&gt;
#*Everything is syntax-highlighted so that you can see potential syntax errors (like unbalanced parentheses or use of variables before they were declared)&lt;br /&gt;
#*The syntax-highligting supports rapid navigation and editing of the survey.&lt;br /&gt;
#**If you click on a variable name, it opens a browser window (or tab) that shows you that question and lets you edit it.&lt;br /&gt;
#**If you click on a group name, it opens a browser window (or tab) showing the group-reorder view so that you can easily move questions around.&lt;br /&gt;
#**All of the question attributes are also syntax highlighted.  This lets you set and see expressions within advanced question options (like basing the max/min number/sum of values on an expression)&lt;br /&gt;
#*The EM author used similar view (a little cleaner) to let his collaborating Epidemiologists and Institutional Review Board validate and authorize surveys with thousands of questions in highly branched and tailored structured interviews&lt;br /&gt;
&lt;br /&gt;
==How Backwards Compatible is EM with 1.91+?==&lt;br /&gt;
&lt;br /&gt;
LimeSurvey 1.92 is fully backwards-compatible with 1.91+ with one exception/caveat:  1.92 handles less-than / greater-than comparisons against empty values differently than 1.91+.&lt;br /&gt;
&lt;br /&gt;
One of the LimeSurvey demo surveys uses a set of conditions that translates to this relevance equation:  {(age &amp;lt; 16) or (age == 20) or ... or (age == 80)}. In LimeSurvey 1.91+, (age &amp;lt; 16) is FALSE when there is no answer (the value is blank).  However, in LimeSurey 1.92, (age &amp;lt; 16) is TRUE when there is no answer, since both PHP and JavaScript treat blank as 0 in mathematical comparisons.  Thus, 1.91+ would hide that question when age was unanswered, but 1.92 would show it.  We went to great pains to prevent this, but since we needed to have the Expressions generate identical results in PHP and JavaScript, there was no way to make 1.92 treat &amp;quot;&amp;quot; &amp;lt; 16 as FALSE.  Fortunately, there is an easy work-around for this.  If you want (age &amp;lt; 16) to be FALSE, then use this expression instead: {(!is_empty(age) and age &amp;lt; 16)}.  You can use the new [[Show Logic File|Survey Logic File]] view to quickly identify and fix any such comparisons in your survey.&lt;br /&gt;
&lt;br /&gt;
=Getting Started=&lt;br /&gt;
&lt;br /&gt;
The best way to get started with EM is to:&lt;br /&gt;
*Install the latest stable version from http://www.limesurvey.org/en/download &lt;br /&gt;
*Import and explore the [[Expression Manager Sample Surveys|sample surveys]].&lt;br /&gt;
*Explore the [[Expression Manager HowTos|use cases and HowTos]] and [[Expression Manager Examples|step-by-step examples]].&lt;br /&gt;
*Explore the EM documentation (this page)&lt;br /&gt;
*Examine the built-in EM test suite&lt;br /&gt;
**From any survey, under tools, select the EM option&lt;br /&gt;
**Available Functions lists the 70+ functions and syntax&lt;br /&gt;
**Unit Tests of Isolated Expressions&lt;br /&gt;
***shows examples of using all EM functions and operators, and the PHP and JavaScript results&lt;br /&gt;
***note there are few functions that generate different results in the PHP and JavaScript versions, so this page lets you plan your EM logic accordingly.&lt;br /&gt;
&lt;br /&gt;
=What Functionality does Expression Manager Extend/Replace? (LimeSurvey &amp;lt;= 1.91+)=&lt;br /&gt;
&lt;br /&gt;
==Conditions =&amp;gt; Relevance==&lt;br /&gt;
&lt;br /&gt;
Conditions controlled which  questions are visible.  The general syntax was &#039;&#039;SGQA operator Value&#039;&#039;, like &#039;&#039;111X2X3 == &amp;quot;Y&amp;quot;&#039;&#039;.  Conditions could be ANDed or ORed together, but mixing ANDs and ORs was difficult.  The conditions themselves were stored in a separate table, and large portion of LimeSurvey&#039;s code was devoted to managing Conditions.  Because of extensive database access, processing large numbers of conditions could cause noticable performance problems.  Furthermore, once you had conditions assigned to questions or groups, you were often not allowed to re-order or delete them.&lt;br /&gt;
&lt;br /&gt;
==Assessments =&amp;gt; Equations and  Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Assessments let users create scale scores from a collection of questions.  However, they could not dynamically change on the current page, and their values were not stored to the database.&lt;br /&gt;
&lt;br /&gt;
==Replacements =&amp;gt; Micro-Tailoring==&lt;br /&gt;
&lt;br /&gt;
Users could tailor some messages and questions based  upon prior responses.  For example, a question might be, &#039;&#039;{TOKEN:FIRSTNAME}, you said {INSERTANS:111X3X4} was your favorite sport&#039;&#039;.  However, it was not possible to do conditional tailoring (like say &amp;quot;Mr.&amp;quot; or &amp;quot;Mrs.&amp;quot; depending upon the person&#039;s gender), or conjugate verbs or decline nouns without fancy JavaScript.  Authors could implement surveys that seemed to tailor questions, but it required separate questions for each permutation, and complex conditions to decide which questions to display.&lt;br /&gt;
&lt;br /&gt;
==Validation==&lt;br /&gt;
&lt;br /&gt;
Question could be validated with Regular expressions, or minimum/maximum values, or let an SGQA response serve as the minimum or maximum value.  However, validations could not be based upon calculations of other variables without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equations==&lt;br /&gt;
&lt;br /&gt;
Equations were not supported without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
==Equation Question Type==&lt;br /&gt;
&lt;br /&gt;
Equations could not be saved to the database (e.g. the final score for an assessment) without fancy JavaScript.&lt;br /&gt;
&lt;br /&gt;
=How Will Expression Manager Replace/Extend That Functionality?=&lt;br /&gt;
&lt;br /&gt;
The Expression Manager is a new core module within LimeSurvey that makes it much easier to support the type of complex functionality that used to require custom JavaScript.  It is also replacing the way LimeSurvey currently manages Conditions and Assessments.&lt;br /&gt;
&lt;br /&gt;
==New Terminology When Referring to Expression Manager (EM)==&lt;br /&gt;
&lt;br /&gt;
EM &amp;quot;thinks&amp;quot; of its functionality in the following terms:&lt;br /&gt;
*&#039;&#039;&#039;Relevance-based Branching&#039;&#039;&#039; - if a question is relevant, then ask it, otherwise don&#039;t (e.g. make it invisible, and mark it as NULL in the database).  There is a new Relevance field for all Question types, and also for each Group (so you can apply a set of conditions to an entire group without having to copy the same condition to each question, and/or combine group and question-level conditional logic).&lt;br /&gt;
*&#039;&#039;&#039;Tailoring&#039;&#039;&#039; - Once you know which questions should be asked, tailoring (sometimes called &#039;&#039;piping&#039;&#039;) specifies how the question should be asked. This lets you support not only simple subsitution (like {TOKEN:FIRSTNAME}), but also conjugation of verbs and declination of nouns based upon the gender or number of your subjects.  It also lets you change the message you deliver to a subject based upon whether they answered (or how they answered) other questions.&lt;br /&gt;
*&#039;&#039;&#039;Equations&#039;&#039;&#039; - EM adds a new question type called Equation which stores the result of an Expression.  These equations results are computed and written to the database, even if you hide them on the page.  Thus, they are useful for hidden scoring calculations, navigation based upon complex equations, assessments, and reports that should be generated and easily available within the database.&lt;br /&gt;
&lt;br /&gt;
===Relevance and Cascading Relevance===&lt;br /&gt;
&lt;br /&gt;
Every question type now has a Relevance option which controls whether the question is displayed.  EM processes each of the Relevance Equations in the order they should appear in the survey.  If the expression is true (or missing - to support legacy surveys), the question will be displayed. If it is not relevant, then the question will be hidden, and the value will be NULLed in the database.  If there are no relevant questions in a group, the entire group will be skipped.&lt;br /&gt;
&lt;br /&gt;
Moreover, if any of the variables within an expression is irrelevant, then the expression always evaluates to false.  This enables Cascading Relevance so that you do not have to write very long Relevance equations for each question.&lt;br /&gt;
&lt;br /&gt;
Say you have 5 questions Q1-Q5, and you only want to show Q2 if Q1 was answered, and Q3 if Q2 was answered, etc.  The relevance equations might be:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question&lt;br /&gt;
|-&lt;br /&gt;
|Q1||1||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|Q2||Q1||{Q1}, how old are you?&lt;br /&gt;
|-&lt;br /&gt;
|Q3||Q2||So, you are {Q2} years old.  Are you married?&lt;br /&gt;
|-&lt;br /&gt;
|Q4||Q3 == &amp;quot;Y&amp;quot;||{Q1}, how long have you been married?&lt;br /&gt;
|-&lt;br /&gt;
|Q5||Q4||How many children do you have, {Q1}?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The relevance calculations also work in JavaScript - so you could put all the above questions on one page and it would still work as expected.  In fact, EM totally replaces how EM processes Survey vs. Group vs. Question-at-a-time survey formats.  They now all use the exactly same navigation engine so they work identically regardless of survey style.&lt;br /&gt;
&lt;br /&gt;
As long as you are on the same page, any data you entered will still be there, just hidden.  So, if you enter some information, then choose an option that makes them irrelevant, then make them relevant again, your answers will still be available.  However, as soon as you move to a different page, all irrelevant responses will be lost to integrity of the dataset.&lt;br /&gt;
&lt;br /&gt;
===Group-Level Relevance===&lt;br /&gt;
&lt;br /&gt;
Expression Manager also supports group-level relevance.  This makes it easier to implement looping.   Say you want to collect information about up to 10 entities (such a products or people in a household), where you first determine how many entities need follow-up (such as by asking how many people live in a household, or having people check which products they like from a long list).  After knowning how many entities need follow-up, you can use Group-level relevance like {count &amp;gt;= 1}, {count &amp;gt;=2}, ... {count &amp;gt;= 10} for each of the 10 groups of follow-up questions.  Within each group, you can have question-level conditional logic (e.g. gender or age-specific follow-up questions for each subject).  The question and group-level relevance equations are ANDed together to determine which should be shown.&lt;br /&gt;
&lt;br /&gt;
===Tailoring / Piping===&lt;br /&gt;
&lt;br /&gt;
Anything within curly braces is now treated as an Expression (with one exception described below).  Expressions have acccess to all of the LimeReplacementFields, all of the variables (via several aliases), all typical equation operators (mathematical, logical, and comparison), and dozens of functions (that even work dynamically on the client-side).&lt;br /&gt;
&lt;br /&gt;
Using these equations, you can do things such as:&lt;br /&gt;
#Conditionally show tailored messages to the respondants based upon prior responses&lt;br /&gt;
#Create Assessments and show Assessment results (or conditionally branch or show messages) based upon those results, all without using the Assessments module itself&lt;br /&gt;
#Conjugate verbs and decline nouns within questions, answers, and reports.&lt;br /&gt;
#Show summaries of responses before the &amp;quot;Show your answers&amp;quot; page at the end of the survey&lt;br /&gt;
&lt;br /&gt;
===Equations===&lt;br /&gt;
&lt;br /&gt;
There is a new question type called  Equation.  It is like a Boilerplate questions, except that it stores the value of what is displayed in the database.  So, if the Equation Question text contains an Assessment computation, that value would be stored in the database in a variable that can be displayed within public or private statistics.&lt;br /&gt;
&lt;br /&gt;
This solves a common request for storing Assessment scores within the database&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Anything contained within curly braces is now considered an Expression (with one exception:  there must be no leading or trailing whitespace - this is needed to ensure the Expression Manager does not try to process embedded JavaScript).&lt;br /&gt;
&lt;br /&gt;
Note, it is OK for expressions to span multiple lines, as long as there is no whitespace after the opening  curly brace or before the closing curly brace.  This is especially helpful for nested if() statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; enclose=&amp;quot;div&amp;quot;&amp;gt;{if(is_empty(PFTotals),&lt;br /&gt;
 &#039;&#039;,&lt;br /&gt;
 if(PFTotals &amp;gt;= -5 &amp;amp;&amp;amp; PFTotals &amp;lt;= -4,&lt;br /&gt;
   &#039;Very Soft&#039;,&lt;br /&gt;
   if(PFTotals &amp;gt;= -3 &amp;amp;&amp;amp; PFTotals &amp;lt;= -2,&lt;br /&gt;
     &#039;Soft&#039;,&lt;br /&gt;
     if(PFTotals == -1,&lt;br /&gt;
       &#039;Somewhat Soft&#039;,&lt;br /&gt;
       if(PFTotals == 0,&lt;br /&gt;
         &#039;Moderate&#039;,&lt;br /&gt;
         if(PFTotals == 1,&lt;br /&gt;
           &#039;Somewhat Hard&#039;,&lt;br /&gt;
           if(PFTotals &amp;gt;= 2 &amp;amp;&amp;amp; PFTotals &amp;lt;= 3,&lt;br /&gt;
             &#039;Hard&#039;,&lt;br /&gt;
             if(PFTotals &amp;gt;= 4 &amp;amp;&amp;amp; PFTotals &amp;lt;= 5,&lt;br /&gt;
               &#039;Very Hard&#039;,&lt;br /&gt;
               &#039;&#039;&lt;br /&gt;
             )&lt;br /&gt;
           )&lt;br /&gt;
         )&lt;br /&gt;
       )&lt;br /&gt;
     )&lt;br /&gt;
   )&lt;br /&gt;
 )&lt;br /&gt;
)}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Expression Manager supports the following syntax:&lt;br /&gt;
*All standard mathematical operators (e.g. +,-,*,/,!)&lt;br /&gt;
*All standard comparison operators (e.g. &amp;lt;,&amp;lt;=,==,!=,&amp;gt;,&amp;gt;=, plus these equivalents:  lt,le,eq,ne,gt,ge)&lt;br /&gt;
*Parentheses (so you can group sub-expressions)&lt;br /&gt;
*Conditional operators (e.g. &amp;amp;&amp;amp;,| | and these equivalents: and,or)&lt;br /&gt;
*Single and double-quoted strings (which can each embed strings with the other quote type)&lt;br /&gt;
*Comma operator (so can have a list of expressions and just return the final result)&lt;br /&gt;
*Assignment operator (=)&lt;br /&gt;
*Pre-defined variables (to refer to questions, question attributes, and responses) - e.g. all of the SGQA codes&lt;br /&gt;
*Pre-defined functions (there are already 70+, and it is easy to add more)&lt;br /&gt;
&lt;br /&gt;
EM syntax follows normal operator precedence:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Level!!Operator(s)!!Description&lt;br /&gt;
|-&lt;br /&gt;
|1||()||parentheses for grouping or calling functions&lt;br /&gt;
|-&lt;br /&gt;
|2||! - +||unary operators: not, negation, unary-plus&lt;br /&gt;
|-&lt;br /&gt;
|3||* /||times, divide&lt;br /&gt;
|-&lt;br /&gt;
|4||+ -||plus, minus&lt;br /&gt;
|-&lt;br /&gt;
|5||&amp;lt; &amp;lt;= &amp;gt; &amp;gt;= lt le gt ge||relative comparisons&lt;br /&gt;
|-&lt;br /&gt;
|6||== != eq ne||equality comparisons&lt;br /&gt;
|-&lt;br /&gt;
|7||and||logical AND&lt;br /&gt;
|-&lt;br /&gt;
|8||or||logical OR&lt;br /&gt;
|-&lt;br /&gt;
|9||=||assignment operator&lt;br /&gt;
|-&lt;br /&gt;
|10||,||comma operator&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note, for consistency between JavaScript and PHP, the plus operator (+) does addition if both operands are numeric, but does concatenation if both parts are non-numeric strings.  However, we recommend using the join() function for concatenation, as that makes your intent more clear, and avoids unexpected results if you were expecting strings but got numbers instead (or vice versa).&lt;br /&gt;
&lt;br /&gt;
===Caution about using Assignment Operator (=)===&lt;br /&gt;
&lt;br /&gt;
Note, you should avoid using the assignment operators unless absolutely necessary, since they may cause unexpected side-effects.  For example, if you change the value of a previous response, the cascading relevance and validation logic between that question and the current question is not re-computed, so you could end up with internally inconsistent data (e.g. questions that stay answered but should have been NULLed, or questions that are skipped but should have been answered).  In general, if you want to assign a value to a variable, you sould create an Equation question type, and use an expression to set its value.  However, there are some rare times that people really need this operator, so we made it available.&lt;br /&gt;
&lt;br /&gt;
To help caution you about this operator, it is shown in red font within the syntax equations (so that you don&#039;t confuse it with &amp;quot;==&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The main reasons you may want to use assignment are:&lt;br /&gt;
*You need to set the default value for a question that does not accept defaults via equation (such as list radio, where the user interface lets you pick one of the answer options, but does not let you enter an equation).  However, be careful, as LimeSurvey will not be able to validate that your equation generates one of the allowable answers for that question.&lt;br /&gt;
*You need to forcibly change the response to a previous question based upon a later response&lt;br /&gt;
&lt;br /&gt;
==Access to Variables==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides read-only access to whichever variables we might need.  For backwards compatibility, it provides access to the following:&lt;br /&gt;
*TOKEN:xxx - the value of a TOKEN (e.g. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (Only for NOT anonymous survey).&lt;br /&gt;
*INSERTANS:SGQA - the display value of an answer (e.g. &amp;quot;Yes&amp;quot;)&lt;br /&gt;
*All {XXX} values used by templates&lt;br /&gt;
*In question text, you can use {QID} replaced by the question id and {SGQ} replaced by the SGQA of the question&lt;br /&gt;
&lt;br /&gt;
In addition, Expression Manager lets you refer to variables by the Question Code (the &#039;title&#039; column in the questions table within the database).  This is also the variable label used when you export your data to SPSS, R, or SAS.  For example, if you have questions about name, age, and gender, you could call those variables &#039;&#039;name&#039;&#039;, &#039;&#039;age&#039;&#039;, and &#039;&#039;gender&#039;&#039; instead of &#039;&#039;12345X13X22&#039;&#039;, &#039;&#039;12345X13X23&#039;&#039;, and  &#039;&#039;12345X13X24&#039;&#039;.  This makes equations easier for everyone to read and validate the logic, plus makes it possible to shuffle questions around without having to keep track of group or question numbers.&lt;br /&gt;
&lt;br /&gt;
Furthermore, Expression Manager lets you access many properties of the Question:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Example!!Example Result&lt;br /&gt;
|-&lt;br /&gt;
|Qcode||an alias for Qcode.code||{implode(&#039;,&#039;,name,gender)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.code||the selected response code for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{implode(&#039;,&#039;,name.code,gender.code)}||&#039;Tom&#039;,&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.NAOK||same as Qcode - see discussion of NAOK||{gender.NAOK}||&#039;M&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.value||the assessment value for the question if it is relevant (otherwise blank), or the text value if it is not a coded question||{gender.value}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.valueNAOK||same as Qcode.value - see discussion about NAOK||{gender.valueNAOK}||&#039;1&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.shown||the dispay value for the question||{implode(&#039;,&#039;,name.shown,gender.shown)}||&#039;Tom&#039;,&#039;Male&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.question||the text of the question||{gender.question}||&#039;What is your gender?&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.mandatory||whether the question is mandatory (Y/N)||{gender.mandatory}||&#039;N&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qid||the internal question number (not the sequential number)||{gender.qid}||337&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.type||the question type||{gender.type}||&#039;G&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.jsName||the correct javascript name for the question, regardless whether declared on or off this page||{gender.jsName}||&#039;java1827X3X337&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gid||the internal group number (not the sequential number)||{gender.gid}||3&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.qseq||the sequential number of the question, starting from 0||{gender.qseq}||5&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.gseq||the sequential number of the group, starting from 0||{gender.gseq}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevanceStatus||whether the question is currently relevant (0 or 1)||{gender.relevanceStatus}||1&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.relevance||the question-level relevance equation||{gender.relevance}||&#039;!is_empty(name)&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.grelevance||the  group-level relevance equation||{gender.grelevance}||&#039;num_children &amp;gt;= 5&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Qcode.sgqa||the SGQA value for this question||{gender.sgqa}||&#039;1827X3X337&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Security issue===&lt;br /&gt;
&lt;br /&gt;
For security issues, text entered by user are filtered. Some characters are replaced by HTML entities.&lt;br /&gt;
* &amp;amp; by &amp;amp;amp;amp;&lt;br /&gt;
* &amp;lt; by &amp;amp;amp;lt;&lt;br /&gt;
* &amp;gt; by &amp;amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Qcode Variable Naming==&lt;br /&gt;
&lt;br /&gt;
Here are the details of how to construct a Qcode (and access some properties) by question type.  In general, Qcodes are constructed as:&lt;br /&gt;
&lt;br /&gt;
  QuestionCode . &#039;_&#039; . SubQuestionID . &#039;_&#039; . ScaleId&lt;br /&gt;
&lt;br /&gt;
For comment and other, question code are QuestionCode_comment and QuestionCode_other&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type!!Description!!Code!!SubQs!!Answer Options!!Scales!!Answer Code!!Answer Shown!!Relevance&lt;br /&gt;
|-&lt;br /&gt;
|5||5 Point Choice Radio-Buttons||Q1|| ||1-5|| ||{Q1}||{Q1.shown}||{Q1==3}&lt;br /&gt;
|-&lt;br /&gt;
|B||Array (10 Point Choice) Radio-Buttons||Q2||L1-L6||1-10|| ||{Q2_L2}||{Q2_L2.shown}||{Q2_L2==7}&lt;br /&gt;
|-&lt;br /&gt;
|A||Array (5 Point Choice) Radio-Buttons||Q3||1-5||1-5|| ||{Q3_1}||{Q3_1.shown}||{Q3_1&amp;gt;=3}&lt;br /&gt;
|-&lt;br /&gt;
|1||Array (Flexible Labels) Dual Scale||Q4||sq1-sq5||0:a1-a3||1:b1-b3||{Q4_sq1_0}||{Q4_sq1_1.shown}||{Q4_sq1_1==&#039;b2&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|H||Array (Flexible) - Column Format||Q5||1-5||s,m,t|| ||{Q5_1}||{Q5_1.shown}||{Q5_1==&#039;s&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|F||Array (Flexible) - Row Format||Q6||F1-F5||1-5|| ||{Q6_F3}||{Q6_F3.shown}||{Q6_F3==4}&lt;br /&gt;
|-&lt;br /&gt;
|E||Array (Increase/Same/Decrease) Radio-Buttons||Q7||1-7||I,S,D|| ||{Q7_4}||{Q7_4.shown}||{Q7_4==&#039;D&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|:||Array (Multi Flexi) 1 To 10||Q8||ls1,todo,ls2||min,max,avg|| ||{Q8_ls1_max}||{Q8_ls2_avg.shown}||{Q8_ls2_min==7}&lt;br /&gt;
|-&lt;br /&gt;
|;||Array (Multi Flexi) Text||Q9||hp,st,sw||1st,2nd,3rd|| ||{Q9_hp_3rd}||{Q9_hp_3rd.shown}||{Q9_hp_3rd==&#039;Peter&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|C||Array (Yes/Uncertain/No) Radio-Buttons||Q10||1-5||Y,N,U|| ||{Q10_1}||{Q10_1.shown}||{Q10_3==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|X||Boilerplate Question||Q11|| || || || ||{Q11.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|D||Date||Q12|| || || ||{Q12}||{Q12.shown}||&lt;br /&gt;
|-&lt;br /&gt;
|*||Equation||Q13|| || || ||{Q13}||{Q13.shown}||{Q13&amp;gt;5}&lt;br /&gt;
|-&lt;br /&gt;
|~124~||File Upload (records number of files uploaded)||Q14|| || || ||{Q14}|| ||{Q14&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|G||Gender Drop-Down List||Q15|| ||M,F|| ||{Q15}||{Q15.shown}||{Q15==&#039;M&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|U||Huge Free Text||Q16|| || || ||{Q16}||{Q16.shown}||{strlen(Q16)&amp;gt;100}&lt;br /&gt;
|-&lt;br /&gt;
|I||Language Question||Q17|| || || ||{Q17}||{Q17.shown}||{Q17==&#039;en&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|!||List - Dropdown||Q18|| ||1-5|| ||{Q18}||{Q18.shown}||{Q18==3}&lt;br /&gt;
|-&lt;br /&gt;
|L||List Drop-Down/Radio-Button List||Q19|| ||A-Z|| ||{Q19}||{Q19.shown}||{Q19==&#039;X&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|O||List With Comment Drop-Down/Radio-Button List + Textarea||Q20|| ||A-F|| ||{Q20},{Q20comment}||{Q20.shown}||{Q20==&#039;B&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|T||Long Free Text||Q21|| || || ||{Q21}||{Q21.shown}||{strstr(Q21,&#039;hello&#039;)&amp;gt;0}&lt;br /&gt;
|-&lt;br /&gt;
|M||Multiple Choice Checkbox||Q22||A-F|| || ||{Q22_E}||{Q22_E.shown}||{Q22_E==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|P||Multiple Choice With Comments Checkbox + Text||Q23||A-F|| || ||{Q23_D}, {Q23_Dcomment}||{Q23_D.shown}||{!is_empty(Q23)}&lt;br /&gt;
|-&lt;br /&gt;
|K||Multiple Numerical Question||Q24||self,mom,dad|| || ||{Q24_self}||{Q24_self.shown}||{Q24_self&amp;gt;30}&lt;br /&gt;
|-&lt;br /&gt;
|Q||Multiple Short Text||Q25||A-F|| || ||{Q25_B}||{Q25_B.shown}||{substr(Q25_B,1,1)==&#039;Q&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|N||Numerical Question Type||Q26|| || || ||{Q26}||{Q26.shown}||{Q26 &amp;gt; 30}&lt;br /&gt;
|-&lt;br /&gt;
|R||Ranking Style||Q27||1-4|| || ||{Q27_1}||{Q27_1.shown}||{Q27_1==3}&lt;br /&gt;
|-&lt;br /&gt;
|S||Short Free Text||Q28|| || || ||{Q28}||{Q28.shown}||{Q28==&#039;mine&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|Y||Yes/No Radio-Buttons||Q29|| || || ||{Q29}||{Q29.shown}||{Q29==&#039;Y&#039;}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==The reserved &#039;this&#039;, &#039;self&#039;, and &#039;that&#039; variables==&lt;br /&gt;
&lt;br /&gt;
Quite often, you want to evalute all parts of a question, such as counting how many sub-questions have been answered, or summing the scores.  Other times, you want to process just certain rows or columns of a question (such as getting the row or column sums and storing them in the database).  These reserved variables make that process relatively painless.&lt;br /&gt;
&lt;br /&gt;
The &#039;this&#039; variable is used exclusively within the &amp;quot;Whole question validation equation&amp;quot; and &amp;quot;Sub-question validation equation&amp;quot; advanced question options.  It expands to the variable names of each of the cells within those questions.  So, if you want to make sure that each entry is greater than three, you would set the &amp;quot;Sub-question validation equation&amp;quot; to (this &amp;gt; 3).&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variable are more powerful, and serve as macros which are expanded prior to processing equations.  The syntax choices are:&lt;br /&gt;
*self&lt;br /&gt;
*self.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*self.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;suffix&#039;&#039; is any of the normal qcode suffixes (e.g. NAOK, value, shown)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sub-selector&#039;&#039; is one of:&lt;br /&gt;
*comments - only subquestions that are comments (e.g. from multiple choice with comment and list with comment)&lt;br /&gt;
*nocomments - only subquestions that are not comments&lt;br /&gt;
*sq_X - where X is a row or column identifier.  Only sub-questions matching pattern X are selected. Note that search is done on complete code identifier, then sq_X match and include subquestions nX, X, Xn (e.g. if you use sq_1, subquestions a1, 1a, 1, 11 or 001 was included). Put attention at dual scale question type where subquestions code are QCODE_SQCODE_1 and QCODE_SQCODE_1 and to ranking question type where subquestions code are QCODE_1,QCODE_2 ....&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of a question been answered?  {count(self.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for this question?  {sum(self.value)}&lt;br /&gt;
&lt;br /&gt;
You can also use these to get row and column totals.  Say you have a array of numbers with rows A-E and columns 1-5.&lt;br /&gt;
*What is the grand total?  {sum(self.NAOK)}&lt;br /&gt;
*What is the total of row B?  {sum(self.sq_B.NAOK)}&lt;br /&gt;
*What is the total of column 3? {sum(self.sq_3.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;that&#039; variable is like the &#039;self&#039; variable, but lets you refer to other questions.  Its syntax is:&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;&lt;br /&gt;
*that.&#039;&#039;qname&#039;&#039;.&#039;&#039;sub-selector&#039;&#039;.&#039;&#039;suffix&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;qname&#039;&#039; is the question name without any sub-question extensions.  So, say you create a question &#039;q1&#039;, that is its &#039;&#039;qname&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
*Has any part of question q1 been answered?  {count(that.q1.NAOK)&amp;gt;0}&lt;br /&gt;
*What is the assessment score for q2?  {sum(that.q2.NAOK)}&lt;br /&gt;
*What is the grand total of q3? {sum(that.q3.NAOK)}&lt;br /&gt;
*What is the total of row C in q4?  {sum(that.q4.sq_C.NAOK)}&lt;br /&gt;
*What is the total of column 2 in q4? {sum(that.q4.sq_2.NAOK)}&lt;br /&gt;
&lt;br /&gt;
The &#039;self&#039; and &#039;that&#039; variables can be used in any relevance,  validation, or tailoring.&lt;br /&gt;
&lt;br /&gt;
The one caveat is that when you use the [[Show Logic File|Show Logic File]] feature, it will show you the expanded value of &#039;self&#039; and &#039;that&#039;.  This lets you see the actual equation that will be generated so that you (and Expression Manager) can validate that the variables exist.  This may seem confusing since you may see quite lenghty equations.  However, if you edit the question, you will see the original equation using &#039;self&#039; and/or &#039;that&#039;&lt;br /&gt;
&lt;br /&gt;
Also note that you should not use these variables if (a) you want to explicitly name each variable used in an equation, or (b) use variables that do not have sub-questions (e.g. single response questions).  In those cases, prefixing a variable with &#039;that&#039; is overkill, and you run the risk of getting unexpected results.&lt;br /&gt;
&lt;br /&gt;
==Access to Functions==&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides access to mathematical, string, and user-defined functions, as shown below.  It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript).  It is easy to add new functions.&lt;br /&gt;
&lt;br /&gt;
===Implemented Functions===&lt;br /&gt;
&lt;br /&gt;
The following functions are currently available:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Function!!Meaning!!Syntax&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.abs.php abs]||Absolute value||number abs(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.acos.php acos]||Arc cosine||number acos(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.addslashes.php addslashes]||Quote string with slashes||string addslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.asin.php asin]||Arc sine||number asin(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan.php atan]||Arc tangent||number atan(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.atan2.php atan2]||Arc tangent of two variables||number atan2(number, number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ceil.php ceil]||Round fractions up||number ceil(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.checkdate.php checkdate]||Returns true(1) if it is a valid date in gregorian calendar||bool checkdate(month,day,year)&lt;br /&gt;
|-&lt;br /&gt;
|convert_value||Convert a numerical value using a inputTable and outputTable of numerical values||number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.cos.php cos]||Cosine||number cos(number)&lt;br /&gt;
|-&lt;br /&gt;
|count||count the number of answered (non-blank)questions in the list||number count(arg1, arg12, ..., argN)&lt;br /&gt;
|-&lt;br /&gt;
|countif||Count the number of answered questions in the list equal the first argument||number countif(matches, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|countifop||Count the number of answered questions in the list which pass the criteria (arg op value)||number countifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.date.php date]||Format a local date/time||string date(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.exp.php exp]||Calculates the exponent of e||number exp(number)&lt;br /&gt;
|-&lt;br /&gt;
|fixnum||Display numbers with comma as radix separator, if needed||string fixnum(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.floor.php floor]||Round fractions down||number floor(number)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.gmdate.php gmdate]||Format a GMT date/time||string gmdate(format &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.html-entity-decode.php html_entity_decode]||Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8)||string html_entity_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlentities.php htmlentities]||Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlentities(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars.php expr_mgr_htmlspecialchars]||Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.htmlspecialchars-decode.php expr_mgr_htmlspecialchars_decode]||Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8)||string htmlspecialchars_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.idate.php idate]||Format a local time/date as integer||string idate(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, timestamp=time()])&lt;br /&gt;
|-&lt;br /&gt;
|if||Excel-style if(test,result_if_true,result_if_false)||if(test,result_if_true,result_if_false)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.implode.php implode]||Join array elements with a string||string implode(glue,arg1,arg2,...,argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.intval.php intval]||Get the integer value of a variable||int intval(number &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, base=10])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.empty.php is_empty]||Determine whether a variable is considered to be empty||bool is_empty(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-float.php is_float]||Finds whether the type of a variable is float||bool is_float(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-int.php is_int]||Find whether the type of a variable is integer||bool is_int(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-nan.php is_nan]||Finds whether a value is not a number||bool is_nan(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-null.php is_null]||Finds whether a variable is NULL||bool is_null(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-numeric.php is_numeric]||Finds whether a variable is a number or a numeric string||bool is_numeric(var)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.is-string.php is_string]||Find whether the type of a variable is string||bool is_string(var)&lt;br /&gt;
|-&lt;br /&gt;
|join{{NewIn|2.0|b=130129}}||Join elements as a new string||join(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|list||Return comma-separated list of non-blank values||string list(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.log.php log]|| The logarithm of number to base, if given, or the natural logarithm. ||number log(number,base=e)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ltrim.php ltrim]||Strip whitespace (or other characters) from the beginning of a string||string ltrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.max.php max]||Find highest value||number max(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.min.php min]||Find lowest value||number min(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.mktime.php mktime]||Get UNIX timestamp for a date (each of the 6 arguments are optional)||number mktime([hour [, minute [, second [, month [, day [, year ]]]]]])&lt;br /&gt;
|-&lt;br /&gt;
|modulo-function||The modulo function is &#039;&#039;&#039;not supported&#039;&#039;&#039; yet. You can use the floor() function instead||floor(x/y)==(x/y)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.nl2br.php nl2br]||Inserts HTML line breaks before all newlines in a string||string nl2br(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.number-format.php number_format]||Format a number with grouped thousands||string number_format(number)&lt;br /&gt;
|-&lt;br /&gt;
|pi||Get value of pi||number pi()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.pow.php pow]||Exponential expression||number pow(base, exp)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-decode.php quoted_printable_decode]||Convert a quoted-printable string to an 8 bit string||string quoted_printable_decode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quoted-printable-encode.php quoted_printable_encode]||Convert a 8 bit string to a quoted-printable string||string quoted_printable_encode(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.quotemeta.php quotemeta]||Quote meta characters||string quotemeta(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rand.php rand]||Generate a random integer, see [[Expression Manager Sample Surveys#Randomly Ask One Question Per Group|this example]]||int rand() OR int rand(min, max)&lt;br /&gt;
|-&lt;br /&gt;
|regexMatch||compare a string to a [[Using regular expressions|regular expression]]||bool regexMatch(pattern,input)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.round.php round]||Rounds a number to an optional precision||number round(val &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, precision])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.rtrim.php rtrim]||Strip whitespace (or other characters) from the end of a string||string rtrim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sin.php sin]||Sine||number sin(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sprintf.php sprintf]||Return a formatted string||string sprintf(format, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.sqrt.php sqrt]||Square root||number sqrt(arg)&lt;br /&gt;
|-&lt;br /&gt;
|stddev||Calculate the Sample Standard Deviation for the list of numbers||number stddev(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-pad.php str_pad]||Pad a string to a certain length with another string||string str_pad(input, pad_length &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, pad_string])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-repeat.php str_repeat]||Repeat a string||string str_repeat(input, multiplier)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.str-replace.php str_replace]||Replace all occurrences of the search string with the replacement string||string str_replace(search, replace, subject)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcasecmp.php strcasecmp]||Binary safe case-insensitive string comparison||int strcasecmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strcmp.php strcmp]||Binary safe string comparison||int strcmp(str1, str2)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strip-tags.php strip_tags]||Strip HTML and PHP tags from a string||string strip_tags(str, allowable_tags)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripos.php stripos]||Find position of first occurrence of a case-insensitive string||int stripos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stripslashes.php stripslashes]||Un-quotes a quoted string||string stripslashes(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.stristr.php stristr]||Case-insensitive strstr||string stristr(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, before_needle=false])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strlen.php strlen]||Get string length||int strlen(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strpos.php strpos]||Find position of first occurrence of a string||int strpos(haystack, needle &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt; offset=0])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strrev.php strrev]||Reverse a string||string strrev(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strstr.php strstr]||Find first occurrence of a string||string strstr(haystack, needle)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtolower.php strtolower]||Make a string lowercase||string strtolower(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtotime.php strtotime]||Parse about any English textual datetime description into a Unix timestamp||int strtotime(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.strtoupper.php strtoupper]||Make a string uppercase||string strtoupper(string)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.substr.php substr]||Return part of a string||string substr(string, start &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, length])&lt;br /&gt;
|-&lt;br /&gt;
|sum||Calculate the sum of values in an array||number sum(arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|sumifop||Sum the values of answered questions in the list which pass the criteria (arg op value)||number sumifop(op, value, arg1, arg2, ... argN)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.tan.php tan]||Tangent||number tan(arg)&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.time.php time]||Return current UNIX timestamp||number time()&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.trim.php trim]||Strip whitespace (or other characters) from the beginning and end of a string||string trim(string &amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;, charlist])&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.php.net/manual/en/function.ucwords.php ucwords]||Uppercase the first character of each word in a string||string ucwords(string)&lt;br /&gt;
|-&lt;br /&gt;
|unique||Returns true if all non-empty responses are unique||boolean unique(arg1, ..., argN)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Functions that are Planned or Being Considered===&lt;br /&gt;
&lt;br /&gt;
Other functions that are planned (or being considered) but which are not implemented yet include the following.  Some of these are for backwards compatability with another survey tool.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Syntax!!Meaning!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|e()||returns the value of e||&lt;br /&gt;
|-&lt;br /&gt;
|formatDate(X,PAT)||return the string value of date X formatted according to Java data format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|formatNumber(X,PAT)||return the string value of number X formatted according to Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X)||returns the text corresponding to the selected option for answer X||this is the same as X.shown&lt;br /&gt;
|-&lt;br /&gt;
|getAnsOption(X,Y)||returns the text corresponding to the option at index Y of node X||&lt;br /&gt;
|-&lt;br /&gt;
|getRelevance(X)||returns the relevance equation for question X||&lt;br /&gt;
|-&lt;br /&gt;
|getStartTime()||returns the date corresponding to the system time when the interview was started||&lt;br /&gt;
|-&lt;br /&gt;
|getType(X)||returns the string name of the datatype - e.g. *NA* if isNA()||&lt;br /&gt;
|-&lt;br /&gt;
|gotoFirst()||jumps to the first relevant set of questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoNext()||jumps to the next set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|gotoPrevious()||jumps to the previous set of relevant questions - this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|isAsked(X)||returns true if the answer is neither *NA*, *INVALID*, nor *UNASKED*||&lt;br /&gt;
|-&lt;br /&gt;
|isInvalid(X)||returns true if the answer is of type *INVALID*||&lt;br /&gt;
|-&lt;br /&gt;
|isNA(X)||returns true if the answer is of type *NA*||&lt;br /&gt;
|-&lt;br /&gt;
|isNotUnderstood(X)||returns true if the answer if of type *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isRefused(X)||returns true if the answer is of type *REFUSED*||&lt;br /&gt;
|-&lt;br /&gt;
|isSpecial(X)||returns true if the answer is of type *UNASKED*, *NA*, *REFUSED*, *INVALID*, *UNKNOWN*, or *HUH*||&lt;br /&gt;
|-&lt;br /&gt;
|isUnknown(X)||returns true if the answer is of type *UNKNOWN*||&lt;br /&gt;
|-&lt;br /&gt;
|jumpTo(X)||jump to the group containing the named question -- this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|jumpToFirstUnasked()||jump to the first unasked question &amp;lt;strike&amp;gt; thus bypassing previous answered questions &amp;lt;/strike&amp;gt; this violates the normal flow of the system||&lt;br /&gt;
|-&lt;br /&gt;
|lastIndexOf(X,Y)||returns the last index (base 0) of string Y in string X. Returns -1 if Y is not contained within X||&lt;br /&gt;
|-&lt;br /&gt;
|list(X,...)||a string containing a comma separated list of the positive values with &amp;quot;and&amp;quot; separating the last two||&lt;br /&gt;
|-&lt;br /&gt;
|mean(X,...)||returns the mean of a list of values||&lt;br /&gt;
|-&lt;br /&gt;
|numAnsOptions(X)||returns the number of answer options that question X has||&lt;br /&gt;
|-&lt;br /&gt;
|orlist(X,...)||a string containing a comma separated list of the positive values, with &amp;quot;or&amp;quot; separting the last two||&lt;br /&gt;
|-&lt;br /&gt;
|parseDate(X,PAT)||returns the date value of string X parsed with Java date format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|parseNumber(X,PAT)||returns the numerical value of string X parsed with Java number format pattern PAT||&lt;br /&gt;
|-&lt;br /&gt;
|showAllResponsesExcept( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.||&lt;br /&gt;
|-&lt;br /&gt;
|showTheseResponses( questionList,attributeList,attributeTitleList)||questionList = pipe-delimited list of question identifiers; attributeList = pipe-delimited list of attributes (like question#, title, text, type - so you can decide what to show); attributeTitleList = pipe-delimited list of table headers, so can internationalize the report.|| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Expression Manager Knows Which Variables are Local==&lt;br /&gt;
&lt;br /&gt;
In order to properly build the JavaScript for page, Expression Manager needs to know which variables are set on the page, and what their JavaScript ID is (e.g. for document.getElementById(x)).  It also must know which variables are set on other pages (so that it can ensure that the needed &amp;lt;input type=&#039;hidden&#039; value=&#039;x&#039;&amp;gt; fields are present and populated).&lt;br /&gt;
&lt;br /&gt;
==Cascading Conditions==&lt;br /&gt;
&lt;br /&gt;
If any of the variables are irrelevant, the whole equation will be irrelevant (false).  For example, in the following table, N/A means that one of the variables was not relevant&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Operator!!Example!!a!!b!!Result&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+ (unary)&amp;lt;/nowiki&amp;gt;||&amp;lt;nowiki&amp;gt;+a&amp;lt;/nowiki&amp;gt;||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|- (unary)||-a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|!||!a||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|== (or eq)||a == b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||N/A|| false&lt;br /&gt;
|-&lt;br /&gt;
|!= (or ne)||a != b||N/A||0||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt; (or gt)||a &amp;gt; b||N/A||5|| false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;gt;= (or ge)||a &amp;gt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt; (or lt)||a &amp;lt; b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;= (or le)||a &amp;lt;= b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|and||a and b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|or||a or b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;+&amp;lt;/nowiki&amp;gt;||a + b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|-||a - b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|*||a * b||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|/||a / b||5||N/A||false&lt;br /&gt;
|-&lt;br /&gt;
|()||(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp)||(a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|(exp) op (exp)||(b + b) &amp;gt; (a &amp;amp;&amp;amp; b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||sum(a,b,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||max(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||min(a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||implode(&#039;, &#039;,a,b,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||if(a,a,b)||N/A||5||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||N/A|| ||false&lt;br /&gt;
|-&lt;br /&gt;
|function||is_empty(a)||0 (or blank)|| ||true&lt;br /&gt;
|-&lt;br /&gt;
|function||!is_empty(a)||N/A|| ||false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Overriding Cascading Conditions===&lt;br /&gt;
&lt;br /&gt;
Say you want to show a running total of all relevant answers.  You might try to use the equation {sum(q1,q2,q3,...,qN)}.  However, this gets translated internally to LEMif(LEManyNA(&#039;q1&#039;,&#039;q2&#039;,&#039;q3&#039;,...,&#039;qN&#039;),&#039;&#039;,sum(LEMval(&#039;q1&#039;),LEMval(&#039;q2&#039;),LEMval(&#039;q3&#039;),...,LEMval(&#039;qN&#039;))).  So, if any of the values q1-qN are irrelevant, the equation will always return false.  In this case, the sum() will show 0 until all questions are answered.&lt;br /&gt;
&lt;br /&gt;
To get around this, each variable can have a &amp;quot;.NAOK&amp;quot; suffix (meaning that Not Applicable is OK) added to it.  In such cases, the following behavior occurs.  Say you have a variable q1.NAOK&lt;br /&gt;
#q1 is not added to the LEManyNA() clause&lt;br /&gt;
#LEMval(&#039;q1&#039;) will  continue to check whether the response is relevant, and will return &amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt; if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).&lt;br /&gt;
&lt;br /&gt;
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).&lt;br /&gt;
&lt;br /&gt;
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later.  For example, say subjects answer a survey in a way that is outside the normal range of responses.  The author could alert the subjects that they may not get valid results, and ask them whether they really want to  continue with the survey.  If they say Yes, then the rest of the questions will be shown.  The condition for the &amp;quot;rest of the questions&amp;quot; would check whether the initial responses were answered within the normal range OR whether the subject said Yes to the question that is only relevant if they answered outside the normal range.&lt;br /&gt;
&lt;br /&gt;
==How does Expression Manager Support Conditional Micro-Tailoring?==&lt;br /&gt;
&lt;br /&gt;
Here is an example of micro-tailoring (where Question Type==&#039;expr&#039; means an Equation):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Question Code!!Relevance!!Question Type!!Question&lt;br /&gt;
|-&lt;br /&gt;
|name||1||text||What is your name?&lt;br /&gt;
|-&lt;br /&gt;
|age||1||text||How old are you?&lt;br /&gt;
|-&lt;br /&gt;
|badage||!is_empty(age)||expr||{(age&amp;lt;16) or (age&amp;gt;80)}&lt;br /&gt;
|-&lt;br /&gt;
|agestop||badage||message||Sorry, {name}, you are too {if( (age&amp;lt;16),&#039;young&#039;,if( (age&amp;gt;80),&#039;old&#039;,&#039;middle-aged&#039;) ) } for this test.&lt;br /&gt;
|-&lt;br /&gt;
|kids||!badage||yesno||Do you have children?&lt;br /&gt;
|-&lt;br /&gt;
|parents||1||expr||{!badage &amp;amp;&amp;amp; kids==&#039;Y&#039;}&lt;br /&gt;
|-&lt;br /&gt;
|numKids||parents||text||How many children do you have?&lt;br /&gt;
|-&lt;br /&gt;
|kid1||parents &amp;amp;&amp;amp; numKids &amp;gt;= 1||text||How old is your first child?&lt;br /&gt;
|-&lt;br /&gt;
|kid2||parents &amp;amp;&amp;amp; numKids &amp;gt;= 2||text||How old is your second child?&lt;br /&gt;
|-&lt;br /&gt;
|kid3||parents &amp;amp;&amp;amp; numKids &amp;gt;= 3||text||How old is your third child?&lt;br /&gt;
|-&lt;br /&gt;
|kid4||parents &amp;amp;&amp;amp; numKids &amp;gt;= 4||text||How old is your fourth child?&lt;br /&gt;
|-&lt;br /&gt;
|kid5||parents &amp;amp;&amp;amp; numKids &amp;gt;= 5||text||How old is your fifth child?&lt;br /&gt;
|-&lt;br /&gt;
|sumage||1||expr||{sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)}&lt;br /&gt;
|-&lt;br /&gt;
|report||parents||yesno||{name}, you said you are {age} and that you have {numKids}.  The sum of ages of your first {min(numKids,5)} kids is {sumage}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All of these questions can be on a single page (e.g. in the same group), and only the relevant questions will display.  Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically update on the page.&lt;br /&gt;
&lt;br /&gt;
Expression Manager provides this functionality by surrounding each expression with a named &amp;lt;span&amp;gt; element.  Every time a value changes, it recomputes the expression that should appear in that &amp;lt;span&amp;gt; element and regenerates the display.  You can have dozens, or even hundreds, of such tailored expressions on the same page, and the page will re-display all of them in a single screen refresh.&lt;br /&gt;
&lt;br /&gt;
==Mapping of LimeSurvey 1.91+ to Expression Manager Functionality==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Old Feature!!New Feature!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|Conditions||Relevance||You can use very complex conditional equations, and access a broader range of variables&lt;br /&gt;
|-&lt;br /&gt;
|Assessments||Equation||Any assessment scores can be re-structured into an Equation. This both ensures that the score is written to the database, and also lets you see dynamic changes to the score value on the current page&lt;br /&gt;
|-&lt;br /&gt;
|Replacements||Expression Manager||The core engine takes the input string and treats everything within curly braces as an Expression - so it handles all historical replacements types.  To avoid messing up embedded JavaScript, Expression Manager only processes content between curly braces as long as (a)  there is no leading or trailing whitespace within the curly braces - e.g. {expr} is an expression, but { expr}, {expr }, and { expr } are not expressions.  Furthermore, Expression Manager does not process content within its own strings (e.g. {list(&#039;hi&#039;,&#039;there {braces}&#039;)} generates &amp;quot;hi there {braces}&amp;quot;).  It also ignores escaped curly braces (e.g. \{this is not an expression\})&lt;br /&gt;
|-&lt;br /&gt;
|Validation||Expression Manager||The plan is to take the current min/max Question Attributes and have Expression Manager process them.  That way the min/max values can be expressions themselves&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Syntax Highlighting=&lt;br /&gt;
&lt;br /&gt;
To help with entering and validating expressions, EM provides syntax highlighting with the following features:&lt;br /&gt;
&lt;br /&gt;
==Types and Meanings of Syntax Highlighting==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Color!!Sample!!Meaning!!Tooltip!!Comments&lt;br /&gt;
|-&lt;br /&gt;
|tan background||style=&#039;background-color: #eee8aa&#039;|Sample||the whole equation||none||Anything within curly braces that is recognized as an equation (e.g. there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text&lt;br /&gt;
|-&lt;br /&gt;
|blue bold text||style=&#039;color:blue; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||function name||meaning and allowable syntax||function names, or things that should be functions since they are followed by an opening parenthesis, are presented in bold blue text.  Tooltips show the meaning and allowable syntax for the function.&lt;br /&gt;
|-&lt;br /&gt;
|grey text||style=&#039;color:grey; background-color:#eee8aa&#039;|Sample||string||none||single and double-quoted strings are shown in grey text&lt;br /&gt;
|-&lt;br /&gt;
|bold maroon text||style=&#039;color:maroon; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, but after the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page but after the current question is shown in bold maroon text.  This color coding should alert authors to possible errors in question sequencing; but it is allowed since some authors may want this sequence of variables a page, especially for dynamic reports.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold cyan text||style=&#039;color:#4C88BE; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on the same page, prior to the current question||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on the same page and prior to the current question is shown in bold cyan text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold green text||style=&#039;color:green; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a prior page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold green text.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold pink text||style=&#039;color:#FF00FF; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||variable set on a later page||&amp;lt;nowiki&amp;gt;[&amp;lt;/nowiki&amp;gt;name or SGQA code]: question; value; answerList showing codes for each value||Any variable that is set on a prior page is shown in bold pink text.  These are erorrs since the variable is  being used before it is declareed.  The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set).  If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show.&lt;br /&gt;
|-&lt;br /&gt;
|bold tan text||style=&#039;color:#996600; background-color:#eee8aa&#039;|&#039;&#039;&#039;Sample&#039;&#039;&#039;||a lime replacement value||the value||Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text.  &lt;br /&gt;
|-&lt;br /&gt;
|red text||style=&#039;color:red; background-color:#eee8aa&#039;|Sample||assignment operator||warning message||If you use one of the assignment operator (=) that operator will be displayed in red text.  This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of  setting the value of a = b.&lt;br /&gt;
|-&lt;br /&gt;
|normal black text||style=&#039;color:black; background-color:#eee8aa&#039;|Sample||punctuation||none||All other punctuation within the expression is shown as normal black text.&lt;br /&gt;
|-&lt;br /&gt;
|red-boxed text||a bold red line surrounds the error||syntax error||description of the error||Any detected syntax errors are shown by surrounding the error with a red box.  The tooltip shows the error.  Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g. missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax.  Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Additional Reading=&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Sample Surveys|Expression Manager Sample Surveys]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager HowTos|Use Cases and HowTos]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Examples|Step-by-Step Examples]].==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager for developers|Reference for Developers]]==&lt;br /&gt;
&lt;br /&gt;
==[[Expression Manager Roadmap|RoadMap/Status/ToDo List]]==&lt;/div&gt;</summary>
		<author><name>Courtm</name></author>
	</entry>
</feed>