From f771be2787f2a8657fe56fd7da9faa4af39ec078 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Wed, 29 Oct 2008 05:09:18 +0000 Subject: [PATCH] user selection: MDL-17053 Improve the user selector used on the assign roles and group memebers pages - Make single user select mode work properly. --- user/selector/lib.php | 82 ++++++++++++++++++++++++++++++++++------- user/selector/script.js | 18 +++++++-- user/selector/test.php | 1 + 3 files changed, 84 insertions(+), 17 deletions(-) diff --git a/user/selector/lib.php b/user/selector/lib.php index c202f97174..9160e636f2 100644 --- a/user/selector/lib.php +++ b/user/selector/lib.php @@ -123,15 +123,9 @@ abstract class user_selector_base { public function display($return = false) { global $USER, $CFG; - // Get the list of requested users, and if there is only one, set a flag to autoselect it. + // Get the list of requested users. $search = optional_param($this->name . '_searchtext', '', PARAM_RAW); $groupedusers = $this->find_users($search); - $select = false; - if (empty($groupedusers) && empty($this->selected)) { - $groupedusers = array(get_string('nomatchingusers') => array()); - } else if (count($groupedusers) == 1 && count(reset($groupedusers)) == 1) { - $select = true; - } // Output the select. $name = $this->name; @@ -145,7 +139,7 @@ abstract class user_selector_base { $multiselect . 'size="' . $this->rows . '">' . "\n"; // Populate the select. - $output .= $this->output_options($groupedusers, $select); + $output .= $this->output_options($groupedusers); // Output the search controls. $output .= "\n
\n"; @@ -221,6 +215,9 @@ abstract class user_selector_base { */ public abstract function find_users($search); + /** + * @return array the options needed to recreate this user_selector. + */ protected function get_options() { return array( 'class' => get_class($this), @@ -231,12 +228,21 @@ abstract class user_selector_base { // Inner workings ========================================================== + /** + * Get the list of users that were selected by doing optional_param then + * validating the result. + * + * @return array of user objects. + */ protected function load_selected_users() { // See if we got anything. $userids = optional_param($this->name, array(), PARAM_INTEGER); if (empty($userids)) { return array(); } + if (!$this->multiselect) { + $userids = array($userids); + } // If we did, use the find_users method to validate the ids. $this->validatinguserids = $userids; @@ -248,9 +254,20 @@ abstract class user_selector_base { foreach ($groupedusers as $group) { $users += $group; } + + // If we are only supposed to be selecting a single user, make sure we do. + if (!$this->multiselect && count($users) > 1) { + $users = array_slice($users, 0, 1); + } + return $users; } + /** + * @param string $u the table alias for the user table in the query being + * built. May be ''. + * @return string fragment of SQL to go in the select list of the query. + */ protected function required_fields_sql($u) { // Raw list of fields. $fields = array('id', 'firstname', 'lastname'); @@ -265,6 +282,14 @@ abstract class user_selector_base { return implode(',', $fields); } + /** + * @param string $search the text to search for. + * @param string $u the table alias for the user table in the query being + * built. May be ''. + * @return array an array with two elements, a fragment of SQL to go in the + * where clause the query, and an array containing any required parameters. + * this uses ? style placeholders. + */ protected function search_sql($search, $u) { global $DB; $params = array(); @@ -314,16 +339,27 @@ abstract class user_selector_base { * This method should do the same as the JavaScript method * user_selector.prototype.handle_response. * - * @param unknown_type $groupedusers - * @param unknown_type $select - * @return unknown + * @param array $groupedusers an array, as returned by find_users. + * @return string HTML code. */ - protected function output_options($groupedusers, $select) { + protected function output_options($groupedusers) { $output = ''; // Ensure that the list of previously selected users is up to date. $this->get_selected_users(); + // If $groupedusers is empty, make a 'no matching users' group. If there + // is only one selected user, set a flag to select them. + $select = false; + if (empty($groupedusers) && empty($this->selected)) { + $groupedusers = array(get_string('nomatchingusers') => array()); + } else if (count($groupedusers) == 1 && count(reset($groupedusers)) == 1) { + $select = true; + if (!$this->multiselect) { + $this->selected = array(); + } + } + // Output each optgroup. foreach ($groupedusers as $groupname => $users) { $output .= $this->output_optgroup($groupname, $users, $select); @@ -341,9 +377,17 @@ abstract class user_selector_base { return $output; } + /** + * Output one particular optgroup. Used by the preceding function output_options. + * + * @param string $groupname the label for this optgroup. + * @param array $users the users to put in this optgroup. + * @param boolean $select if true, select the users in this group. + * @return string HTML code. + */ protected function output_optgroup($groupname, $users, $select) { - $output = '' . "\n"; if (!empty($users)) { + $output = '' . "\n"; foreach ($users as $user) { if ($select || isset($this->selected[$user->id])) { $selectattr = ' selected="selected"'; @@ -355,6 +399,7 @@ abstract class user_selector_base { $this->output_user($user) . "\n"; } } else { + $output = '' . "\n"; $output .= '' . "\n"; } $output .= "\n"; @@ -385,8 +430,9 @@ abstract class user_selector_base { } /** - * Enter description here... + * * + * @return any HTML needed here. */ protected function initialise_javascript() { global $USER; @@ -408,12 +454,20 @@ abstract class user_selector_base { } } +/** + * User selector subclass for the list of potential users on the assign roles page. + * + */ class role_assign_potential_user_selector extends user_selector_base { public function find_users($search) { return array(); // TODO } } +/** + * User selector subclass for the list of users who already have the role in + * question on the assign roles page. + */ class role_assign_current_user_selector extends user_selector_base { public function find_users($search) { return array(); // TODO diff --git a/user/selector/script.js b/user/selector/script.js index 8fbeddde2c..be8822f756 100644 --- a/user/selector/script.js +++ b/user/selector/script.js @@ -290,6 +290,9 @@ user_selector.prototype.output_options = function(data) { // If there was only one option matching the search results, select it. if (this.onlyoption) { this.onlyoption.selected = true; + if (!this.listbox.multiple) { + this.selected = {}; + } } this.onlyoption = null; @@ -303,9 +306,16 @@ user_selector.prototype.output_options = function(data) { this.output_group(this.strprevselected, this.selected, true); } this.selected = null; - } +/** + * This method should do the same sort of thing as the PHP method + * user_selector_base::output_optgroup. + * + * @param String groupname the label for this optgroup.v + * @param Object users the users to put in this optgroup. + * @param Boolean select if true, select the users in this group. + */ user_selector.prototype.output_group = function(groupname, users, select) { var optgroup = document.createElement('optgroup'); optgroup.label = groupname; @@ -327,13 +337,14 @@ user_selector.prototype.output_group = function(groupname, users, select) { } count++; } - if (count == 0) { + if (count > 0) { + optgroup.label += ' (' + count + ')'; + } else { var option = document.createElement('option'); option.disabled = 'disabled'; option.appendChild(document.createTextNode('\u00A0')); optgroup.appendchild(option); } - optgroup.label += ' (' + count + ')'; this.listbox.appendChild(optgroup); } @@ -354,4 +365,5 @@ user_selector.prototype.output_user = function(user) { return output; } +// Say that we want to be a source of custom events. YAHOO.lang.augmentProto(user_selector, YAHOO.util.EventProvider); \ No newline at end of file diff --git a/user/selector/test.php b/user/selector/test.php index 78e6fc1b57..c1e334136b 100644 --- a/user/selector/test.php +++ b/user/selector/test.php @@ -46,6 +46,7 @@ require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); print_header(); $userselector = new test_user_selector('myuserselector'); +$userselector->set_multiselect(false); $users = $userselector->get_selected_users(); if (!empty($users)) { -- 2.39.5