1

I have a wrapper class inside of a map that I want to display on a VFP. The output value of the map is:

{2017-07-13 16:28:02=CaseInfo:[caseNumber=00033490, taskData=Task:{WhatId=500S0000008l5A3IAI, Id=00TS000000Ul9poMAB, CreatedDate=2017-07-13 16:28:02, Comments__c=Olivia Test Case Portfolio Record Type SENT, OwnerId=00534000009QnEtAAK, Subject=Email: Olivia Test Case Portfolio Record Type SENT, AccountId=001S000000raQdyIAE, CreatedById=00534000009QnEtAAK, RecordTypeId=01280000000BawwAAC}], 
2017-07-13 16:28:30=CaseInfo:[caseNumber=00033490, taskData=Task:{WhatId=500S0000008l5A3IAI, Id=00TS000000Ul9puMAB, CreatedDate=2017-07-13 16:28:30, Comments__c=RESPONSE, OwnerId=00580000003HZZnAAO, Subject=RE: Sandbox: Olivia Test Case Portfolio Record Type RESPONSE, CreatedById=00580000003HZZnAAO, RecordTypeId=01280000000BawwAAC}], 
2017-07-17 18:57:22=CaseInfo:[caseNumber=00033494, taskData=Task:{WhatId=500S0000008lPkSIAU, Id=00TS000000UlRjlMAF, CreatedDate=2017-07-17 18:57:22, Comments__c=TEST COMMENTS From: Olivia Porter, OwnerId=00534000009ceS2AAI, Subject=RE: Sandbox: Wire In -, CreatedById=00534000009ceS2AAI}]}`

I want to pull out the key, the caseNumber, and the Task Subject. I am able to pull out the key and the caseNumber but unable to delve further into the map. How would I go about doing something like this?

<apex:repeat value="{!caseTaskMap}" var="taskTime">
    <th colspan="5" id="casenumber">{!taskTime}</th> <!--displays the key-->
    <apex:repeat value="{!caseTaskMap[taskTime]}" var="caseInfo"> <!--displays the whole CaseInfo value-->
        <apex:repeat value="{!caseTaskMap[taskTime[caseInfo]]}" var="taskData"><!--does not work-->
            <apex:repeat value="{!caseTaskMap[taskTime[caseInfo[taskData]]]}" var="task"><!--does not work-->
                <tr>
                    <td>{!taskData.CaseNumber}</td>
                    <td>{!task.Subject}</td>
                </tr>
            </apex:repeat>
        </apex:repeat>
    </apex:repeat>
</apex:repeat>

For ease of viewing, I hope the returned value is enough to understand the question. If not, I can add the wrapper class and map in.

UPDATE: Wrapper

class CaseInfo {
    public String caseNumber {get;set;}
    public Task taskData {get;set;}

    CaseInfo(String caseNumber, Task taskData) {
        this.caseNumber = caseNumber;
        this.taskData = taskData;
    }
}

public viewAllCaseCommentsActivitiesController() {
    ....
    orderedTaskList1 = [SELECT (SELECT CreatedDate, Comments__c, OwnerId, Subject, Owner.Name, AccountId, WhatId, CreatedById, Account.Name FROM Tasks WHERE Private__c = FALSE AND (Status = 'Completed' OR Status = 'Closed')
                            ORDER BY CreatedDate DESC), AccountId, CaseNumber, Merchant_Number__c FROM Case WHERE AccountId = :strAccountId AND Id IN :accountIds];
    caseTaskMap = new Map<String, CaseInfo>();
        for(Case c : orderedTaskList1){
            for (Task t : c.Tasks) {
                caseTaskMap.put(''+t.CreatedDate, new CaseInfo(c.CaseNumber,t));
            }
        }
}
  • You should include the actual wrapper definition. – Adrian Larson Jul 25 '17 at 17:25
  • @AdrianLarson added – Olivia Jul 25 '17 at 17:33
5

Use in the repeat

caseInfo.CaseNumber

Since caseInfo is akin to the loop variable in a for loop and each instance would be a wrapper record

When using the repeats think of each one as a for loop. Maps are accessed using [keys] and values are accessed using dot notation. The var is the loop variable

Working example:

Controller

public class myControllerExample{


    public Map<String,caseInfo> caseTaskMap {get;set;}

    public myControllerExample(){
        caseTaskMap = New Map<String,caseInfo>{
            string.valueOf(system.now().addDays(-3)) => New caseInfo('12345'),
            string.valueOf(system.now().addDays(-2)) => New caseInfo('123456'),
            string.valueOf(system.now().addDays(-1)) => New caseInfo('123457')
        };
    }

    public class caseInfo{

        public Task taskData {get;set;}
        public String caseNumber {get;set;}

        public caseInfo(String caseNumber){
            this.caseNumber = caseNumber;
            taskData = New task(Subject = 'Test Subject for: ' + caseNumber);
        }

    }



}

Page

<apex:page controller="myControllerExample">

<div>
    <table>
        <apex:repeat value="{!caseTaskMap}" var="taskTimeKeys">
                <apex:repeat value="{!caseTaskMap[taskTimeKeys]}" var="caseInfoRows"><!--does not work-->
                        <tr>
                            <td>{!caseInfoRows.CaseNumber}</td>
                            <td>{!caseInfoRows.taskData.Subject}</td>
                        </tr>
                </apex:repeat>
        </apex:repeat>
    </table>
</div>
</apex:page>

enter image description here

Map values:

{
 2017-07-22 13:39:12=caseInfo:[caseNumber=12345, 
     taskData=Task:{Subject=Test Subject for: 12345}], 
 2017-07-23 13:39:12=caseInfo:[caseNumber=123456, 
     taskData=Task:{Subject=Test Subject for: 123456}], 
 2017-07-24 13:39:12=caseInfo:[caseNumber=123457, 
     taskData=Task:{Subject=Test Subject for: 123457}]
}
  • I tried that earlier, unfortunately I get an error message Unknown property 'viewAllCaseCommentsActivitiesController.CaseInfo.CaseNumber' Error is in expression '{!caseInfo.CaseNumber}' in component <apex:repeat> in page viewallcasecommentsactivities. This made me think that perhaps it wasn't possible to move down more layers or that the 'CaseInfo' wasn't being read as a key – Olivia Jul 25 '17 at 17:18
  • @Olivia - Ok. give me a few minutes and I will get you a working example – Eric Jul 25 '17 at 17:21
  • @Olivia Did you expose that variable as a property? You need to define a getter/setter e.g. public String CaseNumber { get; private set; } – Adrian Larson Jul 25 '17 at 17:24
  • @AdrianLarson I did add it and I still get no response. – Olivia Jul 25 '17 at 17:35
  • @Olivia - Updated with example and removed the unnecessary repeats – Eric Jul 25 '17 at 17:43
0

An alternative to

<tr>
<td>{!caseInfoRows.CaseNumber}</td>
<td>{!caseInfoRows.taskData.Subject}</td>
</tr>

that uses standard Visualforce components is

<apex:outputText value="{!caseInfoRows.CaseNumber} /> -- <nbsp/>
<apex:outputText value="{!caseInfoRows.taskData.Subject} /><br/>
  • Could you perhaps edit your post to clarify why this change would be an improvement? – Adrian Larson Feb 1 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.