function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Eager-2-LearnEager-2-Learn 

Using Datatable with an inner class

Hi,

I wrote some code to email a list of specific chatter groups that do not have full license users in the groups.  It works like a charm.  Then I wanted to get fancy and have the same list show on the visualforce page but what I thought would be a simple addition has had me spinning my wheels for over an hour now.  Any ideas would be appreciated.  Below is the error that I am receiving along with the VF page and the controller.

 

The error started when I added the datatable tag additon to the VF page and the getUsersChatterGroups method to the controller.  When I comment this line out in the VF page I can save the page and controller.  <apex:outputtext value="{!ug.ChatterGroupName}"/>

 

Please help!

 

Error

Error: Unknown property 'CFCT_UsersNotInChatterGroups_Controller.HelperClass.ChatterGroupName'

 

<apex:page Controller="CFCT_UsersNotInChatterGroups_Controller" action="{!startProcess}">
    <apex:pagemessages escape="false"/>
    <apex:dataTable value="{!UsersChatterGroups}" var="ug" id="theTable" rowClasses="odd,even" styleClass="tableClass">
        <apex:facet name="option">table option</apex:facet>
        <apex:facet name="header">table header</apex:facet>
        <apex:facet name="footer">table footer</apex:facet>
        <apex:column >
            <apex:facet name="header">Chatter Group</apex:facet>
            <apex:facet name="footer">column footer</apex:facet>
            <apex:outputtext value="{!ug.ChatterGroupName}"/>
        </apex:column>
    </apex:dataTable>
</apex:page>

 

public class CFCT_UsersNotInChatterGroups_Controller {

    private List<User> userList;
    private List<CollaborationGroupMember> chatterGroupList;
    private List<HelperClass> UsersMissingInChatterGroups = new List<HelperClass>();
   
    private Map<id, String> userMap = new Map<id, String>();
    private Map<id, String> ChatterGroupUserMap = new Map<id, String>();
    private String htmlBody = '<table border="1"><tr><th>Chatter Group</th><th>User Name</th></tr>';
    private String plainTextBody = ''; 
        
    public void startProcess() {
         // Get user Information
         userList = [ SELECT id, Name
                      FROM User
                      WHERE isActive = TRUE AND
                            User.Profile.UserLicense.Name = 'Salesforce' ]; 
                                            
        for ( User u : userList ) {
            userMap.put(u.id,u.Name);
        }

        // Build List of Full License Users that do not exist in each Chatter Group
        BuildList('Group1');
        BuildList('Group2');
        BuildList('Group3');
        BuildAndSendEmail();
      
        
        String msg = 'Please check your email inbox for the list of users that need to be added to Chatter Groups.';
        ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.CONFIRM, msg);  
        ApexPages.addMessage(myMsg);     
    }
    
    public List<HelperClass> getUsersChatterGroups() {
        return  UsersMissingInChatterGroups;
    }
    
    // Get Chatter Group List
    // Interate through the User List while building the UsersMissingChatterGroup list
    private void BuildList( String ChatterGroupName ) {           
        chatterGroupList = [ SELECT MemberId, collaborationGroup.Name 
                             FROM CollaborationGroupMember
                             WHERE collaborationGroup.Name = :ChatterGroupName                     
                             ORDER BY collaborationGroup.Name ];                             
        
        for ( CollaborationGroupMember cg : chatterGroupList ) {            
            ChatterGroupUserMap.put(cg.MemberId, cg.collaborationGroup.Name);
        }                
        
        for ( User u : userList) {
            if ( !chatterGroupUserMap.ContainsKey(u.Id) ) {                                                              
                HelperClass UserMissingInChatterGroup = new HelperClass();
                UserMissingInChatterGroup.UserName = u.Name;
                UserMissingInChatterGroup.ChatterGroupName = ChatterGroupName;
                UsersMissingInChatterGroups.add(UserMissingInChatterGroup);
            }            
        }         
    }  
    
    private void BuildAndSendEmail() {
        String priorCGN = '';
        for ( HelperClass hc : UsersMissingInChatterGroups ) {
            if ( priorCGN !='' && priorCGN !=hc.ChatterGroupName ) { 
                htmlBody += '<tr><td align="center">====================</td><td align="center">===========</td></tr>';
            }
            htmlBody += '<tr><td>' + hc.ChatterGroupName + '</td><td>' + hc.UserName + '</td></tr>';
            plainTextBody += hc.ChatterGroupName + '\t' + hc.UserName + '\n';
            priorCGN = hc.ChatterGroupName;
        } 
        htmlBody += '</table>';
        sendEmail();
    }      
    
    private void sendEmail() {
        User currentUser = new User();
        currentUser = QueryBase.getCurrentUser();
        List<String> toAddresses = new List<String> {currentUser.Email};
        String replyToAddress = currentUser.Email;        
        Utils.EmailUtil email = new Utils.EmailUtil(toAddresses);
        email.plainTextBody(plainTextBody);
        email.htmlBody(htmlBody);
        email.senderDisplayName(currentUser.Name);
        email.subject('Users Not In Chatter Groups');
        email.replyTo(replyToAddress);
        email.sendEmail();
    }    
    
           
    // Helper Class
    private class HelperClass {         
        public String UserName;
        public String ChatterGroupName;
    }
}

 

