Question Types
You can implement custom question types using the CoreQuestionDelegate:
db/mobile.php
$addons = [
"qtype_YOURQTYPENAME" => [
"handlers" => [
'YOURQTYPENAME' => [
'displaydata' => [
'title' => 'YOURQTYPENAME question',
'icon' => '/question/type/YOURQTYPENAME/pix/icon.gif',
'class' => '',
],
'delegate' => 'CoreQuestionDelegate',
'method' => 'mobile_get_YOURQTYPENAME',
'offlinefunctions' => [
'mobile_get_YOURQTYPENAME' => [],
],
'styles' => [
'url' => '/question/type/YOURQTYPENAME/mobile/styles_app.css',
'version' => '1.00',
],
],
],
'lang' => [
['pluginname', 'qtype_YOURQTYPENAME'],
],
],
];
classes/output/mobile.php
class mobile {
public static function mobile_get_YOURQTYPENAME() {
global $OUTPUT, $CFG;
$html = $OUTPUT->render_from_template('qtype_YOURQTYPENAME/mobile', []);
return [
'templates' => [
[
'id' => 'main',
'html' => $html,
],
],
'javascript' => file_get_contents($CFG->dirroot . '/question/type/YOURQTYPENAME/mobile/mobile.js'),
];
}
}
templates/mobile.mustache
<section class="list qtype-YOURQTYPENAME-container qtype-YOURQTYPENAME" ion-list *ngIf="question.text || question.text === ''">
<ion-item class="addon-qtype-YOURQTYPENAME-container qtext">
<ion-label>
<core-format-text
[component]="component"
[componentId]="componentId"
[text]="question.text"
(afterRender)="questionRendered()">
</core-format-text>
</ion-label>
</ion-item>
</section>
mobile/mobile.js
const that = this;
const result = {
componentInit() {
if (!this.question) {
console.warn('Aborting because of no question received.');
return that.CoreQuestionHelperProvider.showComponentError(that.onAbort);
}
const div = document.createElement('div');
div.innerHTML = this.question.html;
// Get question questiontext.
const questiontext = div.querySelector('.qtext');
// Replace Moodle's correct/incorrect and feedback classes with our own.
// Only do this if you want to use the standard classes.
this.CoreQuestionHelperProvider.replaceCorrectnessClasses(div);
this.CoreQuestionHelperProvider.replaceFeedbackClasses(div);
// Treat the correct/incorrect icons.
this.CoreQuestionHelperProvider.treatCorrectnessIcons(div);
if (div.querySelector('.readonly') !== null) {
this.question.readonly = true;
}
if (div.querySelector('.feedback') !== null) {
this.question.feedback = div.querySelector('.feedback');
this.question.feedbackHTML = true;
}
this.question.text = this.CoreDomUtilsProvider.getContentsOfElement(div, '.qtext');
if (typeof this.question.text === 'undefined') {
this.logger.warn('Aborting because of an error parsing question.', this.question.name);
return this.CoreQuestionHelperProvider.showComponentError(this.onAbort);
}
// Called by the reference in html to (afterRender)="questionRendered()".
this.questionRendered = function questionRendered() {
// Do stuff that needs the question rendered before it can run.
};
// Wait for the DOM to be rendered.
setTimeout(() => {
// Put stuff here that will be pulled from the rendered question.
});
return true;
}
};
result;