Skip to main content

Custom Queue Management using visualforce page

Here is the pseudo code to build custom page to add/remove queue members without giving Setup and Configuration setting to any other user's profile than Sys Admin

Sample Controller:

public class QueueManagementController {
 
    public SelectOption[] selectedContacts { get; set; }
    public SelectOption[] allContacts { get; set; }
    public SelectOption[] queuelist {get; set;}
 
    public String queueId {get; set;}
    public String message { get; set; }
 
    public QueueManagementController(){
     
        queuelist = new List<SelectOption>();
        queuelist.add(new SelectOption('', '-None-'));
        for(Group Grouprecord : [Select Id, name from Group where type = 'Queue']){
            queuelist.add(new SelectOption(grouprecord.Id, grouprecord.name));
         
        }
     
        fillSelectOptions();
    }
 
    public PageReference save() {
        message = 'Selected Contacts: ';
        Boolean first = true;
        for ( SelectOption so : selectedContacts ) {
            if (!first) {
                message += ', ';
            }
            message += so.getLabel() + ' (' + so.getValue() + ')';
            first = false;
        }
     
        return null;    
    }
 
    public void fillSelectOptions(){
        selectedContacts = new List<SelectOption>();
        set<id> userIds=new set<id>();
        if(queueId != '' && queueId != null){
         
            for(Group Grouprec : [Select Id, name, (Select UserorGroupId from GroupMembers) from Group where type = 'Queue' and id =: queueId]){
             
             
                if(Grouprec.GroupMembers != null && Grouprec.GroupMembers.size() > 0){
                    for(GroupMember groupMember:Grouprec.GroupMembers)
                    {
                        userIds.add(groupMember.UserOrGroupId);
                     
                    }
                }
             
            }
            if(!userIds.isEmpty())
            {
                for(User user:[select id,name from User where id in :userIds])
                {
                    selectedContacts.add(new selectOption(user.Id, user.name));
                 
                }
             
            }
         
         
         
        }
     
        List<User> Users = [SELECT Name, Id FROM User Where User.Profile.name = 'xyz' and IsActive = TRUE ORDER BY Name];
     
        allContacts = new List<SelectOption>();
        for ( User c : Users ) {
            if(!userIds.contains(c.Id))
                allContacts.add(new SelectOption(c.Id, c.Name));
        }
    }
 
 
    public PageReference doSave()
    {
     
        if(queueId!=null && queueId!=''){
            set<id> userIds=new set<id>();
            List<GroupMember> insertgroupMember=new List<GroupMember>();
            List<GroupMember> deletegroupMember=new List<GroupMember>();
            for(SelectOption options:selectedContacts)
            {
                userIds.add(options.getValue());
             
            }
            for(Group Grouprec : [Select Id, name, (Select UserorGroupId from GroupMembers) from Group where type = 'Queue' and id =: queueId]){
             
                set<id> groupMemberUserIds=new set<id>();
                if(Grouprec.GroupMembers != null && Grouprec.GroupMembers.size() > 0){
                    for(GroupMember groupMember:Grouprec.GroupMembers)
                    {
                        groupMemberUserIds.add(groupMember.UserOrGroupId);
                        if(!userIds.contains(groupMember.UserOrGroupId)){
                            deletegroupMember.add(groupMember);
                        }
                    }
                }
             
                for(Id userId:userIds){
                    if(!groupMemberUserIds.contains(userId))
                    {
                        insertgroupMember.add(new GroupMember(GroupId=queueId,UserOrGroupId= userId));
                    }
                 
                }
             
            }
         
            Savepoint sp=Database.setSavepoint();
            try
            {
                insert insertgroupMember;
                system.debug('******'+insertgroupMember);
                delete deletegroupMember;
                system.debug('******'+deletegroupMember);
             
            }
            catch( exception e)
            {
                Database.rollback(sp);
                system.debug('******'+e.getMessage());
                ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.ERROR,e.getMessage()));
             
            }
         
        }
        else{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.WARNING,'Please select the queue'));
            return null;
         
        }
     
     
     
        return null;
    }
 
 
}

------------------------------------------------------

Sample Page Page:

