<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://wiki.mipt.ru/index.php?action=history&amp;feed=atom&amp;title=Development%3AAjax_user_selector</id>
	<title>Development:Ajax user selector - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.mipt.ru/index.php?action=history&amp;feed=atom&amp;title=Development%3AAjax_user_selector"/>
	<link rel="alternate" type="text/html" href="http://wiki.mipt.ru/index.php?title=Development:Ajax_user_selector&amp;action=history"/>
	<updated>2026-05-06T22:00:44Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>http://wiki.mipt.ru/index.php?title=Development:Ajax_user_selector&amp;diff=10800&amp;oldid=prev</id>
		<title>Олег Давидович: 1 версия импортирована</title>
		<link rel="alternate" type="text/html" href="http://wiki.mipt.ru/index.php?title=Development:Ajax_user_selector&amp;diff=10800&amp;oldid=prev"/>
		<updated>2024-10-21T08:50:58Z</updated>

		<summary type="html">&lt;p&gt;1 версия импортирована&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 08:50, 21 октября 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Олег Давидович</name></author>
	</entry>
	<entry>
		<id>http://wiki.mipt.ru/index.php?title=Development:Ajax_user_selector&amp;diff=10799&amp;oldid=prev</id>
		<title>1&gt;TimHunt в 00:28, 14 ноября 2008</title>
		<link rel="alternate" type="text/html" href="http://wiki.mipt.ru/index.php?title=Development:Ajax_user_selector&amp;diff=10799&amp;oldid=prev"/>
		<updated>2008-11-14T00:28:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Moodle 2.0}}This was a proposal for a new user selector to be used on the assign roles and manage group memebers page, and also in two new reports I am writing for Moodle 2.0 to do with displaying a user&amp;#039;s roles and permissions.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;It is now finished&amp;#039;&amp;#039;&amp;#039;, and you can see a screen-shot on the [[Development:Roles_administration_improvements_for_Moodle_2.0#Improved_widget_for_selecting_users|Roles administration improvements for Moodle 2.0]] page. At some point this page should probably be converted into a docs page for people who want to use the new code. However, for now, I will just say that the code in user/selector/lib.php is well commented, and you can see how it is used in Moodle 2.0, so it should be easy to work out.&lt;br /&gt;
&lt;br /&gt;
The aim is to improve usability compared to the existing interface.&lt;br /&gt;
&lt;br /&gt;
A variant of this selector will be used for both the users already assigned the role, and the potential users. This should improve manageability of users in very large courses.&lt;br /&gt;
&lt;br /&gt;
==New configuration options==&lt;br /&gt;
&lt;br /&gt;
There will be an new admin option to control which fields are searched when selecting users, in addition to fullname. Three other options will be available: email, idnumber and username.&lt;br /&gt;
&lt;br /&gt;
:I know Petr will disapprove of username appearing on the list, because revealing usernames has security implications. However, I know several institutions that want this functionality, and I think we should supply it rather than making lots of different people hack the code. I will, however add a suitable warning to the description of this option. By default, only email will be selected, as at present.--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
==User interface==&lt;br /&gt;
&lt;br /&gt;
The selector will be available either as a stand alone HTML control, or as a formslib component.&lt;br /&gt;
&lt;br /&gt;
There will be options for selecting one or many users.&lt;br /&gt;
[[Image:Userselector.png|frame|Moodle 1.9 user selector]]&lt;br /&gt;
&lt;br /&gt;
===With JavaScript off===&lt;br /&gt;
&lt;br /&gt;
It will work very much like it does at the moment:&lt;br /&gt;
&lt;br /&gt;
It will be a list box that either lists users, or says that the list is too long and you should search. There will be a search box below with a search button to do the searching.&lt;br /&gt;
&lt;br /&gt;
The list of users may be displayed in opt-groups, depending on where this control appears. For example, on the group members page, users are grouped by role.&lt;br /&gt;
&lt;br /&gt;
There will always be at least one opt group, so the &amp;quot;7 potential users&amp;quot; label in the example would be changed to &amp;#039;Potential users&amp;#039;, and instead there will be an optgroup &amp;quot;All potential users (7)&amp;quot;. This might change to &amp;quot;Users matching &amp;#039;Fred&amp;#039; (4)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===With JavaScript on===&lt;br /&gt;
&lt;br /&gt;
As with JavaScript off, but the search button will disappear, and user searching will be done with Ajax.&lt;br /&gt;
&lt;br /&gt;
When some users have already been selected, and the search text is changed so that one of the already selected users no longer matches the search term, then a special extra optgroup &amp;#039;Already selected users&amp;#039; will be added at the start of the list, containing those users, still selected.&lt;br /&gt;
&lt;br /&gt;
If we are trying to just select one user, and the text in the search box does only match one user, then that user is automatically selected.&lt;br /&gt;
&lt;br /&gt;
Note that even with JavaScript turned on, the button click that actually does the the role assignment, or makes someone a member of a group, will still be a normal form submission.&lt;br /&gt;
&lt;br /&gt;
===HTML element names===&lt;br /&gt;
&lt;br /&gt;
Suppose that the developers asks for a user selector with name myuserselector. Then in the list box (&amp;lt;select&amp;gt;) will have name=&amp;quot;myuserselector[]&amp;quot; or name=&amp;quot;myuserselector&amp;quot; depending on whether we are doing multiple or single selection. The search text box will have name=&amp;quot;myuserselector_searchtext&amp;quot; and the search button name=&amp;quot;myuserselector_dosearch&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==Code architecture==&lt;br /&gt;
&lt;br /&gt;
The code for a user selector will be wrapped up in a class. There will be a base class user_selector_base which does the common work. Subclasses will just be responsible for implementing the method that searches the database and a constructor. They could also provide other methods for setting options, if they wanted.&lt;br /&gt;
&lt;br /&gt;
There will also be a formslib form element type.&lt;br /&gt;
&lt;br /&gt;
===Security===&lt;br /&gt;
&lt;br /&gt;
One issue with ajax interfaces is how you check permissions in the context of an ajax request, which often gives you very little context at all. Therefore, when a user_selector is displayed, a $selectorid hash code will be generated depending on the subclass name, the control name, and any options. At the same time, we will store the information about this user_selector in the session:&lt;br /&gt;
 $USER-&amp;gt;userselectors[$hash] = array(&lt;br /&gt;
     &amp;#039;class&amp;#039; = &amp;#039;my_user_selector&amp;#039;,&lt;br /&gt;
     // Probably some other values storing the options.&lt;br /&gt;
 );&lt;br /&gt;
