Sure this can be quite a straightforward VisualForce page addition. I will provide some leads below which should be enough to get you to a solution. Everything should be added to your existing page / controller.
In order to have a popup-effect but keep your current state (after selecting the users, you want to return the result to the page at which you're currently at without too much effort), you can use some css styling.
<apex:outputPanel rendered="{!showPopup}" >
<apex:outputPanel styleClass="customPopup" layout="block" >
<!-- put your popup contents here -->
<!-- will be e.g. a pageBlockTable with the Users (incl checkbox to select) and a 'save' and 'cancel' button -->
</apex:outputPanel>
</apex:outputPanel>
<style type="text/css">
.customPopup{
background-color: white;
border-style: solid;
border-width: 1px;
left: 50%;
padding:10px;
position: absolute;
z-index: 9;
/* These are the 3 css properties you will need to tweak so the pop
up displays in the center of the screen. First set the width. Then set
margin-left to negative half of what the width is. You can also add
the height property for a fixed size pop up.*/
width: 750px;
margin-left: -375px;
top:50px;
}
Then in the popup, load a list of Users. In order to make them selectable, you could create a wrapper for the Users, adding a Boolean that indicates whether they are selected or not. Upon initializing the page, you can already load the users.
public with sharing class pageController {
public pageController(){
users = new List<UserWrapper>();
for(User theUser : [Select Id from User Where Name != null]{
UserWrapper uw = new UserWrapper();
uw.u = theUser;
uw.selected = false;
users.add(uw);
}
}
public Boolean showPopup {get;private set}
public List<UserWrapper> users {get;set;}
public class UserWrapper {
public User u {get;private set;}
public Boolean selected {get;set;}
}
}
Also add some pageReferences for the save and cancel methods. The save method will contain the logic to go through the list of users, checking whether they are selected or not, and if they are, adding their Email address to a String which you will then write back to the field.
Let's assume you have 4 boolean varialbes for each of the checkboxes in order to determine which one is selected:
public boolean apple {get; set;}
public boolean orange {get; set;}
public boolean grapes {get; set;}
public boolean kiwi {get; set;}
In your save method you can check which of the 4 is selected and build a semi-colon separated string with the values (it's how multi-select picklists store the values):
public void save()
{
String selectedFruits = '';
selectedFruits += apple == true ? 'Apple;' : '';
selectedFruits += orange == true ? 'Orange;' : '';
selectedFruits += grapes == true ? 'Grapes;' : '';
selectedFruits += kiwi == true ? 'Kiwi;' : '';
Tree__c treeRecord = new Tree__c();
treeRecord.Fruit__c = selectedFruits;
// set other fields
insert treeRecord;
}
Best Answer
You cannot bind a SObject field (even a picklist one) to a standard apex:selectList component...
The documentation for the apex:select says this about the value attribute.
A custom field of type multi picklist is exposed as a String (semi colon delimited), I'm not sure how this ever worked in a read or write case for you to be honest. If you switch to use apex:inputField it will work, though i imagine the appearance is not what you want? Your only option is to implement a wrapper class and expose a true String[] array or list as per the requirements of the apex:selectList component above.