user selection: MDL-16994 Improve the user selector used on the assign roles and group memebers pages - Convert the group memebership page.

This commit is contained in:
tjhunt 2008-10-29 08:18:24 +00:00
parent e4749fcc08
commit 9787301687
9 changed files with 298 additions and 288 deletions

View File

@ -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;
});
}

View File

@ -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);
}

View File

@ -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,106 +28,45 @@ 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()) {
$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 (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)) {
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)) {
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);
}
$groupmembersselector->invalidate_selected_users();
$potentialmembersselector->invalidate_selected_users();
}
}
}
$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 .= '<optgroup label="'.s($roledata->name).'">';
foreach($roledata->users as $member) {
$groupmembersoptions .= '<option value="'.$member->id.'">'.fullname($member, true).'</option>';
$groupmemberscount ++;
}
$groupmembersoptions .= '</optgroup>';
}
} else {
$groupmembersoptions .= '<option>&nbsp;</option>';
}
$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 .= '<optgroup label="'.s($roledata->name).'">';
foreach($roledata->users as $member) {
$name = s(fullname($member, true));
$potentialmembersoptions .= '<option value="'.$member->id.
'" title="'.$name.'">'.$name.
' ('.@count($usergroups[$member->id]).')</option>';
}
$potentialmembersoptions .= '</optgroup>';
}
} else {
$potentialmembersoptions .= '<option>&nbsp;</option>';
}
}
// Print the page and form
$strgroups = get_string('groups');
$strparticipants = get_string('participants');
@ -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
check_theme_arrows();
?>
<script type="text/javascript">
//<![CDATA[
var userSummaries = Array(
<?php
$membercnt = count($potentialmembers);
$i=1;
foreach ($potentialmembers as $userid => $potentalmember) {
if (isset($usergroups[$userid])) {
$usergrouplist = '<ul>';
foreach ($usergroups[$userid] as $groupitem) {
$usergrouplist .= '<li>'.addslashes_js(format_string($groupitem->name)).'</li>';
}
$usergrouplist .= '</ul>';
}
else {
$usergrouplist = '';
}
echo "'$usergrouplist'";
if ($i < $membercnt) {
echo ', ';
}
$i++;
}
?>
);
function updateUserSummary() {
var selectEl = document.getElementById('addselect');
var summaryDiv = document.getElementById('group-usersummary');
var length = selectEl.length;
var selectCnt = 0;
var selectIdx = -1;
for(i=0;i<length;i++) {
if (selectEl.options[i].selected) {
selectCnt++;
selectIdx = i;
}
}
if (selectCnt == 1 && userSummaries[selectIdx]) {
summaryDiv.innerHTML = userSummaries[selectIdx];
} else {
summaryDiv.innerHTML = '';
}
return(true);
}
//]]>
</script>
<div id="addmembersform">
<h3 class="main"><?php print_string('adduserstogroup', 'group'); echo ": $groupname"; ?></h3>
@ -214,71 +93,28 @@ function updateUserSummary() {
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
<input type="hidden" name="group" value="<?php echo $groupid; ?>" />
<table cellpadding="6" class="generaltable generalbox groupmanagementtable boxaligncenter" summary="">
<table class="generaltable generalbox groupmanagementtable boxaligncenter" summary="">
<tr>
<td valign="top">
<td id='memberscell'>
<p>
<label for="removeselect"><?php print_string('existingmembers', 'group', $groupmemberscount); ?></label>
<label for="removeselect"><?php print_string('groupmembers', 'group'); ?></label>
</p>
<select name="removeselect[]" size="20" id="removeselect" multiple="multiple"
onfocus="document.getElementById('assignform').add.disabled=true;
document.getElementById('assignform').remove.disabled=false;
document.getElementById('assignform').addselect.selectedIndex=-1;"
onclick="this.focus();updateUserSummary();">
<?php echo $groupmembersoptions ?>
</select></td>
<td valign="top">
<?php // Hidden assignment? ?>
<?php check_theme_arrows(); ?>
<?php $groupmembersselector->display(); ?>
</td>
<td id='buttonscell'>
<p class="arrow_button">
<input name="add" id="add" type="submit" value="<?php echo $THEME->larrow.'&nbsp;'.get_string('add'); ?>" title="<?php print_string('add'); ?>" /><br />
<input name="remove" id="remove" type="submit" value="<?php echo get_string('remove').'&nbsp;'.$THEME->rarrow; ?>" title="<?php print_string('remove'); ?>" />
</p>
</td>
<td valign="top">
<td id='nonmemberscell'>
<p>
<label for="addselect"><?php print_string('potentialmembers', 'group', $potentialmemberscount); ?></label>
<label for="addselect"><?php print_string('potentialmembs', 'group'); ?></label>
</p>
<select name="addselect[]" size="20" id="addselect" multiple="multiple"
onfocus="updateUserSummary();document.getElementById('assignform').add.disabled=false;
document.getElementById('assignform').remove.disabled=true;
document.getElementById('assignform').removeselect.selectedIndex=-1;"
onclick="this.focus();updateUserSummary();">
<?php
if ($potentialmemberscount > MAX_USERS_PER_PAGE) {
echo '<optgroup label="'.get_string('toomanytoshow').'"><option></option></optgroup>'."\n"
.'<optgroup label="'.get_string('trysearching').'"><option></option></optgroup>'."\n";
} else {
echo $potentialmembersoptions;
}
?>
</select>
<br />
<label for="searchtext" class="accesshide"><?php p($strsearch) ?></label>
<input type="text" name="searchtext" id="searchtext" size="21" value="<?php p($searchtext) ?>"
onfocus ="getElementById('assignform').add.disabled=true;
getElementById('assignform').remove.disabled=true;
getElementById('assignform').removeselect.selectedIndex=-1;
getElementById('assignform').addselect.selectedIndex=-1;"
onkeydown = "var keyCode = event.which ? event.which : event.keyCode;
if (keyCode == 13) {
getElementById('assignform').previoussearch.value=1;
getElementById('assignform').submit();
} " />
<input name="search" id="search" type="submit" value="<?php p($strsearch) ?>" />
<?php
if (!empty($searchtext)) {
echo '<br /><input name="showall" id="showall" type="submit" value="'.s($strshowall).'" />'."\n";
}
?>
</td>
<td valign="top">
<p><?php echo($strusergroupmembership) ?></p>
<div id="group-usersummary"></div>
</td>
<?php $potentialmembersselector->display(); ?>
</td>
</tr>
<tr><td>
<tr><td colspan="3" id='backcell'>
<input type="submit" name="cancel" value="<?php print_string('backtogroups', 'group'); ?>" />
</td></tr>
</table>
@ -287,5 +123,6 @@ function updateUserSummary() {
</div>
<?php
print_js_call('init_add_remove_members_page');
print_footer($course);
?>

View File

@ -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';

View File

@ -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';

View File

@ -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
***/

View File

@ -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 = '<optgroup label="' . s($groupname) . ' (' . count($users) . ')">' . "\n";
$output = ' <optgroup label="' . s($groupname) . ' (' . count($users) . ')">' . "\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 .= '<option' . $selectattr . ' value="' . $user->id . '">' .
$output .= ' <option' . $selectattr . ' value="' . $user->id . '">' .
$this->output_user($user) . "</option>\n";
}
} else {
$output = '<optgroup label="' . s($groupname) . '">' . "\n";
$output .= '<option disabled="disabled">&nbsp;</option>' . "\n";
$output = ' <optgroup label="' . s($groupname) . '">' . "\n";
$output .= ' <option disabled="disabled">&nbsp;</option>' . "\n";
}
$output .= "</optgroup>\n";
$output .= " </optgroup>\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);
}
}
?>

View File

@ -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);
}

View File

@ -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 '</ul>';
}
echo '<form action="test.php"><div><label for="myuserselector">Select users</label>';
echo '<form action="test.php"><div style="width: 30em;"><label for="myuserselector">Select users</label>';
$userselector->display();
echo '<p><input type="submit" id="submitbutton" value="Submit" /></p>';
echo '</div></form>';
echo '<script type="text/javascript">
function selection_change(isempty) {
document.getElementById("submitbutton").disabled = !isempty;
document.getElementById("submitbutton").disabled = isempty;
}
user_selector.get("myuserselector").subscribe("selectionchanged", selection_change);
</script>';