&lt;br /&gt;
Then the ajax requests will go to a php file passing options ?selectorid=&amp;#039;&amp;#039;{selectorid}&amp;#039;&amp;#039;&amp;amp;sesskey=&amp;#039;{sesskey}&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
==API==&lt;br /&gt;
&lt;br /&gt;
===For users===&lt;br /&gt;
&lt;br /&gt;
 require_once($CFG-&amp;gt;dirroot);&lt;br /&gt;
 // ...&lt;br /&gt;
 &lt;br /&gt;
 $userselector = new group_memebers_user_selector(&amp;#039;myuserselector&amp;#039;, &amp;#039;&amp;#039;/* some options */&amp;#039;&amp;#039;);&lt;br /&gt;
 $userselector-&amp;gt;exclude($arrayofuserids); // For example when we are assigning roles, and don&amp;#039;t want to list people who already have that role.&lt;br /&gt;
 // Perhaps call some methods on $userselector to set more options? ...&lt;br /&gt;
 // ...&lt;br /&gt;
 &lt;br /&gt;
 if (data_submitted()) {&lt;br /&gt;
     // ...&lt;br /&gt;
     $users = $userselector-&amp;gt;get_selected_users(); // Like optional_param(&amp;#039;myuserselector&amp;#039;, array(), PARAM_INTEGER), but with more validation.&lt;br /&gt;
     // ...&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // ...&lt;br /&gt;
 $userselector-&amp;gt;display();&lt;br /&gt;
 // ...&lt;br /&gt;
&lt;br /&gt;
Usage within a [[Development:lib/formslib.php_Form_Definition|Moodle form]] will involve creating a &amp;#039;userselector&amp;#039; form field with some options in the usual sort of way.&lt;br /&gt;
&lt;br /&gt;
===For subclasses===&lt;br /&gt;
&lt;br /&gt;
 class my_user_selector extends user_selector_base {&lt;br /&gt;
     public function __construct($name, &amp;#039;&amp;#039;/* custom options */&amp;#039;&amp;#039;) {&lt;br /&gt;
         parent::__construct($name);&lt;br /&gt;
         // Other stuff ...&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     protected function find_users() {&lt;br /&gt;
         $sql = &amp;#039;SELECT &amp;#039; . $this-&amp;gt;required_fields_sql(&amp;#039;u&amp;#039;) . &amp;#039;, at.fieldwewant &amp;#039; .&lt;br /&gt;
                 &amp;#039;FROM {user} u JOIN {another_table} at ON at.userid = u.id &amp;#039; .&lt;br /&gt;
                 &amp;#039;WHERE &amp;#039; . $this-&amp;gt;search_sql(&amp;#039;u&amp;#039;) . &amp;#039; AND at.field = ? &amp;#039;;&lt;br /&gt;
         $users = get_recordset_sql($sql, array(&amp;#039;&amp;#039;/* params */&amp;#039;&amp;#039;));&lt;br /&gt;
         $groupedusers = array();&lt;br /&gt;
         foreach ($users as $user) {&lt;br /&gt;
             $optgroup = // ...; // This will be the actual string that is displayed as the name of the optgroup.&lt;br /&gt;
             $groupedusers[$optgroup][] = $user;&lt;br /&gt;
         }&lt;br /&gt;
         return $groupedusers;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     protected function get_options() {&lt;br /&gt;
         $options = parent::get_options();&lt;br /&gt;
         // Add our custom options to the $options array.&lt;br /&gt;
         return $options;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==JavaScript==&lt;br /&gt;
&lt;br /&gt;
I don&amp;#039;t think anything in YUI does quite what we want, so there will be some hand-coded JavaScript for populating the list box. However, I will try to use existing YUI code, for example the datasource, wherever possible. The JavaScript will just place a single user_selector_6534537 object in the global scope, where 6534537 is the hash mentioned under security above.&lt;br /&gt;
&lt;br /&gt;
==Where the code lives==&lt;br /&gt;
&lt;br /&gt;
I propose to put the code in a new user/selector folder. The code will consist of&lt;br /&gt;
;lib.php&lt;br /&gt;
:containing all the standard selector classes&lt;br /&gt;
;script.js&lt;br /&gt;
:the JavaScript&lt;br /&gt;
;search.php&lt;br /&gt;
:the target of ajax requests&lt;br /&gt;
&lt;br /&gt;
There will also be a lib/form/userselector.php for the formslib element that wraps a userselector.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=108966 Forum thread for discussing this design]&lt;br /&gt;
* MDL-16966&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Roles]]&lt;/div&gt;</summary>
		<author><name>1&gt;TimHunt</name></author>
	</entry>
</feed>