Bulk add users to a course / class - Add multiple members to a course

Under Add multiple members, could the user selection be changed or a better user-friendly filter added to find and select users? https://opigno.atlassian.net/wiki/spaces/OUM/pages/360776/Add+or+remove… https://opigno.atlassian.net/wiki/spaces/OUM/pages/360704/Add+or+remove… It becomes very difficult/impossible to find the users in a long list, especially when usernames are displayed instead of their real/names. Where the single add member function makes it rather easy to find a user as it allows for input both username or names.


Found an interesting module https://www.drupal.org/project/improved_multi_select which is supposed to replace the default multi-select boxes with two pannel list and search. But even a better module https://www.drupal.org/project/autocomplete_deluxe which has type ahead search! I tried implementing autocomplete_delux by hacking for now /opigno/profiles/opigno_lms/modules/opigno/opigno/modules/simple_ui/includes/opigno_simple_ui.og.inc (If I get this to work we can create a custom module) $form['massadd'] = array( // '#type' => 'multiselect', '#title' => t('Select students to add to the group'), // '#default_value' => NULL, // '#size' => 15, '#required' => TRUE, '#type' => 'autocomplete_deluxe', '#autocomplete_deluxe_path' => url('autocomplete_deluxe/taxonomy/MY-FIELD-MACHINE-NAME', array('absolute' => TRUE)), '#multiple' => TRUE, '#autocomplete_min_length' => 0, '#autocomplete_multiple_delimiter' => ',', '#not_found_message' => "The term '@term' will be added.", ); But I can't figure out what the machine field name is of the usernames? Any idea what I can try / need to use? Already tried og_user and user. Using the **user/autocomplete** which I found is used for the single add member works somewhat, but not sure if that's is loading a different interface for this. '#autocomplete_deluxe_path' => url('user/autocomplete', array('absolute' => TRUE)),

Better Module which is working great: Chosen

An even better module is chosen instead of Autocomplete Deluxe, as it prevents adding new terms

(since we don't want to create new usernames - which the form doesn't allow to submit anyway but is annoying that at first will accept it as an option)

Please Note dependancy: It requires the module jquery_update to set default jQuery Version to 1.8 /admin/config/development/jquery_update (higher won't work with statistics app!)

Here the changes, although Ideally we don't want to hack code and should create a custom module for it's implementation. 



// Attach CSS and Javascript for multiselect type field. // $form['#attached']['js'][] = drupal_get_path('module', 'multiselect') . '/multiselect.js'; // $form['#attached']['css'][] = drupal_get_path('module', 'multiselect') . '/multiselect.css'; $form['massadd'] = array( // '#type' => 'multiselect', //disable multiselect '#type' => 'select', //use chosen instead of multiselect '#title' => t('Select students to add to the group'), '#default_value' => NULL, // '#size' => 15, //not requires as chosen has scrollable dropdown and typeahead search '#required' => TRUE, '#multiple' => TRUE, // allow multiple selections for chosen );


Since I'm using realname (Firstname Lastname instead of username), I also had to replace the query to cross-check against users table based on uid

$users = entity_load('user'); foreach ($users as $uid => $account) { if ($uid && !in_array($uid, $exclude)) { // $form['massadd']['#options'][$account->uid] = $account->name; $form['massadd']['#options'][$account->uid] = $account->realname; } } natcasesort($form['massadd']['#options']); //sort users descending /opigno/profiles/opigno_lms/modules/contrib/og_massadd/og_massadd.module // If not, try to check for usernames if (!isset($account) && drupal_strlen($mail)) { // $query = new EntityFieldQuery(); // $query->entityCondition('entity_type', 'user') // ->propertyCondition('name', check_plain($mail)); // $result = $query->execute(); $query = db_select('realname','rn'); $query->join('users','usr','usr.uid=rn.uid'); $query->fields('rn', array('uid')); $query->condition('rn.realname',$mail,'='); $result =$query->execute()->fetchAll(); if (!empty($result)) { $uids =array($result[0]->uid); $account = user_load_multiple($uids); $account = array_shift($account); }


2) NOTE: Private Messaging App - needs to be changed as well! 


unset($form['recipient']['#required']); if (!isset($form['recipient1'])) { // $form['recipient1'] = array( //use $form['recipient'] instead to work with chosen select options $form['recipient'] = array( // '#type' => 'multiselect', '#type' => 'select', //use select for module chosen instead of multiselect module '#multiple' => TRUE, // select multiple recipients '#title' => t('Select recipients'), '#default_value' => NULL, '#size' => 10, '#required' => TRUE, '#weight' => -6, '#prefix' => '<div id="recipient1-div">', '#suffix' => '</div>', '#validated' => TRUE, ); }


FIX: course selection to list available users callback

function messaging_user_update_callback($form, &$form_state) { // $form['recipient1']['#options'] = NULL; $form['recipient']['#options'] = NULL; //use for main select options with chosen $group = $form_state['input']['groups']; global $user; $needs_filtering = TRUE; if ($group === t('All')) { $groups = _opigno_messaging_app_get_groups($user); if (user_access('message anyone regardless of groups')) { $needs_filtering = FALSE; $users = array(); $all_users = entity_load('user'); foreach ($all_users as $value) { $user_list = (array) $value; if ($user_list['uid'] != $user->uid) { $users[$user_list['uid']] = $user_list['name']; } } } } else { $groups['node'][$group] = $group; } if ($needs_filtering) { $users = _opigno_messaging_app_get_users_in_groups($groups, $user); } asort($users); foreach ($users as $userid => $username) { // $form['recipient1']['#options'][$username] = $username; $form['recipient']['#options'][$username] = $username; //use for main select options with chosen } // return $form['recipient1']; return $form['recipient']; //use for main select options with chosen


Below working with realname module, which also requires  privatemsg_realname module (for reverse lookup). 

function _opigno_messaging_app_get_users_in_groups($groups, $user) { $allusers = entity_load('user'); foreach ($allusers as $account) { foreach ($groups['node'] as $groupsid => $group_id) { if (($account->uid != 0) && ($account->uid != $user->uid)) { if ((og_is_member('node', $group_id, 'user', $account)) && ((og_user_access('node', $group_id, "can be messaged", $account)) || (og_user_$ // $users[$account->uid] = $account->name; //change for realname $users[$account->uid] = $account->realname; } } } } return $users; }   $needs_filtering = TRUE; if ((isset($form_state['input']['groups'])) || ((!isset($form_state['input']['groups'])) && ($form['groups']['#default_value'] == t('All'))))$ if (user_access('message anyone regardless of groups')) { $needs_filtering = FALSE; $users = array(); $all_users = entity_load('user'); foreach ($all_users as $value) { $user_list = (array) $value; if ($user_list['uid'] != $user->uid) { // $users[$user_list['uid']] = $user_list['name']; $users[$user_list['uid']] = $user_list['realname']; //use realname instead of username, //which requires privatemsg_realname module to be active } } } }

Chosen - Bulk add users with scroll &amp; type ahead any word search

Image removed.  Image removed.  Image removed.


FYI - All working great! Love it.

I updated the code above, fixed the issue with rendering inside private messaging as it was originally set up for  autocomplete field / multiselect.

The only downside is the performance of rendering a user list with many entries, I got more than 1k and takes about 3 secs.

The selection process for bulk adding users is nicer though for multiple users to click and it can list available users to scroll through. 
Perhaps performance could be improved to render faster.

If I understand correctly, multiselect (select user from list and click add to the right) was implemented instead of autocomplete search so that the courses and classes dropdown could be implemented (to select related users), which unfortunally becomes unusable with a long list of users!