diff --git a/mod/choice/backup/moodle2/backup_choice_stepslib.php b/mod/choice/backup/moodle2/backup_choice_stepslib.php index f0970990cd8..aa89962013e 100644 --- a/mod/choice/backup/moodle2/backup_choice_stepslib.php +++ b/mod/choice/backup/moodle2/backup_choice_stepslib.php @@ -41,7 +41,7 @@ class backup_choice_activity_structure_step extends backup_activity_structure_st 'name', 'intro', 'introformat', 'publish', 'showresults', 'display', 'allowupdate', 'allowmultiple', 'showunanswered', 'limitanswers', 'timeopen', 'timeclose', 'timemodified', - 'completionsubmit', 'showpreview', 'includeinactive')); + 'completionsubmit', 'showpreview', 'includeinactive', 'showavailable')); $options = new backup_nested_element('options'); diff --git a/mod/choice/classes/external.php b/mod/choice/classes/external.php index cdcadd117fd..2fdb40d8567 100644 --- a/mod/choice/classes/external.php +++ b/mod/choice/classes/external.php @@ -519,6 +519,7 @@ class mod_choice_external extends external_api { $choicedetails['limitanswers'] = $choice->limitanswers; $choicedetails['showunanswered'] = $choice->showunanswered; $choicedetails['includeinactive'] = $choice->includeinactive; + $choicedetails['showavailable'] = $choice->showavailable; } if (has_capability('moodle/course:manageactivities', $context)) { @@ -571,6 +572,7 @@ class mod_choice_external extends external_api { 'showpreview' => new external_value(PARAM_BOOL, 'Show preview before timeopen', VALUE_OPTIONAL), 'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL), 'completionsubmit' => new external_value(PARAM_BOOL, 'Completion on user submission', VALUE_OPTIONAL), + 'showavailable' => new external_value(PARAM_BOOL, 'Show available spaces', VALUE_OPTIONAL), 'section' => new external_value(PARAM_INT, 'Course section id', VALUE_OPTIONAL), 'visible' => new external_value(PARAM_BOOL, 'Visible', VALUE_OPTIONAL), 'groupmode' => new external_value(PARAM_INT, 'Group mode', VALUE_OPTIONAL), diff --git a/mod/choice/db/install.xml b/mod/choice/db/install.xml index 0e3cdcb4338..d6ee73f74c6 100644 --- a/mod/choice/db/install.xml +++ b/mod/choice/db/install.xml @@ -1,5 +1,5 @@ - @@ -11,7 +11,6 @@ - @@ -24,8 +23,8 @@ - + @@ -34,7 +33,6 @@ - @@ -44,7 +42,6 @@ - @@ -54,7 +51,6 @@ - @@ -64,7 +60,6 @@ -
diff --git a/mod/choice/db/upgrade.php b/mod/choice/db/upgrade.php index b3db19a0b4f..6f8abdcbc05 100644 --- a/mod/choice/db/upgrade.php +++ b/mod/choice/db/upgrade.php @@ -22,7 +22,9 @@ defined('MOODLE_INTERNAL') || die(); function xmldb_choice_upgrade($oldversion) { - global $CFG; + global $CFG, $DB; + + $dbman = $DB->get_manager(); // Automatically generated Moodle v3.5.0 release upgrade line. // Put any upgrade step following this. @@ -39,5 +41,17 @@ function xmldb_choice_upgrade($oldversion) { // Automatically generated Moodle v3.9.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2020061600) { + // Define field showavailable to be added to choice. + $table = new xmldb_table('choice'); + $field = new xmldb_field('showavailable', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'completionsubmit'); + + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Choice savepoint reached. + upgrade_mod_savepoint(true, 2020061600, 'choice'); + } return true; } diff --git a/mod/choice/lang/en/choice.php b/mod/choice/lang/en/choice.php index a56b121a5d0..8601148d971 100644 --- a/mod/choice/lang/en/choice.php +++ b/mod/choice/lang/en/choice.php @@ -83,6 +83,7 @@ $string['indicator:socialbreadthdef'] = 'Choice social'; $string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the Choice activities during this analysis interval (Levels = No participation, Participant alone, Participant with others)'; $string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth'; $string['limit'] = 'Limit'; +$string['limita'] = 'Limit: {$a}'; $string['limitno'] = 'Limit {no}'; $string['limitanswers'] = 'Limit the number of responses allowed'; $string['modulename'] = 'Choice'; @@ -137,11 +138,14 @@ $string['removemychoice'] = 'Remove my choice'; $string['removeresponses'] = 'Remove all responses'; $string['responses'] = 'Responses'; $string['responsesresultgraphheader'] = 'Graph display'; +$string['responsesa'] = 'Responses: {$a}'; $string['responsesto'] = 'Responses to {$a}'; $string['results'] = 'Results'; $string['savemychoice'] = 'Save my choice'; $string['search:activity'] = 'Choice - activity information'; $string['selectalloption'] = 'Select all "{$a}"'; +$string['showavailable'] = 'Show available spaces'; +$string['showavailable_help'] = 'Allow students to see how many available spaces there are per option.'; $string['showpreview'] = 'Show preview'; $string['showpreview_help'] = 'Allow students to preview the available options before the choice is opened for submission.'; $string['showunanswered'] = 'Show column for unanswered'; diff --git a/mod/choice/lib.php b/mod/choice/lib.php index eca6f38e54e..4096c8b62a4 100644 --- a/mod/choice/lib.php +++ b/mod/choice/lib.php @@ -213,7 +213,9 @@ function choice_prepare_options($choice, $user, $coursemodule, $allresponses) { $cdisplay = array('options'=>array()); - $cdisplay['limitanswers'] = true; + $cdisplay['limitanswers'] = $choice->limitanswers; + $cdisplay['showavailable'] = $choice->showavailable; + $context = context_module::instance($coursemodule->id); foreach ($choice->option as $optionid => $text) { diff --git a/mod/choice/mod_form.php b/mod/choice/mod_form.php index 9fc3741c267..47a400bf8df 100644 --- a/mod/choice/mod_form.php +++ b/mod/choice/mod_form.php @@ -44,6 +44,10 @@ class mod_choice_mod_form extends moodleform_mod { $mform->addElement('selectyesno', 'limitanswers', get_string('limitanswers', 'choice')); $mform->addHelpButton('limitanswers', 'limitanswers', 'choice'); + $mform->addElement('selectyesno', 'showavailable', get_string('showavailable', 'choice')); + $mform->addHelpButton('showavailable', 'showavailable', 'choice'); + $mform->hideIf('showavailable', 'limitanswers', 'eq', 0); + $repeatarray = array(); $repeatarray[] = $mform->createElement('text', 'option', get_string('optionno', 'choice')); $repeatarray[] = $mform->createElement('text', 'limit', get_string('limitno', 'choice')); diff --git a/mod/choice/renderer.php b/mod/choice/renderer.php index cdaae586723..4f954bb0f20 100644 --- a/mod/choice/renderer.php +++ b/mod/choice/renderer.php @@ -50,7 +50,7 @@ class mod_choice_renderer extends plugin_renderer_base { $choicecount = 0; foreach ($options['options'] as $option) { $choicecount++; - $html .= html_writer::start_tag('li', array('class'=>'option')); + $html .= html_writer::start_tag('li', array('class' => 'option mr-3')); if ($multiple) { $option->attributes->name = 'answer[]'; $option->attributes->type = 'checkbox'; @@ -67,6 +67,13 @@ class mod_choice_renderer extends plugin_renderer_base { $availableoption--; } + if (!empty($options['limitanswers']) && !empty($options['showavailable'])) { + $labeltext .= html_writer::empty_tag('br'); + $labeltext .= get_string("responsesa", "choice", $option->countanswers); + $labeltext .= html_writer::empty_tag('br'); + $labeltext .= get_string("limita", "choice", $option->maxanswers); + } + $html .= html_writer::empty_tag('input', (array)$option->attributes + $disabled); $html .= html_writer::tag('label', $labeltext, array('for'=>$option->attributes->id)); $html .= html_writer::end_tag('li'); @@ -182,6 +189,11 @@ class mod_choice_renderer extends plugin_renderer_base { $headertitle = get_string('notanswered', 'choice'); } else if ($optionid > 0) { $headertitle = format_string($choices->options[$optionid]->text); + if (!empty($choices->options[$optionid]->user) && count($choices->options[$optionid]->user) > 0) { + if ((count($choices->options[$optionid]->user)) == ($choices->options[$optionid]->maxanswer)) { + $headertitle .= ' ' . get_string('full', 'choice'); + } + } } $celltext = $headertitle; @@ -209,7 +221,10 @@ class mod_choice_renderer extends plugin_renderer_base { if (!empty($options->user) && count($options->user) > 0) { $numberofuser = count($options->user); } - + if (($choices->limitanswers) && ($choices->showavailable)) { + $numberofuser .= html_writer::empty_tag('br'); + $numberofuser .= get_string("limita", "choice", $options->maxanswer); + } $celloption->text = html_writer::div($celltext, 'text-center'); $optionsnames[$optionid] = $celltext; $cellusernumber->text = html_writer::div($numberofuser, 'text-center'); diff --git a/mod/choice/tests/behat/limit_responses.feature b/mod/choice/tests/behat/limit_responses.feature index fc6d4cc232e..4804e220954 100644 --- a/mod/choice/tests/behat/limit_responses.feature +++ b/mod/choice/tests/behat/limit_responses.feature @@ -10,6 +10,7 @@ Feature: Limit choice responses | teacher1 | Teacher | 1 | teacher1@example.com | | student1 | Student | 1 | student1@example.com | | student2 | Student | 2 | student2@example.com | + | student3 | Student | 3 | student3@example.com | And the following "courses" exist: | fullname | shortname | category | | Course 1 | C1 | 0 | @@ -18,12 +19,14 @@ Feature: Limit choice responses | teacher1 | C1 | editingteacher | | student1 | C1 | student | | student2 | C1 | student | + | student3 | C1 | student | And I log in as "teacher1" And I am on "Course 1" course homepage with editing mode on And I add a "Choice" to section "1" and I fill the form with: | Choice name | Choice name | | Description | Choice Description | | Limit the number of responses allowed | 1 | + | Show available spaces | 1 | | option[0] | Option 1 | | limit[0] | 1 | | option[1] | Option 2 | @@ -38,4 +41,20 @@ Feature: Limit choice responses And I am on "Course 1" course homepage And I follow "Choice name" And I should see "Option 1 (Full)" + And I should see "Responses: 1" + And I should see "Limit: 1" And the "choice_1" "radio" should be disabled + And I log out + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I follow "Choice name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | Limit the number of responses allowed | No | + And I press "Save and return to course" + And I log out + And I log in as "student3" + And I am on "Course 1" course homepage + And I follow "Choice name" + Then I should not see "Limit: 1" + And the "choice_1" "radio" should be enabled diff --git a/mod/choice/tests/behat/multiple_options.feature b/mod/choice/tests/behat/multiple_options.feature index 0b6e15ed0b1..2efd12414bc 100644 --- a/mod/choice/tests/behat/multiple_options.feature +++ b/mod/choice/tests/behat/multiple_options.feature @@ -52,6 +52,7 @@ Feature: Multiple option choice response | Description | Choice Description | | Allow more than one choice to be selected | Yes | | Limit the number of responses allowed | 1 | + | Show available spaces | 1 | | option[0] | Option 1 | | limit[0] | 1 | | option[1] | Option 2 | @@ -74,3 +75,21 @@ Feature: Multiple option choice response And the "#choice_1" "css_element" should be disabled And the "#choice_2" "css_element" should be disabled And the "#choice_3" "css_element" should be enabled + And I log out + And I log in as "teacher1" + And I am on "Course 1" course homepage + And I follow "Choice name" + And I follow "View 1 responses" + Then I should see "Option 1 (Full)" + And I should see "Limit: 1" + And I am on "Course 1" course homepage with editing mode on + And I follow "Choice name" + And I navigate to "Edit settings" in current page administration + And I set the following fields to these values: + | Limit the number of responses allowed | No | + And I press "Save and return to course" + And I am on "Course 1" course homepage + And I follow "Choice name" + And I follow "View 1 responses" + Then I should not see "Limit: 1" + And I log out diff --git a/mod/choice/version.php b/mod/choice/version.php index 5a18e6ba06b..5963fc837c3 100644 --- a/mod/choice/version.php +++ b/mod/choice/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2020061500; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2020061600; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2020060900; // Requires this Moodle version $plugin->component = 'mod_choice'; // Full name of the plugin (used for diagnostics) $plugin->cron = 0; diff --git a/theme/boost/scss/moodle/modules.scss b/theme/boost/scss/moodle/modules.scss index 62f78626b33..57c1d7ca248 100644 --- a/theme/boost/scss/moodle/modules.scss +++ b/theme/boost/scss/moodle/modules.scss @@ -17,6 +17,12 @@ select { } } +.path-mod-choice { + .choices .option label { + vertical-align: top; + } +} + .path-mod-feedback .feedback_form .col-form-label { display: block !important; /* stylelint-disable-line declaration-no-important */ } diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 93f02cb4b81..fba0b2ccc9a 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -16591,6 +16591,9 @@ select { .path-mod-choice .horizontal .choices .option { display: inline-block; } +.path-mod-choice .choices .option label { + vertical-align: top; } + .path-mod-feedback .feedback_form .col-form-label { display: block !important; /* stylelint-disable-line declaration-no-important */ } diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 02d840a419a..62726927ed9 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -16820,6 +16820,9 @@ select { .path-mod-choice .horizontal .choices .option { display: inline-block; } +.path-mod-choice .choices .option label { + vertical-align: top; } + .path-mod-feedback .feedback_form .col-form-label { display: block !important; /* stylelint-disable-line declaration-no-important */ }