Custom Render ― Question Elements
Sections in this topic:
- Handle event ― onRenderQuestion
- Use event parameter options ― AdornerOptions object
- How to customize question titles
- How to customize question choices
API to use:
Event:
SurveyPDF.onRenderQuestion
Event parameter's popular options:
options.question
options.bricks
PdfBrick.unfold()
PdfBrick.textColor
Handle event ― onRenderQuestion
When exporting a survey to a PDF file, you can handle the SurveyPDF object's onRenderQuestion event to access and customize structural elements of any rendered survey question.
The event signature is as follows.
onRenderQuestion: EventAsync<(survey: SurveyPDF, options: AdornersOptions) => any, any>
Two parameters are passed to event handlers:
survey
― The event sender. A SurveyPDF object instance,options
― An AdornerOptions object that contains the processed question's render information.
View the event sources: declaration, invocation.
See also:
SurveyPDF.onRenderPage
(docs, sources)
SurveyPDF.onRenderPanel
(docs, sources)
Use event parameter options ― AdornerOptions object
An AdornerOptions
object instance is passed to onRenderQuestion event handlers as the options
parameter. This parameter exposes the following set of properties to help you access and customize the rendered question's composite elements.
question
question: IQuestion;
Identifies the rendered question.bricks
bricks: IPdfBrick[];
An array of PdfBrick objects representing the question's render structure.point
point: IPoint;
controller
controller: DocController;
repository
repository: FlatRepository;
module
module: any;
Bricks
Within the PDF file content, question elements are represented by bricks (PdfBrick instances). Bricks are the most fundamental elements that are used to construct a document.
A brick is a simple element with a specified size, contents and location that is used to display any textual and/or graphic information on a document page. A PdfBrick object exposes the following API.
Position and size options:
xLeft
xRight
yTop
yBot
width
height
isPageBreak
Appearance options:
textColor
formBorderColor
fontSize
Methods:
unfold()
render()
Note:
If you just need to modify a brick's appearance, the simplest way is to use any of the appearance options, such as the text color (textColor
) or font size (fontSize
).
When working with bricks, the main challenges facing you as a developer are as follows:
- understand the structure of bricks that compose a survey question being currently rendered into a PDF file,
- access certain bricks that relate to the required question structural element (such as a question title, question description or an individual choice).
Our documentation does not currently provide detail information about the precise brick structure used to render survey questions of different types. We consider the rendering process to be an internal logic which might change in future releases.
However, we have an open suggestion issue - #49 - which you can track and add to if you feel a need for such a description and you can provide illustrative use cases of question element customization required.
It appears that the fastest way to understand how a question is rendered within a PDF file is to insert the debugger
statement into an onRenderQuestion
event handler and to investigate the rendered question's structure in a browser's DevTools Console.
surveyPDF
.onRenderQuestion
.add(function (survey, options) {
debugger;
// Your customization logic here...
/*
const plainBricks = options
.bricks[0]
.unfold();
*/
});
How to customize question titles
The code below shows how to handle the onRenderQuestion
event to change question title colors (to highlight correct and incorrect answers) for questions of the Radiogroup type.
To modify the text color of title bricks, a brick's textColor property is used.
surveyPDF
.onRenderQuestion
.add(function (survey, options) {
//debugger // <-- Discover the brick structure in DevTools
const plainBricks = options.bricks[0].unfold();
if (options.question.isAnswerCorrect()) {
// Change the title color to green for correct answers:
plainBricks[0].textColor = "#00ff00"; // A brick for number in a question title.
plainBricks[1].textColor = "#00ff00"; // A brick for text in a question title.
} else {
// Change the title color to red for incorrect answers:
plainBricks[0].textColor = "#ff0000"; // A brick for number in a question title.
plainBricks[1].textColor = "#ff0000"; // A brick for text in a question title.
}
return new Promise(function (resolve) {
resolve();
});
});
Links to the related API used in the code:
onRenderQuestion
― sources, docs
options
― sources
options.bricks
― sources
options.question
― sources
options.question.isAnswerCorrect()
― sources
PdfBrick.textColor
― sources
You can see the complete sample code and test it in action in the Plunker example:
SurveyPDF ― How to highlight incorrect answers in a PDF file
There is more info about the onRenderQuestion
event in our Adorners example's documentation:
https://surveyjs.io/Examples/Pdf-Export?id=survey-pdf-adorners#content-docs
How to customize question choices
The code below shows how to handle the onRenderQuestion
event to change the color of choices (to highlight correct choices) for questions of the Radiogroup type.
To modify the text color of choice bricks, a brick's textColor property is used.
This example is based on the previous example's code and extends it with the functionality of finding and highlighting the correct choice in the rendered question.
surveyPDF
.onRenderQuestion
.add(function (survey, options) {
const plainBricks = options.bricks[0].unfold();
// #region Titles
// Change the title color for correct/incorrect answers:
if (options.question.isAnswerCorrect()) {
plainBricks[0].textColor = "#00ff00";
plainBricks[1].textColor = "#00ff00";
} else {
plainBricks[0].textColor = "#ff0000";
plainBricks[1].textColor = "#ff0000";
}
// #endregion
// Find a correct choice and access its text brick:
const correctChoice = Survey.ItemValue.getItemByValue(options.question.choices, options.question.correctAnswer);
const correctChoiceIndex = options.question.choices.indexOf(correctChoice);
const correctChoiceRootBrick = options.bricks[correctChoiceIndex];
//debugger // <-- Discover the brick structure in DevTools
const correctChoiceTextBrick = correctChoiceRootBrick.bricks[1].bricks[0];
if (correctChoiceIndex === 0) {
correctChoiceTextBrick = correctChoiceRootBrick.bricks[1].bricks[1].bricks[0];
}
// Change the correct choice's text color to green:
correctChoiceTextBrick.textColor = "#00ff00";
return new Promise(function (resolve) {
resolve();
});
});
Links to the related API used in the code:
onRenderQuestion
― sources, docs
options
― sources
options.bricks
― sources
options.question
― sources
options.question.isAnswerCorrect()
― sources
Survey.ItemValue
― sources
Survey.ItemValue.getItemByValue()
― sources
options.question.choices
― sources, docs
options.question.choices.indexOf()
― docs
PdfBrick.textColor
― sources
You can see the complete sample code and test it in action in the Plunker example:
SurveyPDF - How to highlight correct/incorrect answers together with correct choices in a PDF file
There is more info about the onRenderQuestion
event in our Adorners example's documentation:
https://surveyjs.io/Examples/Pdf-Export?id=survey-pdf-adorners#content-docs