<apex:page sidebar="true" controller="QueueManagementController" showHeader="true">
    <apex:form >
        <apex:pageBlock title="Queue Maintenance">
            <apex:pageBlockSection title="Select Queue to be Modified">
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Select Queue" id="queuelist"></apex:OutputLabel>
                    <apex:selectList value="{!queueId}" size="1" multiselect="false" >
                        <apex:selectOptions value="{!queuelist}"/>
                        <apex:actionSupport event="onchange" action="{!fillSelectOptions}"/>
                     
                    </apex:selectList>
                </apex:pageBlockSectionItem>
             
            </apex:pageblockSection>
            <c:MultiSelectPicklist leftLabel="Available Users"
                                   leftOption="{!allContacts}"
                                   rightLabel="Current Members"
                                   rightOption="{!selectedContacts}"
                                   size="24"
                                   width="300px"/>
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!doSave}" title="Save"/>
                <apex:commandButton value="Cancel"  title="Cancel"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
    <apex:outputText >{!message}</apex:outputText>
</apex:page>

-----------------------------------------------------------------
Visualforce Component Controller: MultiSelectController

public class MultiSelectController {

    public String selectedContacts { get; set; }

    public String allContacts { get; set; }

    public PageReference fillSelectOptions() {
        return null;
    }


    public String queuelist { get; set; }

    public String queueId { get; set; }
    // SelectOption lists for public consumption
    public SelectOption[] leftOptions { get; set; }
    public SelectOption[] rightOptions { get; set; }
 
    // Parse &-separated values and labels from value and
    // put them in option
    private void setOptions(SelectOption[] options, String value) {
        options.clear();
        String[] parts = value.split('&');
        for (Integer i=0; i<parts.size()/2; i++) {
            options.add(new SelectOption(EncodingUtil.urlDecode(parts[i*2], 'UTF-8'),
              EncodingUtil.urlDecode(parts[(i*2)+1], 'UTF-8')));
        }
    }
 
    // Backing for hidden text field containing the options from the
    // left list
    public String leftOptionsHidden { get; set {
           leftOptionsHidden = value;
           setOptions(leftOptions, value);
        }
    }
 
    // Backing for hidden text field containing the options from the
    // right list
    public String rightOptionsHidden { get; set {
           rightOptionsHidden = value;
           setOptions(rightOptions, value);
        }
    }
}

-------------------------------------------------------------------------
Visualforce Component: MultiSelectPicklist

<apex:component controller="MultiSelectController">
    <apex:attribute name="leftLabel" description="Label on left listbox."
                    type="String" required="true" />
    <apex:attribute name="rightLabel" description="Label on right listbox."
                    type="String" required="true" />
    <apex:attribute name="size" description="Size of listboxes."
                    type="Integer" required="true" />
    <apex:attribute name="width" description="Width of listboxes."
                    type="String" required="true" />
    <apex:attribute name="showUpDownButtons" description="Should Up/Down buttons be displayed or not."
                    type="Boolean" required="false" default="true"/>
 
    <apex:attribute name="leftOption"
                    description="Options list for left listbox." type="SelectOption[]"
                    required="true" assignTo="{!leftOptions}" />
    <apex:attribute name="rightOption"
                    description="Options list for right listbox." type="SelectOption[]"
                    required="true" assignTo="{!rightOptions}" />
 
    <apex:outputPanel id="multiselectPanel" layout="block" styleClass="duelingListBox">
        <table class="layout">
            <tbody>
                <tr>
                    <td class="selectCell">
                        <apex:outputPanel layout="block" styleClass="selectTitle">
                            <!--