Best Answer chosen by Admin (Salesforce Developers) 
WaveOCWaveOC
Try to add {get; set;} next to your properties within the HelperClass - worked for me, example below: private class HelperClass { public String UserName {get; set;} public String ChatterGroupName {get; set;} }

All Answers

WaveOCWaveOC
I am not sure, but maybe the reason is that your HelperClass is "private".
Eager-2-LearnEager-2-Learn

I already tried making it public with no luck but just for giggles I tried it again and still the same error message.

 

I even tried to explicity reference it as ...

<apex:outputtext value="{!ug.HelperClass.ChatterGroupName}"/>

 

but still no luck.

WaveOCWaveOC
And is that possible that there is HelperClass.cls within current Org?
Eager-2-LearnEager-2-Learn

I changed the name of the inner class and all references to it to 'myInnerClass' and the same error message occured but referencing the new name 'myInnderClass'.

WaveOCWaveOC
When you go to "Your Name" --> "Setup" and then "Develop" --> "Apex Classes" you will see the list of classes that you have within your org, so maybe there is HelperClass already there - this may cause the issue
Eager-2-LearnEager-2-Learn

No ther is no class with that name.  Plus changing the name of the inner class like I did also did not work.

 

As long as I keep this one line of markup commented out the code works fine.  I get the email with the list that I need and the page shows the Succes message on but I just don't get my list on the page like I want.

 

 <!-- <apex:outputtext value="{!ug.ChatterGroupName}"/>  -->

 

 

Since this part of the markup does not cause a problem that tells me that the getUsersChatterGroups method works but for some reason it does not have the two properties  one which is in the commented market above.

 

<apex:dataTable value="{!UsersChatterGroups}" var="ug" id="theTable" rowClasses="odd,even" styleClass="tableClass">

 

Perhaps you can copy the code in your ORG and see what I am talking about.  You would have to change the hard coded chatter group names to your chatter groups.  Actaully commment out two of them and just use one.  May you can see first hand and it will jump out at you what the problem is.

 

Eager-2-LearnEager-2-Learn

I updated the getter as follows and turned on debug and I see the values so I just don't get why the VF page cannot see ChatterGroupName when I try to save the page!

 

 public List<HelperClass> getUsersChatterGroups() {
       
        for ( HelperClass hp : UsersMissingInChatterGroups ) {
            System.debug('zzz: ' + hp.ChatterGroupName);
        }
       
       
        return UsersMissingInChatterGroups;
    }

WaveOCWaveOC
Try to add {get; set;} next to your properties within the HelperClass - worked for me, example below: private class HelperClass { public String UserName {get; set;} public String ChatterGroupName {get; set;} }
This was selected as the best answer
Eager-2-LearnEager-2-Learn

Yes, that is exactly what I did but also had to make it public and the members.  Working great.  I would like to turn the chatter field into a link so that the user can hold the control key (windows standard funcitonality) and click the chatter name to get to the group quickly.

 

I am thinking that I need to use the commandlink component but I am not sure exactly how to do it.  I think I need to add a member to my helper class that holds the id of the chatter group.  If that is correct I am not sure how to make this works without hard coding the url which I know is bad practice.

 

Thanks for sticking in there with me on this. I appreciate very much.

WaveOCWaveOC
Yes, you need to add new property to your Helper Class to store Chatter Group Id (groupId is used in example below).
<apex:page Controller="CFCT_UsersNotInChatterGroups_Controller" action="{!startProcess}">
    <apex:pagemessages escape="false"/>
    <apex:dataTable value="{!UsersChatterGroups}" var="ug" id="theTable" rowClasses="odd,even" styleClass="tableClass">
        <apex:facet name="option">table option</apex:facet>
        <apex:facet name="header">table header</apex:facet>
        <apex:facet name="footer">table footer</apex:facet>
        <apex:column >
            <apex:facet name="header">Chatter Group</apex:facet>
            <apex:facet name="footer">column footer</apex:facet>
            <apex:outputLink value="/{!ug.groupId}">{!ug.ChatterGroupName}</apex:outputLink>
        </apex:column>
    </apex:dataTable>
</apex:page>

I think this should work.
WaveOCWaveOC
Problem solved?
Eager-2-LearnEager-2-Learn

Yes, I have it all working.  Thank you for assisting me and getting passed the hurtle.

 

I started this off as some quick code to just help us see what full license users are missing in Chatter Groups.  My next step is to make this work with a check box and an update button.  This way the admin can select the users they want to add (some times certain users may not be required to be in the group  so we need to allow the admin to select.  Click the button then the user is automatically added.

 

But this is a great start for now to identify the users.

 

Finally, I plan to write code that will have custom multi-picklist field on the user object and when the user is added then the admin can select the groups that are required for the new user to be in.  I figure this will require trigger code and a class that is called from the trigger.  NEXT CHAPTER.

 

Thanks again so much.