Question Widgets! Everybody loves Question Widgets! Over the next couple of weeks I’ll be writing a series of posts to help you get up and building Question Widgets.
In this post, we’ll look at the basics of how to create a Question Widget, and how to get it to answer correctly, incorrectly, or as incomplete. After you know how to do these things, everything else is making sure the widget works smoothly with the Captivate Movie.
Let’s meet the beast.
What is a Question Widget?
A Question Widget is a widget that Captivate treats as a Question Type. Captivate has native Question Types such as: True or False, Multiple Choice, Fill in the Blank, and many many more. However, if you wanted to create a Crossword Puzzle question or a Drag and Drop question, then Captivate doesn’t have those Question Types. Question Widgets mean you can create your own Crossword Puzzle widget and it would work just like it was a native Captivate Question Type (provided you put it together right).
The good news is, if you already know how to build a Static Widget, then you have most of the knowledge needed to build a Question Widget. All the properties and methods that you use in Static Widgets are used in Question Widgets as well. Question Widgets also have additional properties and methods that are used in unique Question Widgety situations. You can see a list of them in the documentation right now (Select Question Widget under All Classes).
An important difference between Question Widgets and other widget types is this: When you insert a Static or Interactive widget into a Captivate Movie, they are added to the current slide as an element. This means you can change their timing and depth on the timeline. However, when you insert a Question Widget, a whole new slide is created for it. In fact, the Question Widget is considered as being part of that slide. So there are no timing or depth controls for the widget.
How do I make a Question Widget?
It’s as easy as making a Static Widget. If you don’t know how to do that, then read this post on how to create a Static Widget in Flash. You can change the Static Widget in that post to a Question Widget by swaping the StaticWidget class with the QuestionWidget class so that the widget looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 | package { import widgetfactory.QuestionWidget; public class MyQuestionWidget extends QuestionWidget { public function MyQuestionWidget() { } } } |
How do I score a Question Widget?
In the end, a Question Widget comes down to one thing: How did the audience answer the question?
Did they get it right? Did they get it wrong? Or did they flat out not answer it?
When the question is submitted (either by the audience clicking the question’s submit button, or the widget submitting itself with the triggerSubmitProcess() method) Captivate will demand from the widget how the audience answered its question. The answer that the widget gives Captivate is handled by two properties: isCompleteAnswer, and isCorrectAnswer.
isCompleteAnswer tells Captivate IF the audience has answered the question. If isCompleteAnswer is set to false, then Captivate will display the ‘You must answer the question before continuing’ caption, and give the audience another chance to answer the question. If isCompleteAnswer is set to true, then Captivate will recoginise the question as having an answer, and move on to the next step to try and establish what that answer is.
isCorrectAnswer tells Captivate HOW the audience has answered the question. If isCorrectAnswer is set to true, then the question will be picked up as being correct. If it’s set to false, then the question will be marked as incorrect.
By default, isCompleteAnswer is set to true, and isCorrectAnswer is set to false.
Let’s take a look at a really basic Question Widget.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package { import widgetfactory.QuestionWidget; public class MyQuestionWidget extends QuestionWidget { public function MyQuestionWidget() { isCompleteAnswer = true; isCorrectAnswer = true; } } } |
This question will always be picked up as being correct. Try playing around with the values of isCompleteAnswer and isCorrectAnswer in your own time. See how the different combinations change the result of the Question.
Of course, the answer of the above widget is set in stone as soon as it is published. In a working Question Widget, the answer would be uncertain until the audience clicks the submit button. So ideally what should happen is after the question is submitted, the widget checks itself to see if it was answered correct, incorrect, or incomplete. But how do we do that? How do we get that checking code to run when the audience submits the question?
Well, lucky for us, QuestionWidget has a unique Template Method called submit. Here’s how you override it.
1 2 3 4 | override protected function submit():void { } |
Any code that you put in the submit method will be executed between when the user clicks the submit button and Captivate requests the results of the isCompleteAnswer and isCorrectAnswer properties. That makes it the perfect time to evaluate the answer of your question.
So now that we know a little about Question Widgets, let’s build a working one. The Question Widget below creates two toggling buttons, one called ‘correctAnswerButton’ and one called ‘incorrectAnswerButton’. When the question is submitted, it will be received as correct if the correctAnswerButton is selected, or incorrect if the incorrectAnswerButton is selected. Alternatively, if neither button is selected, then the question will be marked incomplete.
Here’s the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | package { import fl.controls.Button; import flash.events.MouseEvent; import widgetfactory.QuestionWidget; public class SimpleButtonQuestion extends QuestionWidget { private var correctAnswerButton:Button; private var incorrectAnswerButton:Button; override protected function enterRuntime():void { // When this button is selected, the question will be recieved as correct correctAnswerButton = new Button(); addChild(correctAnswerButton); // Change the text on the button correctAnswerButton.label = "Answer Correct"; // Make into a toggle button correctAnswerButton.toggle = true; // Put in the top left corner (where it is by default anyway) correctAnswerButton.x = 0; correctAnswerButton.y = 0; // Call the onButtonClick function when this button is clicked correctAnswerButton.addEventListener(MouseEvent.CLICK, onButtonClick); // When this button is selected, the question will be recieved as incorrect incorrectAnswerButton = new Button(); addChild(incorrectAnswerButton); // Change the button's text incorrectAnswerButton.label = "Answer Incorrect"; // Make it toggle incorrectAnswerButton.toggle = true; // Shift it to be to the right of the correctAnswerButton incorrectAnswerButton.x = correctAnswerButton.width + 10; incorrectAnswerButton.y = 0; // Call the onButtonClick function when this button is clicked also incorrectAnswerButton.addEventListener(MouseEvent.CLICK, onButtonClick); // This stops the buttons being created again when the movie is rewound dispatchRuntimeAfterRewind = false; } private function onButtonClick(e:MouseEvent):void { // If the user has just clicked on the correctAnswerButton... if (e.target == correctAnswerButton) { // ...Then we want to toggle the incorrectAnswerButton off incorrectAnswerButton.selected = false; // If the user hasn't click the correctAnswerButton... // ...then they must have clicked the incorrectAnswerButton } else { // In which case we want to toggle the correctAnswerButton off. correctAnswerButton.selected = false; } } // The user has just click the submit button, // Captivate is just about to check the isCompleteAnswer // and isCorrectAnswer properties override protected function submit():void { // Unless otherwise stated, the question is complete. isCompleteAnswer = true; // If the correctAnswerButton is selected... if (correctAnswerButton.selected == true) { // ...then the question is answered correctly isCorrectAnswer = true; // if the incorrectAnswerButton is selected... } else if (incorrectAnswerButton.selected == true) { // ...then the question is answered incorrectly isCorrectAnswer = false; // If no buttons are selected... } else { // ...then the question hasn't been answered at all isCompleteAnswer = false; } } } } |
Click here to download the widget!
This isn’t a flawless widget. Notice how after you’ve answered it, you can still interact with the buttons (although that does not change the result of the question). In the next post of this series, we’ll look at how to enable and disable the questions in synch with the status of the Captivate Movie.





Pingback: Tweets that mention Question Widgets – Part 1 | The Widget King -- Topsy.com
Tristan,
Great post and very clear explanation. I always enjoy reading your articles.
Jim Leichliter
Pingback: Flash-Factor » Blog Archive » Ideas for Question Wigets
hi Tristan,
Thank for your graet site !
I’m new with the whole widget issue, and learning fast from your blog
I want to create a question widget according to this post,
but I have to be sure that the question at the end will be SCORM compaliacned,
so I could track the answers in a LMS.
I didn’t find any reference to this subject in your post.
Is the question going to be reportable ?
Thank’s in advance !
yael.
Hi Yael,
The SCORM compliance for all questions (including Question Widgets) is handled inside Captivate. So you don’t need to worry about programming that into your Question Widget.
Isn’t that lovely?
Great! Thanks for the reply!
In that case I’ll start reading & learning about it right away !