Visualforce prepends the correct prefix to the outputLabel's
'for' attribute
-->
                            <apex:outputLabel value="{!leftLabel}"
                                              for="multiselectPanel:leftList" />
                        </apex:outputPanel>
                        <select id="{!$Component.multiselectPanel}:leftList"
                                class="multilist" multiple="multiple" size="{!size}"
                                style="width: {!width};">
                            <apex:repeat value="{!leftOptions}" var="option">
                                <option value="{!option.value}">{!option.label}</option>
                            </apex:repeat>
                        </select>
                    </td>
                    <td class="buttonCell">
                        <apex:outputPanel layout="block" styleClass="text">Add</apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="text">
                            <apex:outputLink value="javascript:moveSelectedOptions('{!$Component.multiselectPanel}:leftList',
                                                    '{!$Component.multiselectPanel}:rightList', '{!$Component.leftHidden}',
                                                    '{!$Component.rightHidden}');"
                                             id="btnRight">
                                <apex:image value="/s.gif" alt="Add" styleClass="rightArrowIcon"
                                            title="Add" />
                            </apex:outputLink>
                        </apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="text">
                            <apex:outputLink value="javascript:moveSelectedOptions('{!$Component.multiselectPanel}:rightList',
                                                    '{!$Component.multiselectPanel}:leftList', '{!$Component.rightHidden}',
                                                    '{!$Component.leftHidden}');"
                                             id="btnLeft">
                                <apex:image value="/s.gif" alt="Remove"
                                            styleClass="leftArrowIcon" title="Remove" />
                            </apex:outputLink>
                        </apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="duelingText">Remove</apex:outputPanel>
                    </td>
                    <td class="selectCell">
                        <apex:outputPanel layout="block" styleClass="selectTitle">
                            <apex:outputLabel value="{!rightLabel}" for="multiselectPanel:rightList" />
                        </apex:outputPanel>
                        <select id="{!$Component.multiselectPanel}:rightList"
                                class="multilist" multiple="multiple" size="{!size}"
                                style="width: {!width};">
                            <apex:repeat value="{!rightOptions}" var="option">
                                <option value="{!option.value}">{!option.label}</option>
                            </apex:repeat>
                        </select>
                    </td>
                    <td class="buttonCell"><apex:outputPanel layout="block"
                                                             styleClass="text" rendered="{!showUpDownButtons}">Up</apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="text" rendered="{!showUpDownButtons}">
                            <apex:outputLink value="javascript:slideSelectedOptionsUp('{!$Component.multiselectPanel}:rightList',
                                                    '{!$Component.rightHidden}');"
                                             id="upBtn">
                                <apex:image value="/s.gif" alt="Up" styleClass="upArrowIcon"
                                            title="Up" />
                            </apex:outputLink>
                        </apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="text" rendered="{!showUpDownButtons}">
                            <apex:outputLink value="javascript:slideSelectedOptionsDown('{!$Component.multiselectPanel}:rightList',
                                                    '{!$Component.rightHidden}');"
                                             id="downBtn">
                                <apex:image value="/s.gif" alt="Down" styleClass="downArrowIcon"
                                            title="Down" />
                            </apex:outputLink>
                        </apex:outputPanel>
                        <apex:outputPanel layout="block" styleClass="text" rendered="{!showUpDownButtons}">Down</apex:outputPanel>
                    </td>
                </tr>
            </tbody>
        </table>
        <apex:inputHidden value="{!leftOptionsHidden}" id="leftHidden" />
        <apex:inputHidden value="{!rightOptionsHidden}" id="rightHidden" />
    </apex:outputPanel>
 
    <script type="text/javascript">
    if (!buildOutputString) {
        // Create a string from the content of a listbox
        var buildOutputString = function(listBox, hiddenInput) {
            var str = '';
         
            for ( var x = 0; x < listBox.options.length; x++) {
                str += encodeURIComponent(listBox.options[x].value) + '&'
                + encodeURIComponent(listBox.options[x].text) + '&';
            }
            str.length--;
         
            hiddenInput.value = str.slice(0, -1);
        }
        }
 
    if (!moveSelectedOptions) {
        // Move the selected options in the idFrom listbox to the idTo
        // listbox, updating the corresponding strings in idHdnFrom and
        // idHdnTo
        var moveSelectedOptions = function(idFrom, idTo, idHdnFrom, idHdnTo) {
            listFrom = document.getElementById(idFrom);
            listTo = document.getElementById(idTo);
         
            for ( var x = 0; x < listTo.options.length; x++) {
                listTo.options[x].selected = false;
            }
         
            for ( var x = 0; x < listFrom.options.length; x++) {
                if (listFrom.options[x].selected == true) {
                    listTo.appendChild(listFrom.options[x]);
                    x--;
                }
            }
         
            listTo.focus();
         
            buildOutputString(listFrom, document.getElementById(idHdnFrom));
            buildOutputString(listTo, document.getElementById(idHdnTo));
        }
        }
 
    if (!slideSelectedOptionsUp) {
        // Slide the selected options in the idList listbox up by one position,
        // updating the corresponding string in idHidden
        var slideSelectedOptionsUp = function(idList, idHidden) {
            listBox = document.getElementById(idList);
         
            var len = listBox.options.length;
         
            if (len > 0 && listBox.options[0].selected == true) {
                return;
            }
         
            for ( var x = 1; x < len; x++) {
                if (listBox.options[x].selected == true) {
                    listBox.insertBefore(listBox.options[x],
                                         listBox.options[x - 1]);
                }
            }
         
            listBox.focus();
         
            buildOutputString(listBox, document.getElementById(idHidden));
        }
        }
 
    if (!slideSelectedOptionsDown) {
        // Slide the selected options in the idList listbox down by one position,
        // updating the corresponding string in idHidden
        var slideSelectedOptionsDown = function(idList, idHidden) {
            listBox = document.getElementById(idList);
         
            var len = listBox.options.length;
         
            if (len > 0 && listBox.options[len - 1].selected == true) {
                return;
            }
         
            for ( var x = listBox.options.length - 2; x >= 0; x--) {
                if (listBox.options[x].selected == true) {
                    listBox.insertBefore(listBox.options[x + 1],
                                         listBox.options[x]);
                }
            }
         
            listBox.focus();
         
            buildOutputString(listBox, document.getElementById(idHidden));
        }
        }
 
    // initialize the string representations
    buildOutputString(document.getElementById('{!$Component.multiselectPanel}:leftList'),
                      document.getElementById('{!$Component.leftHidden}'));
    buildOutputString(document.getElementById('{!$Component.multiselectPanel}:rightList'),
                      document.getElementById('{!$Component.rightHidden}'));
    </script>
 
