From: tjhunt Date: Wed, 29 Oct 2008 08:18:24 +0000 (+0000) Subject: user selection: MDL-16994 Improve the user selector used on the assign roles and... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=9787301687423db8a4240a808728b7ac01e94c46;p=moodle.git user selection: MDL-16994 Improve the user selector used on the assign roles and group memebers pages - Convert the group memebership page. --- diff --git a/group/clientlib.js b/group/clientlib.js index d1f77f9a0e..f074ec1afb 100644 --- a/group/clientlib.js +++ b/group/clientlib.js @@ -201,3 +201,17 @@ var removeLoaderImgs = function (elClass, parentId) { parentEl.removeChild(loader); } }; + +function init_add_remove_members_page() { + var addselect = user_selector.get('addselect'); + document.getElementById('add').disabled = addselect.is_selection_empty(); + addselect.subscribe('selectionchanged', function(isempty) { + document.getElementById('add').disabled = isempty; + }); + + var removeselect = user_selector.get('removeselect'); + document.getElementById('remove').disabled = removeselect.is_selection_empty(); + removeselect.subscribe('selectionchanged', function(isempty) { + document.getElementById('remove').disabled = isempty; + }); +} \ No newline at end of file diff --git a/group/lib.php b/group/lib.php index 23e359820e..a647dbac34 100644 --- a/group/lib.php +++ b/group/lib.php @@ -392,57 +392,6 @@ function groups_delete_groupings($courseid, $showfeedback=false) { /* various functions used by groups UI */ /* =================================== */ -/** - * Gets the users for a course who are not in a specified group, and returns - * them in an array organised by role. For the array format, see - * groups_get_members_by_role. - * @param int $groupid The id of the group - * @param string searchtext similar to searchtext in role assign, search - * @return array An array of role id or '*' => information about that role - * including a list of users - */ -function groups_get_users_not_in_group_by_role($courseid, $groupid, $searchtext='', $sort = 'u.lastname ASC') { - global $CFG, $DB; - - $context = get_context_instance(CONTEXT_COURSE, $courseid); - -/// Get list of allowed roles - if (!$validroleids = groups_get_possible_roles($context)) { - return array(); - } - list($roleids, $params) = $DB->get_in_or_equal($validroleids, SQL_PARAMS_NAMED, $start='r0'); - - if ($searchtext !== '') { // Search for a subset of remaining users - $LIKE = $DB->sql_ilike(); - $FULLNAME = $DB->sql_fullname(); - $wheresearch = " AND u.id IN (SELECT id FROM {user} WHERE $FULLNAME $LIKE :search1 OR email $LIKE :search2)"; - $params['search1'] = "%$searchtext%"; - $params['search2'] = "%$searchtext%"; - } else { - $wheresearch = ''; - } - -/// Construct the main SQL - $sql = " SELECT r.id AS roleid,r.shortname AS roleshortname,r.name AS rolename, - u.id AS userid, u.firstname, u.lastname - FROM {user} u - JOIN {role_assignments} ra ON ra.userid = u.id - JOIN {role} r ON r.id = ra.roleid - WHERE ra.contextid ".get_related_contexts_string($context)." - AND u.deleted = 0 - AND ra.roleid $roleids - AND u.id NOT IN (SELECT userid - FROM {groups_members} - WHERE groupid = :groupid) - $wheresearch - ORDER BY $sort"; - $params['groupid'] = $groupid; - - $rs = $DB->get_recordset_sql($sql, $params); - return groups_calculate_role_people($rs, $context); -} - - /** * Obtains a list of the possible roles that group members might come from, * on a course. Generally this includes all the roles who would have @@ -620,15 +569,22 @@ function groups_unassign_grouping($groupingid, $groupid) { * @param int $courseid Course ID (should match the group's course) * @param string $fields List of fields from user table prefixed with u, default 'u.*' * @param string $sort SQL ORDER BY clause, default 'u.lastname ASC' + * @param string $extrawheretest extra SQL conditions ANDed with the existing where clause. + * @param array $whereparams any parameters required by $extrawheretest. * @return array Complex array as described above */ -function groups_get_members_by_role($groupid, $courseid, $fields='u.*', $sort='u.lastname ASC') { +function groups_get_members_by_role($groupid, $courseid, $fields='u.*', + $sort='u.lastname ASC', $extrawheretest='', $whereparams=array()) { global $CFG, $DB; // Retrieve information about all users and their roles on the course or // parent ('related') contexts $context = get_context_instance(CONTEXT_COURSE, $courseid); + if ($extrawheretest) { + $extrawheretest = ' AND ' . $extrawheretest; + } + $sql = "SELECT r.id AS roleid, r.shortname AS roleshortname, r.name AS rolename, u.id AS userid, $fields FROM {groups_members} gm @@ -636,10 +592,11 @@ function groups_get_members_by_role($groupid, $courseid, $fields='u.*', $sort='u JOIN {role_assignments} ra ON ra.userid = u.id JOIN {role} r ON r.id = ra.roleid WHERE gm.groupid=? - AND ra.contextid ".get_related_contexts_string($context)." + AND ra.contextid ".get_related_contexts_string($context). + $extrawheretest." ORDER BY r.sortorder, $sort"; - $params = array($groupid); - $rs = $DB->get_recordset_sql($sql, $params); + array_unshift($whereparams, $groupid); + $rs = $DB->get_recordset_sql($sql, $whereparams); return groups_calculate_role_people($rs, $context); } diff --git a/group/members.php b/group/members.php index c704129f8b..16924f5398 100644 --- a/group/members.php +++ b/group/members.php @@ -2,24 +2,18 @@ /** * Add/remove members from group. * - * @copyright © 2006 The Open University + * @copyright © 2006 The Open University and others * @author N.D.Freear AT open.ac.uk - * @author J.White AT open.ac.uk + * @author J.White AT open.ac.uk and others * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @package groups */ -require_once('../config.php'); -require_once('lib.php'); - -define("MAX_USERS_PER_PAGE", 5000); +require_once(dirname(__FILE__) . '/../config.php'); +require_once(dirname(__FILE__) . '/lib.php'); +require_once($CFG->dirroot . '/user/selector/lib.php'); +require_js('group/clientlib.js'); $groupid = required_param('group', PARAM_INT); -$searchtext = optional_param('searchtext', '', PARAM_RAW); // search string -$showall = optional_param('showall', 0, PARAM_BOOL); - -if ($showall) { - $searchtext = ''; -} if (!$group = $DB->get_record('groups', array('id'=>$groupid))) { print_error('invalidgroupid'); @@ -34,103 +28,42 @@ require_login($course); $context = get_context_instance(CONTEXT_COURSE, $courseid); require_capability('moodle/course:managegroups', $context); -$strsearch = get_string('search'); -$strshowall = get_string('showall'); $returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid.'&group='.$group->id; +if (optional_param('cancel', false, PARAM_BOOL)) { + redirect($returnurl); +} -if ($frm = data_submitted() and confirm_sesskey()) { - - if (isset($frm->cancel)) { - redirect($returnurl); - - } else if (isset($frm->add) and !empty($frm->addselect)) { - - foreach ($frm->addselect as $userid) { - if (! $userid = clean_param($userid, PARAM_INT)) { - continue; - } - if (!groups_add_member($groupid, $userid)) { +$groupmembersselector = new group_members_selector('removeselect', + array('groupid' => $groupid, 'courseid' => $course->id)); +$groupmembersselector->set_extra_fields(array()); +$potentialmembersselector = new group_non_members_selector('addselect', + array('groupid' => $groupid, 'courseid' => $course->id)); +$potentialmembersselector->set_extra_fields(array()); + +if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { + $userstoadd = $potentialmembersselector->get_selected_users(); + if (!empty($userstoadd)) { + foreach ($userstoadd as $user) { + if (!groups_add_member($groupid, $user->id)) { print_error('erroraddremoveuser', 'group', $returnurl); } + $groupmembersselector->invalidate_selected_users(); + $potentialmembersselector->invalidate_selected_users(); } - - } else if (isset($frm->remove) and !empty($frm->removeselect)) { - - foreach ($frm->removeselect as $userid) { - if (! $userid = clean_param($userid, PARAM_INT)) { - continue; - } - if (!groups_remove_member($groupid, $userid)) { - print_error('erroraddremoveuser', 'group', $returnurl); - } - } - } -} - -$groupmembersoptions = ''; -$groupmemberscount = 0; - -// Get members, organised by role, and display -if ($groupmemberroles = groups_get_members_by_role($groupid,$courseid,'u.id,u.firstname,u.lastname')) { - foreach($groupmemberroles as $roleid=>$roledata) { - $groupmembersoptions .= ''; - foreach($roledata->users as $member) { - $groupmembersoptions .= ''; - $groupmemberscount ++; - } - $groupmembersoptions .= ''; } -} else { - $groupmembersoptions .= ''; } -$potentialmembers = array(); -$potentialmembersoptions = ''; -$potentialmemberscount = 0; - -// Get potential members, organised by role, and count them -$potentialmembersbyrole = groups_get_users_not_in_group_by_role($courseid, $groupid, $searchtext); -$potentialmemberscount=0; -$potentialmembersids=array(); -if (!empty($potentialmembersbyrole)) { - foreach($potentialmembersbyrole as $roledata) { - $potentialmemberscount += count($roledata->users); - $potentialmembersids = array_merge($potentialmembersids, array_keys($roledata->users)); - } -} - -$usergroups = array(); - -if ($potentialmemberscount <= MAX_USERS_PER_PAGE) { - if ($potentialmemberscount > 0) { - // Get other groups user already belongs to - list($potentialmembersids, $params) = $DB->get_in_or_equal($potentialmembersids, SQL_PARAMS_NAMED, 'pm0'); - $sql = "SELECT u.id AS userid, g.* - FROM {user} u - JOIN {groups_members} gm ON u.id = gm.userid - JOIN {groups} g ON gm.groupid = g.id - WHERE u.id $potentialmembersids AND g.courseid = :courseid "; - $params['courseid'] = $course->id; - if ($rs = $DB->get_recordset_sql($sql, $params)) { - foreach ($rs as $usergroup) { - $usergroups[$usergroup->userid][$usergroup->id] = $usergroup; - } - $rs->close(); - } - - foreach ($potentialmembersbyrole as $roleid=>$roledata) { - $potentialmembersoptions .= ''; - foreach($roledata->users as $member) { - $name = s(fullname($member, true)); - $potentialmembersoptions .= ''; +if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) { + $userstoremove = $groupmembersselector->get_selected_users(); + if (!empty($userstoremove)) { + foreach ($userstoremove as $user) { + if (!groups_remove_member($groupid, $user->id)) { + print_error('erroraddremoveuser', 'group', $returnurl); } - $potentialmembersoptions .= ''; + $groupmembersselector->invalidate_selected_users(); + $potentialmembersselector->invalidate_selected_users(); } - } else { - $potentialmembersoptions .= ''; } } @@ -149,62 +82,8 @@ $navlinks[] = array('name' => $stradduserstogroup, 'link' => null, 'type' => 'mi $navigation = build_navigation($navlinks); print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '', '', true, '', user_login_string($course, $USER)); - -// Print Javascript for showing the selected users group membership -?> -

@@ -214,71 +93,28 @@ function updateUserSummary() { - +
- - + - - + display(); ?> + -
+

- +

-
- - - + display(); ?> +


+

- +

- -
- - - - '."\n"; - } - ?> -
-

-
-
+
@@ -287,5 +123,6 @@ function updateUserSummary() {
diff --git a/lang/en_utf8/error.php b/lang/en_utf8/error.php index c724a69b4c..dbaf14e933 100644 --- a/lang/en_utf8/error.php +++ b/lang/en_utf8/error.php @@ -269,7 +269,7 @@ $string['invalidnumkey'] = '\$conditions array may not contain numeric keys, ple $string['invalidoutcome'] = 'Incorrect outcome id'; $string['invalidpagesize'] = 'Invalid page size'; $string['invalidpaymentmethod'] = 'Invalid payment method: $a'; -$stirng['invalidqueryparam'] = 'ERROR: Incorrect number of query parameters!!'; +$string['invalidqueryparam'] = 'ERROR: Incorrect number of query parameters. Expected $a->expected, got $a->actual.'; $string['invalidrequest'] = 'Invalid request'; $string['invalidrole'] = 'Invalid role'; $string['invalidroleid'] = 'Invalid role ID'; diff --git a/lang/en_utf8/group.php b/lang/en_utf8/group.php index c1b6658ec1..9ee7678bfe 100644 --- a/lang/en_utf8/group.php +++ b/lang/en_utf8/group.php @@ -72,6 +72,7 @@ $string['newgrouping'] = 'New grouping'; $string['backtogroups'] = 'Back to groups'; $string['backtogroupings'] = 'Back to groupings'; $string['existingmembers'] = 'Existing members: $a'; +$string['potentialmembs'] = 'Potential members'; $string['potentialmembers'] = 'Potential members: $a'; $string['groupinfo'] = 'Info about selected group'; $string['groupinfomembers'] = 'Info about selected members'; diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css index f27ae4d5a0..16d7304ea2 100644 --- a/theme/standard/styles_layout.css +++ b/theme/standard/styles_layout.css @@ -433,16 +433,45 @@ form.popupform label { overflow:hidden; } +.groupmanagementtable { + width: 90%; +} + .groupmanagementtable td { - vertical-align: top; + vertical-align: middle; } .groupmanagementtable p { text-align: center; } -.groupmanagementtable select { - width: 18em; +.groupmanagementtable #memberscell, +.groupmanagementtable #nonmemberscell { + width: 42%; +} +.groupmanagementtable #memberscell label, +.groupmanagementtable #nonmemberscell label { + font-weight: bold; +} +.groupmanagementtable #buttonscell { + width: 16%; +} +.groupmanagementtable #buttonscell input { + width: 80%; + padding: 1em 0; + margin: 2em 0; +} +.groupmanagementtable #backcell { + padding-top: 2em; + text-align: center; +} +#removeselect_wrapper, +#addselect_wrapper { + width: 100%; +} +.groupmanagementtable #removeselect_wrapper label, +.groupmanagementtable #addselect_wrapper label { + font-weight: normal; } #group-groupings .buttons { @@ -517,6 +546,13 @@ div.hide { display:none; } +.userselector select { + width: 100%; +} +.userselector div label { + margin-right: 0.3em; +} + /*** *** Forms ***/ diff --git a/user/selector/lib.php b/user/selector/lib.php index 9160e636f2..04b1b3d87c 100644 --- a/user/selector/lib.php +++ b/user/selector/lib.php @@ -37,6 +37,10 @@ define('USER_SELECTOR_DEFAULT_ROWS', 20); /** * Base class for user selectors. + * + * In your theme, you must give each user-selector a defined width. If the + * user selector has name="myid", then the div myid_wrapper must have a width + * specified. */ abstract class user_selector_base { /** The control name (and id) in the HTML. */ @@ -115,14 +119,22 @@ abstract class user_selector_base { return $this->selected; } + /** + * If you update the database in such a way that it is likely to change the + * list of users that this component is allowed to select from, then you + * must call this method. For example, on the role assign page, after you have + * assigned some roles to some users, you should call this. + */ + public function invalidate_selected_users() { + $this->selected = null; + } + /** * Output this user_selector as HTML. * @param boolean $return if true, return the HTML as a string instead of outputting it. * @return mixed if $return is true, returns the HTML as a string, otherwise returns nothing. */ public function display($return = false) { - global $USER, $CFG; - // Get the list of requested users. $search = optional_param($this->name . '_searchtext', '', PARAM_RAW); $groupedusers = $this->find_users($search); @@ -199,6 +211,16 @@ abstract class user_selector_base { return $this->name; } + /** + * Set the user fields that are displayed in the selector in addition to the + * user's name. + * + * @param array $fields a list of field names that exist in the user table. + */ + public function set_extra_fields($fields) { + $this->extrafields = $fields; + } + // API for sublasses ======================================================= /** @@ -351,7 +373,7 @@ abstract class user_selector_base { // 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)) { + if (empty($groupedusers)) { $groupedusers = array(get_string('nomatchingusers') => array()); } else if (count($groupedusers) == 1 && count(reset($groupedusers)) == 1) { $select = true; @@ -387,7 +409,7 @@ abstract class user_selector_base { */ protected function output_optgroup($groupname, $users, $select) { if (!empty($users)) { - $output = '' . "\n"; + $output = ' ' . "\n"; foreach ($users as $user) { if ($select || isset($this->selected[$user->id])) { $selectattr = ' selected="selected"'; @@ -395,14 +417,14 @@ abstract class user_selector_base { $selectattr = ''; } unset($this->selected[$user->id]); - $output .= '' . + $output .= ' ' . $this->output_user($user) . "\n"; } } else { - $output = '' . "\n"; - $output .= '' . "\n"; + $output = ' ' . "\n"; + $output .= ' ' . "\n"; } - $output .= "\n"; + $output .= " \n"; return $output; } @@ -449,7 +471,8 @@ abstract class user_selector_base { // Initialise the selector. $output .= print_js_call('new user_selector', array($this->name, $hash, - sesskey(), $this->extrafields, get_string('previouslyselectedusers')), true); + sesskey(), $this->extrafields, get_string('previouslyselectedusers'), + get_string('nomatchingusers')), true); return $output; } } @@ -474,9 +497,119 @@ class role_assign_current_user_selector extends user_selector_base { } } -class group_members_user_selector extends user_selector_base { +abstract class groups_user_selector_base extends user_selector_base { + protected $groupid; + protected $courseid; + + /** + * @param string $name control name + * @param array $options should have two elements with keys groupid and courseid. + */ + public function __construct($name, $options) { + global $CFG; + parent::__construct($name, $options); + $this->groupid = $options['groupid']; + $this->courseid = $options['courseid']; + require_once($CFG->dirroot . '/group/lib.php'); + } + + protected function get_options() { + $options = parent::get_options(); + $options['groupid'] = $this->groupid; + $options['courseid'] = $this->courseid; + return $options; + } + + /** + * Enter description here... + * + * @param array $roles array in the format returned by groups_calculate_role_people. + * @return array array in the format find_users is supposed to return. + */ + protected function convert_array_format($roles) { + if (empty($roles)) { + $roles = array(); + } + $groupedusers = array(); + foreach ($roles as $role) { + $groupedusers[$role->name] = $role->users; + foreach ($groupedusers[$role->name] as &$user) { + unset($user->roles); + $user->fullname = fullname($user); + } + } + return $groupedusers; + } +} + +/** + * User selector subclass for the list of users who are in a certain group. + * Used on the add group memebers page. + */ +class group_members_selector extends groups_user_selector_base { public function find_users($search) { - return array(); // TODO + list($wherecondition, $params) = $this->search_sql($search, 'u'); + $roles = groups_get_members_by_role($this->groupid, $this->courseid, + $this->required_fields_sql('u'), 'u.lastname, u.firstname', + $wherecondition, $params); + return $this->convert_array_format($roles); + } +} + +/** + * User selector subclass for the list of users who are not in a certain group. + * Used on the add group memebers page. + */ +class group_non_members_selector extends groups_user_selector_base { + const MAX_USERS_PER_PAGE = 100; + + protected function output_user($user) { + return parent::output_user($user) . ' (' . $user->numgroups . ')'; + } + + public function find_users($search) { + global $DB; + + // Get list of allowed roles. + $context = get_context_instance(CONTEXT_COURSE, $this->courseid); + if (!$validroleids = groups_get_possible_roles($context)) { + return array(); + } + list($roleids, $roleparams) = $DB->get_in_or_equal($validroleids); + + // Get the search condition. + list($searchcondition, $searchparams) = $this->search_sql($search, 'u'); + + // Build the SQL + $fields = "SELECT r.id AS roleid, r.shortname AS roleshortname, r.name AS rolename, u.id AS userid, " . + $this->required_fields_sql('u') . + ', (SELECT count(igm.groupid) FROM {groups_members} igm JOIN {groups} ig ON + igm.groupid = ig.id WHERE igm.userid = u.id AND ig.courseid = ?) AS numgroups '; + $sql = " FROM {user} u + JOIN {role_assignments} ra ON ra.userid = u.id + JOIN {role} r ON r.id = ra.roleid + WHERE ra.contextid " . get_related_contexts_string($context) . " + AND u.deleted = 0 + AND ra.roleid $roleids + AND u.id NOT IN (SELECT userid + FROM {groups_members} + WHERE groupid = ?) + AND $searchcondition"; + $orderby = " ORDER BY u.lastname, u.firstname"; + + $params = array_merge($roleparams, array($this->groupid), $searchparams); + $potentialmemberscount = $DB->count_records_sql('SELECT count(DISTINCT u.id) ' . $sql, $params); + + if ($potentialmemberscount > group_non_members_selector::MAX_USERS_PER_PAGE) { + return array(get_string('toomanytoshow') => array(), + get_string('trysearching') => array()); + } + + array_unshift($params, $this->courseid); + $rs = $DB->get_recordset_sql($fields . $sql . $orderby, $params); + $roles = groups_calculate_role_people($rs, $context); + + return $this->convert_array_format($roles); } } ?> \ No newline at end of file diff --git a/user/selector/script.js b/user/selector/script.js index be8822f756..b551c6d874 100644 --- a/user/selector/script.js +++ b/user/selector/script.js @@ -12,14 +12,16 @@ * @param Array extrafields extra fields we are displaying for each user in addition to fullname. * @param String label used for the optgroup of users who are selected but who do not match the current search. */ -function user_selector(name, hash, sesskey, extrafields, strprevselected) { +function user_selector(name, hash, sesskey, extrafields, strprevselected, strnomatchingusers) { this.name = name; this.extrafields = extrafields; this.strprevselected = strprevselected; + this.strnomatchingusers = strnomatchingusers; + this.searchurl = moodle_cfg.wwwroot + '/user/selector/search.php?selectorid=' + + hash + '&sesskey=' + sesskey + '&search=' // Set up the data source. - this.datasource = new YAHOO.util.XHRDataSource(moodle_cfg.wwwroot + - '/user/selector/search.php?selectorid=' + hash + '&sesskey=' + sesskey + '&search='); + this.datasource = new YAHOO.util.XHRDataSource(this.searchurl); this.datasource.connXhrMode = 'cancelStaleRequests'; this.datasource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON; this.datasource.responseSchema = {resultsList: 'results'}; @@ -92,6 +94,14 @@ user_selector.prototype.extrafields = []; */ user_selector.prototype.strprevselected = ''; +/** + * Name of the no matching users group. + * + * @property strnomatchingusers + * @type String + */ +user_selector.prototype.strnomatchingusers = ''; + // Fields that configure the control's behaviour =============================== /** @@ -107,6 +117,13 @@ user_selector.prototype.querydelay = 0.2; // Internal fields ============================================================= +/** + * The URL for the datasource. + * @property searchurl + * @type String + */ +user_selector.prototype.searchurl = null; + /** * The datasource used to fetch lists of users from Moodle. * @property datasource @@ -199,6 +216,7 @@ user_selector.prototype.get_search_text = function() { */ user_selector.prototype.send_query = function() { var value = this.get_search_text(); + this.searchfield.className = ''; if (this.lastsearch == value) { return; } @@ -226,6 +244,15 @@ user_selector.prototype.handle_response = function(request, data) { */ user_selector.prototype.handle_failure = function() { this.listbox.style.background = ''; + this.searchfield.className = 'error'; + + // If we are in developer debug mode, output a link to help debug the failure. + if (moodle_cfg.developerdebug) { + var link = document.createElement('a'); + link.href = this.searchurl + this.get_search_text(); + link.appendChild(document.createTextNode('Ajax call failed. Click here to try the search call directly.')) + this.searchfield.parentNode.appendChild(link); + } } /** @@ -236,10 +263,10 @@ user_selector.prototype.is_selection_empty = function() { for (i = 0; i < options.length; i++) { var option = options[i]; if (option.selected) { - return true; + return false; } } - return false; + return true; } /** @@ -283,8 +310,14 @@ user_selector.prototype.output_options = function(data) { // Output each optgroup. this.onlyoption = null; + var nogroups = true; for (groupname in results) { this.output_group(groupname, results[groupname], false); + nogroups = false; + } + + if (nogroups) { + this.output_group(this.strnomatchingusers, {}, false) } // If there was only one option matching the search results, select it. @@ -343,7 +376,7 @@ user_selector.prototype.output_group = function(groupname, users, select) { var option = document.createElement('option'); option.disabled = 'disabled'; option.appendChild(document.createTextNode('\u00A0')); - optgroup.appendchild(option); + optgroup.appendChild(option); } this.listbox.appendChild(optgroup); } diff --git a/user/selector/test.php b/user/selector/test.php index c1e334136b..dfbc5fd7c7 100644 --- a/user/selector/test.php +++ b/user/selector/test.php @@ -34,7 +34,6 @@ class test_user_selector extends user_selector_base { $options['file'] = 'user/selector/test.php'; return $options; } - } if ($justdefineclass) { @@ -46,7 +45,7 @@ require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM)); print_header(); $userselector = new test_user_selector('myuserselector'); -$userselector->set_multiselect(false); +//$userselector->set_multiselect(false); $users = $userselector->get_selected_users(); if (!empty($users)) { @@ -58,14 +57,14 @@ if (!empty($users)) { echo ''; } -echo '
'; +echo '
'; $userselector->display(); echo '

'; echo '
'; echo '';