Skip to content

Commit

Permalink
MDL-71305 core_question: Use toggle button for flag question element
Browse files Browse the repository at this point in the history
  • Loading branch information
rezaies committed Mar 8, 2022
1 parent e0dcb76 commit 8c1587e
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 46 deletions.
12 changes: 4 additions & 8 deletions question/engine/lib.php
Expand Up @@ -747,26 +747,22 @@ public static function initialise_js() {
'requires' => array('base', 'dom', 'event-delegate', 'io-base'),
);
$actionurl = $CFG->wwwroot . '/question/toggleflag.php';
$flagtext = array(
0 => get_string('clickflag', 'question'),
1 => get_string('clickunflag', 'question')
);
$flagattributes = array(
0 => array(
'src' => $OUTPUT->image_url('i/unflagged') . '',
'title' => get_string('clicktoflag', 'question'),
'alt' => get_string('notflagged', 'question'),
// 'text' => get_string('clickflag', 'question'),
'alt' => get_string('flagged', 'question'), // Label on toggle should not change.
'text' => get_string('clickflag', 'question'),
),
1 => array(
'src' => $OUTPUT->image_url('i/flagged') . '',
'title' => get_string('clicktounflag', 'question'),
'alt' => get_string('flagged', 'question'),
// 'text' => get_string('clickunflag', 'question'),
'text' => get_string('clickunflag', 'question'),
),
);
$PAGE->requires->js_init_call('M.core_question_flags.init',
array($actionurl, $flagattributes, $flagtext), false, $module);
array($actionurl, $flagattributes), false, $module);
$done = true;
}
}
Expand Down
27 changes: 12 additions & 15 deletions question/engine/renderer.php
Expand Up @@ -263,8 +263,6 @@ public function standard_mark_out_of_max(question_attempt $qa, question_display_
* @param int $flagsoption the option that says whether flags should be displayed.
*/
protected function question_flag(question_attempt $qa, $flagsoption) {
global $CFG;

$divattributes = array('class' => 'questionflag');

switch ($flagsoption) {
Expand All @@ -290,17 +288,14 @@ protected function question_flag(question_attempt $qa, $flagsoption) {

$flagcontent = html_writer::empty_tag('input',
array('type' => 'hidden', 'name' => $id, 'value' => 0)) .
html_writer::empty_tag('input', $checkboxattributes) .
html_writer::empty_tag('input',
array('type' => 'hidden', 'value' => $postdata, 'class' => 'questionflagpostdata')) .
html_writer::empty_tag('input', $checkboxattributes) .
html_writer::tag('label', $this->get_flag_html($qa->is_flagged(), $id . 'img'),
array('id' => $id . 'label', 'for' => $id . 'checkbox')) . "\n";

$divattributes = array(
'class' => 'questionflag editable',
'aria-atomic' => 'true',
'aria-relevant' => 'text',
'aria-live' => 'assertive',
);

break;
Expand All @@ -322,18 +317,16 @@ protected function question_flag(question_attempt $qa, $flagsoption) {
protected function get_flag_html($flagged, $id = '') {
if ($flagged) {
$icon = 'i/flagged';
$alt = get_string('flagged', 'question');
$label = get_string('clickunflag', 'question');
} else {
$icon = 'i/unflagged';
$alt = get_string('notflagged', 'question');
$label = get_string('clickflag', 'question');
}
$attributes = array(
$attributes = [
'src' => $this->image_url($icon),
'alt' => $alt,
'alt' => '',
'class' => 'questionflagimage',
);
];
if ($id) {
$attributes['id'] = $id;
}
Expand All @@ -343,10 +336,14 @@ protected function get_flag_html($flagged, $id = '') {
return $img;
}

protected function edit_question_link(question_attempt $qa,
question_display_options $options) {
global $CFG;

/**
* Generate the display of the edit question link.
*
* @param question_attempt $qa The question attempt to display.
* @param question_display_options $options controls what should and should not be displayed.
* @return string
*/
protected function edit_question_link(question_attempt $qa, question_display_options $options) {
if (empty($options->editquestionparams)) {
return '';
}
Expand Down
73 changes: 50 additions & 23 deletions question/flags.js
Expand Up @@ -28,13 +28,11 @@
M.core_question_flags = {
flagattributes: null,
actionurl: null,
flagtext: null,
listeners: [],

init: function(Y, actionurl, flagattributes, flagtext) {
init: function(Y, actionurl, flagattributes) {
M.core_question_flags.flagattributes = flagattributes;
M.core_question_flags.actionurl = actionurl;
M.core_question_flags.flagtext = flagtext;

Y.all('div.questionflag').each(function(flagdiv, i) {
var checkbox = flagdiv.one('input[type=checkbox]');
Expand All @@ -47,38 +45,67 @@ M.core_question_flags = {
input.set('name', checkbox.get('name'));
input.set('value', checkbox.get('checked') ? 1 : 0);

// Create an image input to replace the img tag.
var image = Y.Node.create('<input type="image" class="questionflagimage" />');
var flagtext = Y.Node.create('<span class="questionflagtext">.</span>');
M.core_question_flags.update_flag(input, image, flagtext);
var ariaPressed = checkbox.get('checked') ? 'true' : 'false';
var toggle = Y.Node.create('<a ' +
'tabindex="0" ' +
'class="aabtn" ' +
'role="button" ' +
'aria-pressed="' + ariaPressed + '">' +
'.' +
'</a>');
M.core_question_flags.update_flag(input, toggle);

checkbox.remove();
flagdiv.one('label').remove();
flagdiv.append(input);
flagdiv.append(image);
flagdiv.append(flagtext);
flagdiv.append(toggle);
});

Y.delegate('click', function(e) {
var input = this.one('input.questionflagvalue');
input.set('value', 1 - input.get('value'));
M.core_question_flags.update_flag(input, this.one('input.questionflagimage'),
this.one('span.questionflagtext'));
var postdata = this.one('input.questionflagpostdata').get('value') +
input.get('value');

e.halt();
Y.io(M.core_question_flags.actionurl , {method: 'POST', 'data': postdata});
M.core_question_flags.fire_listeners(postdata);
M.core_question_flags.process(this);
}, document.body, 'div.questionflag');
Y.delegate('key', function(e) {
e.halt();
if (e.keyCode == 13) {
M.core_question_flags.process(this);
}
}, document.body, 'down:enter, space', 'div.questionflag');
Y.delegate('key', function(e) {
e.halt();
M.core_question_flags.process(this);
}, document.body, 'up:space', 'div.questionflag');
},

update_flag: function(input, image, flagtext) {
update_flag: function(input, toggle) {
var value = input.get('value');
image.setAttrs(M.core_question_flags.flagattributes[value]);
flagtext.replaceChild(flagtext.create(M.core_question_flags.flagtext[value]),
flagtext.get('firstChild'));
flagtext.set('title', M.core_question_flags.flagattributes[value].title);
toggle.setContent(
'<img class="questionflagimage" src="' + M.core_question_flags.flagattributes[value].src + '" alt="" />' +
M.core_question_flags.flagattributes[value].text
);
toggle.set('aria-pressed', parseInt(value) ? 'true' : 'false');
toggle.set('aria-label', M.core_question_flags.flagattributes[value].alt);
if (M.core_question_flags.flagattributes[value].title != M.core_question_flags.flagattributes[value].text) {
toggle.set('title', M.core_question_flags.flagattributes[value].title);
} else {
toggle.removeAttribute('title');
}
},

/**
* Process the change of flag status.
*
* @param {Y.Node} target The root element
*/
process: function(target) {
var input = target.one('input.questionflagvalue');
input.set('value', 1 - input.get('value'));
M.core_question_flags.update_flag(input, target.one('[aria-pressed]'));
var postdata = target.one('input.questionflagpostdata').get('value') +
input.get('value');

Y.io(M.core_question_flags.actionurl, {method: 'POST', 'data': postdata});
M.core_question_flags.fire_listeners(postdata);
},

add_listener: function(listener) {
Expand Down

0 comments on commit 8c1587e

Please sign in to comment.