</apex:component>

Comments

Popular posts from this blog

Track Field History for more than 20 fields - Salesforce

All of us would have come across a situation when we need to track more than 20 fields for an object in salesforce. We have raised this Idea around 8 years ago in the success community. But sill it has't implemented by salesforce. But for now, we can achieve it partially with the following workaround. Approach: This approach uses a custom Text field which stores values of multiple other individual fields. Then enabling field history tracking of this field would allow you to track changes for multiple sets of other individual fields. Thus even though remaining within the count limit 20, yet track changes of more than 20 fields. Let us in this example take “Account ”  object and apply the steps to track change in Account Name, Phone, Parent Account and Billing Address all together. Steps: Step 1:  Add a new custom field. Setup -> Customize -> Accounts -> Fields Create a new Text (255) field “ Track FieldHistory ” (Or give any other n...

Customize the columns in the Items to Approve section on home page

We can customize the items to approve section with the help of custom visualforce page. All you need to do is create the below page with your object and respected fields to be displayed and then add the page to a new home page component. Page: <apex:page controller="itemstoApprovecontroller" sidebar="false" showHeader="false">     <apex:form >         <apex:pageBlock title="Incidents/Service Request To Approve">             <apex:pageBlockTable value="{!items_to_approve}" var="item_to_approve">                 <apex:column headerValue="Action" width="160 px" >                                     <apex:commandLink target="_top" value="Reassign |" action="{!REASSIGNnavigation}" style="text-decoration:none;color: #015ba7;" styleClass="cactionLink">   ...

Kanban view for Lightning

Tired of list views? Looking for a dynamic views to show your cases or opportunities in all new way? Here we go,  Salesforce introduced Kanban views for us to have better visibility  of our cases/opportunities and their journey from opening to closure. A case kanban allows you to visually summarize all of the cases for your agents,  by status or priority. It's not only a board, but also a  drag and drop  tool that will help agents keep their cases moving towards resolution. Similarly an opportunity Kanban display opportunities from a particular sales path Let's take a closer look at what all we can do with Kanban Track a Deal with Path Display opportunities by Sales path Move an Opportunity to the Next Stage Take Action on Your Records