diff --git a/amd/build/studentid.min.js b/amd/build/studentid.min.js
new file mode 100644
index 00000000..2f95f499
--- /dev/null
+++ b/amd/build/studentid.min.js
@@ -0,0 +1,10 @@
+/**
+ * Potential user selector module.
+ *
+ * @module mod_scheduler/studentid
+ * @copyright 2022 University of Glasgow
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define("mod_scheduler/studentid",["jquery","core/ajax","core/templates"],(function($,Ajax,Templates){return{processResults:function(selector,results){var users=[];return $.each(results,(function(index,user){users.push({value:user.id,label:user._label})})),users},transport:function(selector,query,success,failure){let scheduler=$(selector).attr("scheduler")||null,groupids=$(selector).attr("groupids")||null;Ajax.call([{methodname:"mod_scheduler_studentid",args:{query:query,scheduler:scheduler,groupids:groupids}}])[0].then((function(results){var promises=[],i=0;return $.each(results,(function(index,user){promises.push(Templates.render("mod_scheduler/studentid",user))})),$.when.apply($.when,promises).then((function(){var args=arguments;$.each(results,(function(index,user){user._label=args[i],i++})),success(results)}))})).fail(failure)}}}));
+
+//# sourceMappingURL=studentid.min.js.map
\ No newline at end of file
diff --git a/amd/build/studentid.min.js.map b/amd/build/studentid.min.js.map
new file mode 100644
index 00000000..515c5dde
--- /dev/null
+++ b/amd/build/studentid.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"studentid.min.js","sources":["../src/studentid.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Potential user selector module.\n *\n * @module mod_scheduler/studentid\n * @copyright 2022 University of Glasgow\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {\n\n return /** @alias module:mod_scheduler/studentid */ {\n\n processResults: function(selector, results) {\n var users = [];\n $.each(results, function(index, user) {\n users.push({\n value: user.id,\n label: user._label\n });\n });\n return users;\n },\n\n transport: function(selector, query, success, failure) {\n var promise;\n\n let scheduler = $(selector).attr('scheduler') || null;\n let groupids = $(selector).attr('groupids') || null;\n promise = Ajax.call([{\n methodname: 'mod_scheduler_studentid',\n args: {\n query: query,\n scheduler: scheduler,\n groupids: groupids\n }\n }]);\n\n promise[0].then(function(results) {\n var promises = [],\n i = 0;\n\n // Render the label.\n $.each(results, function(index, user) {\n promises.push(Templates.render('mod_scheduler/studentid', user));\n });\n\n // Apply the label to the results.\n return $.when.apply($.when, promises).then(function() {\n var args = arguments;\n $.each(results, function(index, user) {\n user._label = args[i];\n i++;\n });\n success(results);\n return;\n });\n\n }).fail(failure);\n }\n\n };\n\n});"],"names":["define","$","Ajax","Templates","processResults","selector","results","users","each","index","user","push","value","id","label","_label","transport","query","success","failure","scheduler","attr","groupids","call","methodname","args","then","promises","i","render","when","apply","arguments","fail"],"mappings":";;;;;;;AAuBAA,iCAAO,CAAC,SAAU,YAAa,mBAAmB,SAASC,EAAGC,KAAMC,iBAEZ,CAEhDC,eAAgB,SAASC,SAAUC,aAC3BC,MAAQ,UACZN,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BH,MAAMI,KAAK,CACPC,MAAOF,KAAKG,GACZC,MAAOJ,KAAKK,YAGbR,OAGXS,UAAW,SAASX,SAAUY,MAAOC,QAASC,aAGtCC,UAAYnB,EAAEI,UAAUgB,KAAK,cAAgB,KAC7CC,SAAWrB,EAAEI,UAAUgB,KAAK,aAAe,KACrCnB,KAAKqB,KAAK,CAAC,CACjBC,WAAY,0BACZC,KAAM,CACFR,MAAOA,MACPG,UAAWA,UACXE,SAAUA,aAIV,GAAGI,MAAK,SAASpB,aACjBqB,SAAW,GACXC,EAAI,SAGR3B,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BiB,SAAShB,KAAKR,UAAU0B,OAAO,0BAA2BnB,UAIvDT,EAAE6B,KAAKC,MAAM9B,EAAE6B,KAAMH,UAAUD,MAAK,eACnCD,KAAOO,UACX/B,EAAEO,KAAKF,SAAS,SAASG,MAAOC,MAC5BA,KAAKK,OAASU,KAAKG,GACnBA,OAEJV,QAAQZ,eAIb2B,KAAKd"}
\ No newline at end of file
diff --git a/amd/src/studentid.js b/amd/src/studentid.js
new file mode 100644
index 00000000..76d2dc27
--- /dev/null
+++ b/amd/src/studentid.js
@@ -0,0 +1,78 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see .
+
+/**
+ * Potential user selector module.
+ *
+ * @module mod_scheduler/studentid
+ * @copyright 2022 University of Glasgow
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {
+
+ return /** @alias module:mod_scheduler/studentid */ {
+
+ processResults: function(selector, results) {
+ var users = [];
+ $.each(results, function(index, user) {
+ users.push({
+ value: user.id,
+ label: user._label
+ });
+ });
+ return users;
+ },
+
+ transport: function(selector, query, success, failure) {
+ var promise;
+
+ let scheduler = $(selector).attr('scheduler') || null;
+ let groupids = $(selector).attr('groupids') || null;
+ promise = Ajax.call([{
+ methodname: 'mod_scheduler_studentid',
+ args: {
+ query: query,
+ scheduler: scheduler,
+ groupids: groupids
+ }
+ }]);
+
+ promise[0].then(function(results) {
+ var promises = [],
+ i = 0;
+
+ // Render the label.
+ $.each(results, function(index, user) {
+ promises.push(Templates.render('mod_scheduler/studentid', user));
+ });
+
+ // Apply the label to the results.
+ return $.when.apply($.when, promises).then(function() {
+ var args = arguments;
+ $.each(results, function(index, user) {
+ user._label = args[i];
+ i++;
+ });
+ success(results);
+ return;
+ });
+
+ }).fail(failure);
+ }
+
+ };
+
+});
\ No newline at end of file
diff --git a/classes/external.php b/classes/external.php
new file mode 100644
index 00000000..3c8ab315
--- /dev/null
+++ b/classes/external.php
@@ -0,0 +1,118 @@
+.
+
+/**
+ * This is the external API for this component.
+ *
+ * @package mod_scheduler
+ * @copyright 2022 University of Glasgow
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace mod_scheduler;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once("$CFG->libdir/externallib.php");
+
+use external_api;
+use external_function_parameters;
+use external_value;
+use external_single_structure;
+use external_multiple_structure;
+
+use \mod_scheduler\model\scheduler;
+
+/**
+ * This is the external API for this component.
+ *
+ * @copyright 2022 University of Glasgow
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class external extends external_api {
+
+ /**
+ * studentid parameters
+ *
+ * @return external_function_parameters
+ */
+ public static function studentid_parameters() {
+ return new external_function_parameters([
+ 'query' => new external_value(PARAM_TEXT, 'The search query', VALUE_REQUIRED),
+ 'scheduler' => new external_value(PARAM_INT, 'The scheduler id', VALUE_REQUIRED),
+ 'groupids' => new external_value(PARAM_INT, 'The group ids', VALUE_DEFAULT)
+ ]);
+ }
+
+ /**
+ * Fetch the details of a user's data request.
+ *
+ * @since Moodle 3.5
+ * @param string $query The search query.
+ * @param string $scheduler The scheduler id.
+ * @param string $groupids The group ids.
+ * @return array
+ * @throws required_capability_exception
+ * @throws dml_exception
+ * @throws invalid_parameter_exception
+ * @throws restricted_context_exception
+ */
+
+ public static function studentid($query, $scheduler, $groupids) {
+ $params = external_api::validate_parameters(self::studentid_parameters(), [
+ 'query' => $query,
+ 'scheduler' => $scheduler,
+ 'groupids' => $groupids
+ ]);
+ $query = $params['query'];
+ $scheduler = $params['scheduler'];
+ $groupids = $params['groupids'];
+
+ $scheduler = scheduler::load_by_id($scheduler);
+ $availablestudents = $scheduler->get_available_students();
+
+ $students = [];
+ $i = 0;
+ foreach ($availablestudents as $id => $student) {
+ $fullname = fullname($student);
+
+ if (mb_stripos($fullname, $query) !== false) {
+ $students[] = ['id' => $id, 'fullname' => fullname($student)];
+ $i++;
+ }
+ }
+
+ return $students;
+
+ }
+
+ /**
+ * Parameter description for get_users().
+ *
+ * @since Moodle 3.5
+ * @return external_description
+ * @throws coding_exception
+ */
+ public static function studentid_returns() {
+ return new external_multiple_structure(
+ new external_single_structure([
+ 'id' => new external_value(PARAM_INT, 'User ID'),
+ 'fullname' => new external_value(PARAM_NOTAGS, 'User fullname')
+ ])
+ );
+ }
+
+}
diff --git a/db/services.php b/db/services.php
new file mode 100644
index 00000000..6faa22da
--- /dev/null
+++ b/db/services.php
@@ -0,0 +1,37 @@
+.
+
+/**
+ * Mod Scheduler webservice definitions
+ *
+ * @package mod_scheduler
+ * @copyright 2022 University of Glasgow
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$functions = array(
+
+ 'mod_scheduler_studentid' => array(
+ 'classname' => 'mod_scheduler\external',
+ 'methodname' => 'studentid',
+ 'description' => 'Retrieve the list of potential studentids.',
+ 'type' => 'read',
+ 'ajax' => true,
+ 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
+ ),
+);
diff --git a/lib.php b/lib.php
index 907ef63b..14119c92 100644
--- a/lib.php
+++ b/lib.php
@@ -78,6 +78,18 @@ function scheduler_add_instance($data, $mform = null) {
return $data->id;
}
+function scheduler_student_autocomplete_callback($value) {
+ global $OUTPUT;
+
+ $fields = 'id ' . \core_user\fields::for_name()->get_sql()->selects;
+ $user = \core_user::get_user($value, $fields);
+ $useroptiondata = [
+ 'fullname' => fullname($user)
+ ];
+
+ return $OUTPUT->render_from_template('mod_scheduler/studentid', $useroptiondata);
+}
+
/**
* Given an object containing all the necessary data,
* (defined by the form in mod.html) this function
diff --git a/slotforms.php b/slotforms.php
index 4f8d8ad5..c03384cb 100644
--- a/slotforms.php
+++ b/slotforms.php
@@ -249,14 +249,12 @@ protected function definition() {
$repeatarray[] = $mform->createElement('header', 'appointhead', get_string('appointmentno', 'scheduler', '{no}'));
// Choose student.
- $students = $this->scheduler->get_available_students($this->usergroups);
- $studentchoices = array();
- if ($students) {
- foreach ($students as $astudent) {
- $studentchoices[$astudent->id] = fullname($astudent);
- }
- }
- $grouparray[] = $mform->createElement('searchableselector', 'studentid', '', $studentchoices);
+ $options = [
+ 'ajax' => 'mod_scheduler/studentid',
+ 'valuehtmlcallback' => 'scheduler_student_autocomplete_callback',
+ 'scheduler' => $this->scheduler->id
+ ];
+ $grouparray[] = $mform->createElement('autocomplete', 'studentid', '', [], $options);
$grouparray[] = $mform->createElement('hidden', 'appointid', 0);
// Seen tickbox.
diff --git a/templates/studentid.mustache b/templates/studentid.mustache
new file mode 100644
index 00000000..42658cd0
--- /dev/null
+++ b/templates/studentid.mustache
@@ -0,0 +1,52 @@
+{{!
+ This file is part of Moodle - http://moodle.org/
+
+ Moodle is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Moodle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Moodle. If not, see .
+}}
+{{!
+ @template mod_scheduler/studentid
+
+ Moodle template for the list of valid options in an autocomplate form element.
+
+ Classes required for JS:
+ * none
+
+ Data attributes required for JS:
+ * none
+
+ Context variables required for this template:
+ * fullname string Users full name
+ * email string user email field
+
+ Example context (json):
+ {
+ "fullname": "Admin User",
+ "extrafields": [
+ {
+ "name": "email",
+ "value": "admin@example.com"
+ },
+ {
+ "name": "phone1",
+ "value": "0123456789"
+ }
+ ]
+ }
+}}
+
+ {{fullname}}
+ {{#extrafields}}
+ {{{value}}}
+ {{/extrafields}}
+
diff --git a/tests/behat/behat_mod_scheduler.php b/tests/behat/behat_mod_scheduler.php
index 5c55add5..ad7e7db0 100644
--- a/tests/behat/behat_mod_scheduler.php
+++ b/tests/behat/behat_mod_scheduler.php
@@ -170,8 +170,8 @@ public function i_click_on_item_in_the_nth_autocomplete_list($item, $listnumber)
$downarrowtarget = "(//span[contains(@class,'form-autocomplete-downarrow')])[$listnumber]";
$this->execute('behat_general::i_click_on', [$downarrowtarget, 'xpath_element']);
- $xpathtarget = "(//ul[@class='form-autocomplete-suggestions']//*[contains(concat('|', string(.), '|'),'|" .
- $item . "|')])[$listnumber]";
- $this->execute('behat_general::i_click_on', [$xpathtarget, 'xpath_element']);
+ $xpathtarget = "(//descendant::ul[@class='form-autocomplete-suggestions'][$listnumber]//"
+ ."*[contains(concat('|', string(.), '|'),'|$item|')])";
+ $this->execute('behat_general::i_click_on', [$xpathtarget, 'xpath_element']);
}
}
diff --git a/version.php b/version.php
index 274c96d0..4952256a 100644
--- a/version.php
+++ b/version.php
@@ -29,7 +29,7 @@
*/
$plugin->component = 'mod_scheduler'; // Full name of the plugin (used for diagnostics).
-$plugin->version = 2024080102; // The current module version (Date: YYYYMMDDXX).
+$plugin->version = 2024080103; // The current module version (Date: YYYYMMDDXX).
$plugin->release = '4.x dev'; // Human-friendly version name.
$plugin->requires = 2023100905; // Requires Moodle 4.3.
$plugin->maturity = MATURITY_ALPHA; // Development release - not for production use.