Moodle HTML Quickform select options not loading correctly

By : Chesney
Source: Stackoverflow.com
Question!

I have 2 select lists

  1. ausers - List all available users
  2. susers - Displays selected users

I use moodles global $SESSION variable to store the users selection items and then I load the selected items into the susers list using the $SESSION->susers variable. This happens when the user clicks on the "Add user" button.

I am using a session variable to save the selections since I need to post the form more than once. (The form will have another course selection list)

I cannot use javascript to accomplish this since my client wants the script to function without js support.

NOTE :

My code loads the options correctly but displays the current $SESSION data and the previous $SESSION data in the select list.I think the problem might be a refresh issue of the select element. I use the following statement to load the selected users in the susers element $susers_el->load($susers);

To better illustrate the problem :

On "Add user" button click

Selected users (ausers) 1.Joe 2.James Select List (susers) 1.Joe 2.James

When I want to add another user to the susers list the following happens: On "Add user" button click

Selected users (ausers) 3.Lance Select List (susers) 1.Joe 2.James 1.Joe 2.James 3.Lance

Below is the current code, any help or advice is most appreciated.

class learner_progress_form extends moodleform {
  function definition() {
    global $SESSION, $CFG;
    fb('Create form');
    $mform  = & $this->_form;
    //User Section
    $mform->addElement('header', 'site_users', 'Site Users');
    $objs[]    = array();
    $ausers[]  = array();
    //All users & courses sessions
    $SESSION->all_users   = $this->get_all_users(); 
    //Available users $ courses
    $ausers   = $SESSION->all_users; 
    //Form design
    $objs[0] =& $mform->createElement('select', 'ausers', 'Available users', $ausers, 'size="15"');
    $objs[0]->setMultiple(true);
    $objs[1] =& $mform->createElement('select', 'susers', 'Selected users', null, 'size="15"');
    $objs[1]->setMultiple(true);
    $grp =& $mform->addElement('group', 'usersgrp', 'Users', $objs, ' ', false);

    $objs = array();
    $objs[] =& $mform->createElement('submit', 'uaddsel','Add');
    $objs[] =& $mform->createElement('submit', 'uremovesel', 'Remove');
    $grp =& $mform->addElement('group', 'ubuttonsgrp', null, $objs, array(' ', '<br />'), false);
    $renderer =& $mform->defaultRenderer();
    $template = '<label class="qflabel" style="vertical-align:top">{label}</label> {element}';
    $renderer->setGroupElementTemplate($template, 'usersgrp');

    //Button Section
    $mform->addElement('header','actions','Generate report');
    $objs = array();
    $objs[] =& $mform->createElement('submit', 'submit', 'Go');
    $mform->addElement('group', 'actionsgrp', 'Generate report with selected data', $objs, ' ', false);
  }

  function definition_after_data() {
    global $SESSION;
    fb('definition after data');
    $mform      =& $this->_form; 
    //Get users group and elements
    $usersgrp   =& $mform->getElement('usersgrp')->getElements();
    //Selected Users
    $susers_el  =& $usersgrp[1]; //selected users 
    $susers     = $SESSION->susers;
    $susers_el->load($susers); 
  }

function get_all_users() {
    global $SESSION, $CFG;
    $ausers = array();
    $userlist = get_records_sql(
      "select id, firstname, lastname, email 
      from {$CFG->prefix}user
      where id NOT IN (0,1,2)"); //exclude empty,admin & guest
    foreach($userlist as $user){
      if (!empty($user) ) {
        $ausers[$user->id] = $user->firstname." ".$user->lastname;
      }
    }
    //sort($ausers);
    return $ausers;
  }

/**
 * Add user(s) selections to list
 * $SESSION->s_users : Stores previous selections
 * TBD   : Seems to be a refresh bug
 * TOFIX : Duplication - possible refresh bug 
 **/
  function set_user_selections() {
    global $SESSION, $CFG;
    $usergrp        =& $this->_form->getElement('usersgrp')->getElements();
    $ausers_el      =& $usergrp[0];
    $susers_el      =& $usergrp[1];
    $susers         = $ausers_el->getSelected();
    $ausers         = $SESSION->all_users;
    $users          = array();
    //build selected users array
    foreach ($susers as $user=>$id) {
      $users[$id] = $ausers[$id];
    }
    //Check selected user sessions
    if (isset($SESSION->susers) )
    {
      //Remove duplicate selections
      foreach ($SESSION->susers as $id=>$val) {
        if (in_array($id, $users) )
        {
          unset($SESSION->susers[$id]);
        }
      }
      $users = $SESSION->susers + $users;
    }
    $SESSION->susers = $users;
    //asort($users);
    fb('User being loaded in select list');
    fb($users);
    $susers_el->load($users);
  }
By : Chesney


Answers

SOLVED! I basically had to check the $_POST variables to perform the appropriate action on my select lists. This had to be done in the definition_after_data function every time the form is loaded (refreshed, posted etc). The session variables work great to keep load the users previous selections.

These simple lines of code solved my problem.

//Load users  
if (!isset($_POST['uaddsel']) and !isset($_POST['uremovesel']) ) { 
  $this->load_session_users(); //load previous selected user in susers 
} 
//Load courses 
if (!isset($_POST['caddsel']) and !isset($_POST['cremovesel']) ) { 
  $this->load_session_courses(); 
}

and in my index.php i would call :

//Add user
  if (isset($_POST['uaddsel']) ) {
    //add user
    $form->set_user_selections();
  }
  //remove user
  if (isset($_POST['uremovesel']) ) {
    $form->remove_selected_users();
  }
By : QCar


This video can help you solving your question :)
By: admin