SurveyFactory Documentation Documentation Custom template functions
Custom template functions

We have defined many custom template functions for use by survey and template designers. You may also want to view custom template filters or template variables. The following is a list of functions available:

allowBackwardMove

This function returns a true value if you have checked the Move backward within survey option within the respondent movement section of your publication editor. You may wish to use it in your templates in order to present the user with a back button:

[% IF allowBackwardMove && isPrevPage; %]
  <input type="submit" name="cmd_prevpage"
    value="[% page.template.button_prevtext | eval %]">
[% END; %]

allowForwardJump

This function returns a true value if you have checked the Jump forward within survey option within the respondent movement section of your publication editor. It is currently used within the getTocPages function to determine whether pages that have not yet been visited should be linked.

allowModifyComplete

This function returns a true value if you have checked the Allow respondents to modify their survey response after completion option within the Manage Resopnses section of your publication editor. It is commonly used to display the "Edit Response" button when displaying the default completion message.

[% IF allowModifyComplete %]
  <input type="submit" name="changecq_1"
    value="[% survey.template.button_edittext %]">
[% END %]

This function is also used in the getPageButtons function to determine whether or not the "Edit Response" button should be shown during custom completion behavior.

allowSaveForLater

This function returns a true value if you have checked the Save response progress and return later option within the respondent movement section of your publication editor. It is currently used within the getPageButtons function to determine whether or not the "Save for Later" button should be shown.

allowSubmitAny

This function returns a true value if you have checked the Submit from any page within survey (once 100% complete) option within the respondent movement section of your publication editor. You may wish to use it in your templates in order to provide the user with a submit button:

[% IF isComplete && allowSubmitAny %]
  <input type="submit" name="cmd_complete"
    value="[% page.template.button_submittext %]">
[% END %]

evalDefault

It is important to never eval any form input value, as it can allow injection of cross-site scripting vulnerabilities into your survey. You may at first think that in order to be able to use Template-Toolkit within a text field default, you would therefore need to evaluate the question.answer.f_value parameter. This is dangerous, however, as users could then enter arbitrary Template-Toolkit code into your survey and have it executed. Instead, the proper thing to do is compare the f_value to the default, and if it is the same, you can eval the default and use that. Here is some sample code for how you can enable Template Toolkit in the default value for a Single Text Field question type:


Calling evalDefault() as:

tfValue = evalDefault(question.answer.default, question.answer.f_value);

is equivalent to:

[%
tfValue = question.answer.f_value;
tfDefault = question.answer.default | escapeHTML;
IF tfDefault != '' && tfDefault == tfValue;
  tfValue = question.answer.default | eval | escapeHTML;
END;
%]

You can then use this value in your template, such as:

[% IF question.answer.type == 'textarea'; %]
  <textarea name="[% question.answer.f_name %]">[% tfValue %]</textarea>
[% ELSE; %]
  <input type="text" name="[% question.answer.f_name %]" value="[% tfValue %]" />
[% END; %]

You can see that the above evalDefault() will compare the answer's value to that of the default string. Answer values always have their HTML escaped (so you can put them directly into value="" attributes), so we escape the default as well. If those are equal, then we evaluate the answer default that has been entered by the survey designer, but you can see that we never evaluate the answer.f_value field, which could contain malicious code entered by a survey respondent.

getNextPage

This function takes a single, optional argument, which is a page template variable, and then returns the next page in the survey response. If you do not pass in any argument, the survey.page variable, which defines the current page in the survey, will be used. If no survey.page is defined, or there is no next page in the survey because you are on the last page, this function will return false (0).

The page returned by this function will contain all of the page template variables. This function will not distinguish between pages that are part of the response and pages found in the completion behavior, you will need to test the .incompletion variable if you need to know the difference. We recommend that for purposes of displaying the "Next Page" button, you use the function getPageButtons.

See also: isNextPage, getPrevPage

getPageButtons

This function takes one argument, a page object, and returns a hash that will advise you on which buttons should be displayed for that page. If no page argument is supplied, it will default to survey.page. In the event that survey.page does not exist, it will return an empty hash. Otherwise, the structure may contain any of the following button types:

pageButtons.
   nextpage        # If the next page button should be shown
   prevpage        # If the previous page button should be shown
   complete        # If the submit survey button should be shown
   saveforlater    # If the save for later button should be shown
   editresponse    # If the edit response button should be shown

The values of each of these variables will be set to the form field name that must be submitted in order for that action to occur. If the button should not be shown, then that hash value would not exist. A common way you can use this in your templates would be:

[% pageButtons = getPageButtons; %]
[% IF pageButtons.prevpage; %]
  <input type="submit" name="[% pageButtons.prevpage %]"
    value="[% languageString('PreviousPageButton') %]>
[% END %]
[% IF pageButtons.nextpage; %]
  <input type="submit" name="[% pageButtons.nextpage %]"
    value="[% languageString('NextPageButton') %]>
[% END %]

In your actual template, you will also want to check for the complete and editresponse buttons. It is important to use this function to determine the settings for your page buttons, as it takes into account various survey settings such as whether backwards movement is allowed, whether the survey is 100% completed, whether the respondent is in custom completion behavior and should be presented an editresponse button instead of prevpage, etc.

See also: getPreviewButtons

getPageQuestions

This function takes a page template variable as an argument, and if none is supplied, will default to survey.page (the current survey page). It returns a list of questions that belong to that page, each containing the question template variables for that question type. If isAdmin returns true, it will also show any hidden questions that were hidden while populating the response.

[% qlist = getPageQuestions(survey.page) %]

is currently equivalent to:

[% qlist = []
   FOREACH q IN survey.questions;
     NEXT IF q.sortorder <= survey.page.sortorder;
     LAST IF q.type == 'Page';
     NEXT IF q.hidden && !isAdmin;
     qlist.push(q);
   END;
%]

It is commonly used in a loop to print the questions, although you will usually want to perform other tests to omit some of the unanswered questions and content types when printing a response. To print all of the questions on the current survey page, you could do:

[% FOREACH question IN getPageQuestions(survey.page); printQuestion; END %]

getPreviewButtons

This function takes one argument, a page object, and returns a hash that will advise you on which buttons should be displayed for that page. If no page argument is supplied, it will default to survey.page. In the event that isPreview returns false, this function will return an empty hash. Otherwise, the structure may contain any of the following button types:

pageButtons.
   skiptoprev        # A button to skip to the previous page
   skiptonext        # A button to skip to the next page
   skiptosurvey      # A button to bypass access restrictions

These buttons allow a survey designer who is previewing the behavior of their survey to skip lengthy access restrictions (skip to survey) or jump to the previous and next pages without incurring any errors for required questions or invalid answers.

The values of each of these variables will be set to the form field name that must be submitted in order for that action to occur. If the button should not be shown, then that hash value would not exist. A common way you can use this in your templates would be:

[% pButtons = getPreviewButtons; %]
[% IF pButtons.skiptoprev; %]
  <input type="submit" name="[% pButtons.skiptoprev %]"
    value="[% languageString('SkipToPreviousPageButton') %]>
[% END %]
[% IF pButtons.skiptonext; %]
  <input type="submit" name="[% pButtons.skiptonext %]"
    value="[% languageString('SkipToNextPageButton') %]>
[% END %]

In your actual template, you will also want to check for the skiptosurvey button. It is important to use this function to determine the settings for your preview buttons, as it takes into account various survey settings such as whether the survey is display an access restriction page, whether this is a preview response, etc.

See also: getPageButtons

getPrevPage

This function takes a single, optional argument, which is a page template variable, and then returns the previous page in the survey response. If you do not pass in any argument, the survey.page variable, which defines the current page in the survey, will be used. If no survey.page is defined, or there is no previous page in the survey because you are on the first page, this function will return false (0).

The page returned by this function will contain all of the page template variables. This function will not distinguish between pages that are part of the response and pages found in the completion behavior, you will need to test the .incompletion variable if you need to know the difference. We recommend that for purposes of displaying the "Previous Page" button, you use the function getPageButtons.

See also: isPrevPage, getNextPage

getQuestion

This function accepts a single argument, the question id, and will return the corresponding question object. For instance:

[% q = getQuestion(123) %]

if equivalent to:

[% q = {};
   FOREACH item IN surveys.questions;
     IF item.id == 123; q = item; LAST; END;
   END; %]


If your survey logic contains any loops, you will want to use getResponses if you are trying to obtain any response-related information, as it is possible that the question will appear multiple times in the same survey. getQuestion will always return the first occurrence, whereas getResponses will pivot based on the current location in the survey response (or a location that you specify). Another alternative, if you know exactly which question you want to retrieve, is to use getQuestionBySortOrder, which is useful when printing out the items returned from getTOCPages.

getQuestionBySortOrder

This function returns the question object associated with a specific sortorder. The sortorder is the order within the survey response that the question appears. It is not predictable before the display of the survey, as the sortorder for a question can change throughout the survey due to the addition of questions via survey loops. However, some functions, such as getTOCPages, return the sortorder of an item and this function is needed to fetch the appropriate question object.

[%
toc_items = getTOCPages;
FOREACH item IN toc_items;
  toc_page = getQuestionBySortOrder(item.sortorder);
  # Print toc_page.title in various formats depending on item.status and item.linked
END;
%]

getResponseContentQuestions

Pass this function a Response Content question type and it will return a list of questions for which the responses should be shown. If you do not pass it a function, it will attempt to use the question template variable, if defined. An example of its use is:

[% FOREACH q IN getResponseContentQuestions;
   printQuestion(q, { 'printerfriendly' => 1 });
   IF !loop.last; INCLUDE spacer.tpl; END;
 END %]

That would print the responses to each question, as long as your questions are setup to recognize the printerfriendly template variable. That template variable is just something that the standard templates we have designed use, but you could call it something else if you wanted.

getResponses

This function will retrieve a list of responses for the given question. It takes one required argument, which is the question id and returns an array of all the matching responses. There are additional options that you can provide to narrow down which responses you are looking for.

Each returned item in the list will be a hash containing one or more of the following keys:

{
  'aid' => The answer id corresponding to this response
  'rid' => The row id corresponding to this response
  'cid' => The column id corresponding to this response
  'comment_tf' => Set to 1 if this is from an additional comment text field
  'selected' => Set to 1 if this response was the result of an answer or column selection
  'entered' => Set to any text that the user entered for this response

  # The following two keys available for File Upload questions only
  'filename' => The name of the file uploaded
  'filesize' => The size (in bytes) of the file uploaded

  # The following keys available for Dates and Times questions only
  # They will be available depending on the inputs for each answer type
  'year', 'month', 'day', 'hour', 'minute', 'second' => integers entered by respondent
  'ampm' => AM or PM
}

The following are a list of options you may pass to this function. If the answer or column option is provided, no returned responses for that question will have comment_tf set to true. Otherwise, if the respondent answered any additional comment text fields, they will be returned.

Option Description
answer This option allows you to specify the id of a specific answer for which to return responses. This is most commonly used in Text Field List, Ranking List, Constant Sum, File Upload and Dates and Times question types, but is valid for all question types.
row This option allows you to specify the id of a specific row for which to return responses. You can use this option when piping responses from File Upload, One Answer per Row, Many Answers per Row, Most Preferred and Super Matrix question types.
column This option allows you to specify the id of a specific column for which to return responses. You can use this option when piping responses from Super Matrix question types.
pivot In certain survey responses, providing the question ID alone is not enough to identify the response that you wish to have piped. For instance, if there are loops in the survey, it is possible for the same question to appear multiple times. The pivot option exists so that you may specify a location in the survey that will determine which response is used. The first question that matches the question id passed to pipeResponse() and appears prior to the pivot will be used. The pivot value defaults to the current question's sortorder. Keep in mind that sortorders can change throughout the survey if loops are added.

To retrieve the answer with id 567 to a text field list question with id of 1234, you would do:

[% responses = getResponses(1234, { 'answer' => 567 }); %]

The responses variable would then contain .aid and .entered parameters, due to the question type.

See also: pipeResponse

getTOCPages

This function takes an optional argument, which is the current page. If it is not found, it will default to what is available in the survey.page template variable. This function will return an array of items to be shown in the table of contents. Each item in the array will contain:

item.sortorder # the sortorder of the page (as multiple pages with same id can exist)
item.status    # set to 'current', 'done' or 'todo'
item.linked    # set to 1 if it may be linked, 0 otherwise

When displaying the table of contents, you can then do something like:

[%
toc_items = getTOCPages;
FOREACH item IN toc_items;
  toc_page = getQuestionBySortOrder(item.sortorder);
  # Print toc_page.title in various formats depending on item.status and item.linked
END;
%]

This function will not return any pages that are after a content type of Redirect, as the respondent may never reach them. If the Redirect is hidden via conditions, those pages that are after the Redirect in the survey will then be viewable in the table of contents.

isAdmin

This function returns true if the survey.config.display.access variables is equal to 'admin'. That means the survey creator (or a subaccount of that creator) is viewing the response or a preview of the question. This function is currently used by the getPageQuestions function to show hidden questions.

isComplete

This function will return 1 if all pages of the survey response have been submitted, there are no error messages for any question and all required questions have a valid answer. Otherwise, it returns 0. A response can return a 1 for isComplete before the respondent submits it, if they use the previous page button or jump around in the table of contents. This function is primarily used in conjunction with allowSubmitAny to display the submit button:

[% IF isComplete && allowSubmitAny %]
  <input type="submit" name="cmd_complete"
    value="[% page.template.button_submittext %]">
[% END %]

isNextPage

This function will return a true value when the respondent is on a page that is not the last in the survey. Keep in mind, however, that this function does not care whether the next page is in the completion behavior or the actual survey. If that will affect whether or not you wish to use the page, you may want to use getNextPage so you can test the .incompletion attribute. When presenting the respondent with the "Next Page" button, we suggest you use the function getPageButtons function to determine whether or not to display that button.

By default, this function will use the survey.page template variable, but you can pass in as the single argument any page template variable to determine whether there is a page following it.

See also: getNextPage, isPrevPage

isPageComplete

This function accepts a single optional argument, a page object, and will return a true value when the page has been submitted and contains no errors. If you omit the optional page argument, it will attempt to use the survey.page template variable.

isPreview

This function returns true when the response being displayed is a preview of the survey or publication. Previews can only be created through your account manager, but the link can then be sent to anyone to view the preview response. This function is primarily used inside of getPreviewButtons, but can be used by template designers to alter the look of the response in preview mode.

isPrevPage

This function will return a true value when the respondent is on a page that is not the first in the survey. Keep in mind, however, that this function does not care whether the previous page is in the completion behavior or the actual survey. If that will affect whether or not you wish to use the page, you may want to use getPrevPage function so you can test the .incompletion attribute. When presenting the respondent with a "Previous Page" button, we suggest you use the function getPageButtons to determine whether or not to display the back button.

By default, this function will use the survey.page template variable, but you can pass in as the single argument any page template variable to determine whether there is a page before it.

See also: getPrevPage, isNextPage

languageString

This function can be used to call a language string from the standard or custom language file in use for the response. In most cases, it takes only one argument which is the string to be looked up. For instance:

languageString('NextPageButton');

Will display the localized text that should be used for the next page. You can find a full list of language strings that are available for use. Some language strings will expect numbered variables, which can be used using a list structure:

languageString('Hours', [ 3 ]);  # outputs "hours"
languageString('Hours', [ 1 ]);  # outputs "hour"

Whether or not numbered arguments are supplied for any given language string can be found with the list of language strings. By default, a Template Toolkit evaluation will be done on the string. If you want to avoid that, pass in an empty list of arguments:

languageString('Example', []);

loopCount

This function returns the iteration of a loop within a survey response. When you use a loop in your survey design, especially numbered loops, you will commonly want to display to the respondent which iteration of the loop they are responding to. For instance, let's assume you have a numbered forward loop where you ask respondents how many jobs they have had in the last 10 years. A loop can then be created based on this response to allow them to enter information pertaining to each job. Inside of that loop, you could create a question with the title:

Please enter contact information for employer #[% loopCount %]:

When the respondent takes this survey, the tag will then be replaced with the current iteration count of the innermost loop for that page or question, so on the third time through this question, the respondent would see:

Please enter contact information for employer #3:

By default, the loopCount function will always display the count of the innermost loop. This function accepts additional parameters to help differentiate between embedded loops. If you have embedded loops and need to reference the count of an outer loop, you can use one of the following two arguments:

loopCount('-loop_id' => #);
loopCount('-trigger_qid' => #);

You can choose to use either of these two additional parameters to specify a specific loop that you want to reference with loopCount, either using the loop id (which can be found on the survey logic page by clicking on a loop) or the question id of the question that triggers the loop.

See also: loopResponse

loopResponse

This function returns the text of the response that triggered a loop in your survey. When you use a loop in your survey design, you will commonly want to display the response that triggered the specific loop the respondent is viewing so they know where they are in your survey. For instance, let's assume you want to ask in-depth questions about each product they have purchased from you. You can use a Choose Multiple Answers question to allow them to select all of the products they have purchased from you. Then, by creating a named forward loop based on the responses to this question, you could have a question inside of the loop that is named:

Please rate your experience with [% loopResponse %]:

When the respondent takes the survey and has selected 'Product A' and 'Product C', a loop of the selected questions will be created for each response, and the respondent would see the following as they proceed through the first loop:

Please rate your experience with Product A:

By default, the loopResponse function will always display the response that triggered the innermost loop. This function accepts additional parameters to help differentiate between embedded loops. If you have embedded loops and need to reference the trigger response of an outer loop, you can use one of the following two arguments:

loopResponse('-loop_id' => #);
loopResponse('-trigger_qid' => #);

You can choose to use either of these two additional parameters to specify a specific loop that you want to reference with loopResponse, either using the loop id (which can be found on the survey logic page by clicking on a loop) or the question id of the question that triggers the loop.

By default, loopResponse will return the label of the answer choice that triggered the loop in the case of multiple choice question types or the text entered by the user in the case of open ended question types. In the event that the multiple choice question type that triggered the loop contains answer choices with a text field, you can set the -return option to retrieve that value. For instance:

Please rate your experience with [% loopResponse('-return' => 'textinput') || loopResponse %]

In the event that the answer choice that triggered the loop does not have a text input field, or it was left blank, an empty string will be returned if you pass in the -return option set to 'textinput'. Therefore, you can use the pipes as shown above, which will call loopResponse without that argument if the first half evaluates false (thus returning the answer choice's label).

See also: loopCount

pipeResponse

This function allows you to use a response from a previous question in the question text, answer choice or other area of a current question. This function takes one required argument, which is the question id. There are additional options that you can provide to narrow down which response you are looking for or specify how you want the responses returned.

Option Description
answer This option allows you to specify the id of a specific answer for which to return responses. This is most commonly used in Text Field List, Ranking List, Constant Sum, File Upload and Dates and Times question types, but is valid for all question types.
row This option allows you to specify the id of a specific row for which to return responses. You can use this option when piping responses from File Upload, One Answer per Row, Many Answers per Row, Most Preferred and Super Matrix question types.
column This option allows you to specify the id of a specific column for which to return responses. You can use this option when piping responses from Super Matrix question types.
comment_tf If this option is set to 1, any text that the respondent entered into the additional comment text field will be returned. You can use this for Choose One Answer, Choose Multiple Answers, Single Answer Menu, Multiple Answer Menu, One Answer per Row, and Many Answers per Row question types.
return Depending on the question type and how you call pipeResponse, it is possible that multiple responses will be returned. How these are returned depends on this variable. By default, they will be returned as one string joined together based on the StringifyList language file string. You can also specify to have only the first response found returned ('first') or to have each response returned as part of an array ('array'). To see how this works, take an example where a user has answered a Choose Multiple Answers question type with the responses "Red", "Green" and "Blue" and that you are using the default English language file. The following would be returned depending on the value of the return variable:
return settingvalue returned
string (default)Red, Green and Blue
firstRed
array[ "Red", "Green", "Blue ]

The following examples show how these return values are related:

pipeResponse(#);

is equivalent to:

responses = pipeResponse(#, { 'return' => 'array' });
responses.size ? languageString('StringifyList', responses) : '';

while

pipeResponse(#, { 'return' => 'first' });

is equivalent to:

responses = pipeResponse(#, { 'return' => 'array' });
responses.size ? responses.0 : '';
pivot In certain survey responses, providing the question ID alone is not enough to identify the response that you wish to have piped. For instance, if there are loops in the survey, it is possible for the same question to appear multiple times. The pivot option exists so that you may specify a location in the survey that will determine which response is used. The first question that matches the question id passed to pipeResponse() and appears prior to the pivot will be used. The pivot value defaults to the current question's sortorder. Keep in mind that sortorders can change throughout the survey if loops are added.

For instance, assume you have a question that asks what the user's favorite color is. This could be a Choose One Answer or Single Text Field question type. Assume that once you have created that question in the survey, the question is assigned an ID of 765. If you wanted to use this response in a future question, you could enter:

What do you like about the color [% pipeResponse(765) %]?

Now, if the user had selected or entered 'Red' to your first question, the above question would appear as:

What do you like about the color Red?

See also: getResponses

printCompletedPercent

This function will print a number between 0 and 100 that represents the percentage of the survey that is "completed". There are several ways that a completion percentage could be calculated, but the way our default function handles it is as follows:

  • Any questions hidden due to conditions will not counted
  • Any question that is successfully answered is counted as done
  • Any question that has not yet been submitted is counted as todo
  • Any condition that currently has an error is counted as as todo

We then return the integer value of (100 * (done / (done + todo))). A side effect to note is that if you have a page full of questions that are not required, the respondent can click next without completing any questions and all of those questions will be removed from the count of todo, but none will be added to the done total.

printEmailVerificationAddress

This function will print the current email verification address entered for this survey response.

[% printEmailVerificationAddress %]

is currently identical to:

[% FOREACH address IN survey.publication.email.addresses;
  IF address.current; address.email; LAST; END;
END %]

printEmailVerificationCode

This function will print the current email verification code needed to verify the email address returned by printEmailVerificationAddress.

[% printEmailVerificationCode %]

is currently identical to:

[% FOREACH address IN survey.publication.email.addresses;
  IF address.current; address.vcode; LAST; END;
END %]

printEmailVerificationURL

This function will print a link that can be used by the respondent to verify the email address return by printEmailVerificationAddress. This function is required to be present within the email verification message body.

printFileDownloadURL

This function provides you with a URL that will enable the viewer to download a file that was attached to the survey via the File Upload question type. Pass the function a question object, an answer object (file upload field) and a file object (can be found in answer.files[]). The file object is needed because each answer object can contain multiple uploaded files. This function will return a URL that can be used to link to the specific file for download. If the file cannot be found an empty string is returned.

In the following example, we print out links to all of the attached files for the current question.

[%
FOREACH answer IN question.answers;
  FOREACH file IN uploadfield.files;
    IF file.uploaded;
      fsize = file.size | filesize;
      fname = file.name | escapeHTML;
      furl = printFileDownloadURL(question, answer, file);
      "<a href=\"${furl}\">${fname} (${fsize})</a>";
    END;
  END;
END;
%]

printFormEnd

This function will print the closing </form> tag as well as specific configuration form fields that control the behavior of the survey. It takes a single argument which controls whether the configuration form fields that must be printed are printed in regular HTML, or XHTML, in order to properly validate to a specific standard.

[% printFormEnd %]
[% printFormEnd('xhtml') %]

This single argument is passed to the printFormFields function, which will be called by printFormEnd.

printFormFields

It is usually unnecessary to call this function directly, as it will be called by printFormEnd automatically. This function takes two arguments:

printFormFields(formfields, style);

The formfields argument is a hash that contains name => value mappings of the form fields you would like to have printed. The style argument can be 'xhtml' or empty. If it is xhtml, it will print the tags with a closing ' /' in order to validate to that standard. For instance, if you did:

[% printFormFields({ 'email' => someone@example.com' }); %]

It would print:

<input type="hidden" name="email" value="someone@example.com">

If you instead changed the style to xhtml:

[% printFormFields({ 'email' => someone@example.com' }, 'xhtml'); %]

you would get:

<input type="hidden" name="email" value="someone@example.com" />

printFormStart

This function is used to print the start of the survey's <form> tag. This function will attach an onsubmit="return: false;" attribute to the form tag if displaying during a question preview. The form tag will point to survey.config.formurl in the action attribute and have a name attribute of survey.config.formname. It sets the method to POST and enctype to multipart/form-data so that file uploads can work correctly. It can also take a hash of parameters, only one of which is currently used: target.

[% printFormStart({ 'target' => '_blank' }); %]

would add a target="_blank" attribute to the form tag. You can use any name you like as the value of this parameter, but _blank is a special keyword for browsers that lets them know to put the results of the form submission in a new window or tab. Similarly,

[% printFormStart({ 'target' => '_top' }); %]

will cause the form submission to break out of any frames it make be located in and place the resulting page in the full screen of the browser. The target parameter is commonly set via template variables in the standard SurveyFactory templates.

printPageCount

This function prints the total number of pages in the survey response. This number can change throughout a response due to conditions or loops in your survey logic. It is commonly used to show the respondent where they are in the survey:

[% languageString('PageCount', [printPageNumber, printPageCount]) %]

which for a respondent on the second page of a five page survey using the default English language file would show:

Page 2 of 5

printPageNumber

This function prints the current page number in the survey response. This number can change throughout a response due to conditions or loops in your survey logic. It is commonly used to show the respondent where they are in the survey:

[% languageString('PageCount', [printPageNumber, printPageCount]) %]

which for a respondent on the second page of a five page survey using the default English language file would show:

Page 2 of 5

printTimeLimitRemaining

This function will print out the amount of time remaining if you have set a time limit for the publication. This function accepts a hash of named arguments to determine whether or not it utilizes JavaScript to perform an automatic countdown and whether or not it can store a temporary session cookie on the user's browser.

printTimeLimitRemaining; # Timer is only updated when they move to new page
printTimeLimitRemaining({ 'js' => 1, 'cookies' => 0 }); # Live countdown timer

The cookies value defaults to 1, but it is common to use a template variable that the survey designer can designate for both a javscript countdown and whether you can use cookies in the live countdown. Using a temporary cookie in the live countdown allows us to correctly update a timer (in most browsers) when the user hits the back button. The JavaScript will even jump start the timer if the user has started the time, but then clicks back to a page prior to when the timer had started. Some of this will not work correctly if you do not allow cookies, but the countdown on the current page will be shown accurately.

If you wish to remove all possibility of outdated or incorrect timers, you would need to turn off caching of survey pages so that if they used the back button, the page would actually have to be reloaded.

This function will also wrap the time limit in a <div> HTML tag with style="display: inline;" and class="sfTimer" attributes, allowing you to style the time limit in your template. Furthermore, if there is a live countdown, the div tag will also have an id attached to it so that JavaScript can fetch the div and replace the text inside every second.

printQuestion

This function accepts a question object and an optional hash of template variables that will be passed on to the question-specific template file. If no question object is passed in, the function will attempt to locate the question object in the template variable named question. This function will then call the appropriate template file for the given question type. To print out a survey page, a simple way of doing so would be:

[% FOREACH question IN getPageQuestions(survey.page); printQuestion; END %]

In some of our standard templates, you will see us call printQuestion with additional template variables. For instance, we often pass a 'printerfriendly' variable, which says we want to print is as a response:

[% printQuestion(q, { 'printerfriendly' => 1 } %]

That hash of template variables will add to the template variables available to your individual question template. If the variable name exists, it will overwrite it temporarily.

printQuestionErrorMessage

This function accepts two arguments, an error object and a question object. If you do not pass in a question object, the function will look for it in the question template variable. if you do not pass in an error object, it will look in the error template variable (you cannot pass in a question object without passing in an error object as well). To print out all of the error messages for a question, you can do:

[% FOREACH error IN question.errors; printQuestionErrorMessage; END; %]

This function will then evaluate the error.message template variable, but not until it has made some temporarily template variables available to the error.message string. For instance, if error.aid is present, it will populate the answer template with the appropriate answer object so that it may be used by your error string. The same is true of columns, rows and additional comment text fields that may be configured for the specific question an error message. This allows each error message to have the objects it needs to print a concise and accurate error message.

toJSON

This function will encode the entire survey template variable hierarchy into a JSON string notation. This can be useful if you want to simply dump the variables to be read by another display method such as Flex, but should not normally be needed for standard template design.