1

I have a custom visualforce component with a controller, it takes an attribute of an Id of a related record, and in the controller I query for the set of objects I want to display.

When I attempt to dereference this list inside an <apex:repeat /> tag I get some strange behavior. Am I totally missing something?

Controller:

public without sharing class VIPCommissionProgramAtSitesController {
    public Id accreditationStandardId {get; set {
            accreditationStandardId = value;
            linkedServiceStandardLocations =  [SELECT Id, Program_At_Site__r.Program__r.Name, Program_At_Site__r.Site__r.Name,
                Service_Standard__r.Service_Standard__c, Accreditation_Standard__c, Program_At_Site__c
                FROM Linked_Service_Standard_Location__c WHERE Accreditation_Standard__c = :accreditationStandardId];

                System.debug(LoggingLevel.WARN,'Selecting LSSL: '+linkedServiceStandardLocations.size());
            }   
        }

    public List<Linked_Service_Standard_Location__c> linkedServiceStandardLocations {get; private set; }

        // The service standard locations to which this AC_Standard__c IS linked

    public Map<Id, Boolean> appliesToLinkedServiceStandardLocation {get {
                Map<Id, Boolean> retVal  = new Map<Id, Boolean>();
                for (Linked_Service_Standard_Location__c lssl : linkedServiceStandardLocations) {
                    retVal.put(lssl.id, false);
                }
                return retVal;
            } set;
     }
}

Component:

<apex:component controller="SitesController" allowDml="true">
    <apex:attribute name="stdid" type="String" required="true" assignTo="{!standardId}" description="description" />

             <apex:repeat value="{!locations}" var="lssl">
                <apex:outputText value="{!lssl.Id}" />
             </apex:repeat>
</component>

The output repeat is empty?

However, when I output some text inside of the repeat I get repeated statements:

     <apex:component controller="VIPCommissionProgramAtSitesController" allowDml="true">
    <apex:attribute name="acStandardId" type="Id" assignTo="{!accreditationStandardId}" description="id of the accreditation cycle to render linked program at sites for" />
    <apex:attribute name="accreditationStandardTitle" type="String" description="description" />
    <div class="modal-content" id="{!accreditationStandardId}-modal">
        <div class="modal-header">
            <h1>{!accreditationStandardTitle}</h1>
        </div>
        <div style="min-height:500px; margin-top:45px;">
            <div>
                <h3>Please provide a <strong>Site Visit Justification</strong> for this rating.</h3>
            </div>
            <div class="coa-tabs-wrapper">
                <ul class="coa-tabs">
                    <li class="coa-tab coa-modal-tab active">
                        <a href="#view-by-programs-{!accreditationStandardId}">View by Programs</a>
                    </li>
                    <li class="coa-tab coa-modal-tab">
                        <a href="#view-by-sites-{!accreditationStandardId}">View by Sites</a>
                    </li>
                </ul>
                <div class="coa-tabs-pane-wrapper">
                    <div id="view-by-programs-{!accreditationStandardId}" class="coa-tabs-pane active">
                    {!accreditationStandardId}
                    {!appliesToLinkedServiceStandardLocation}
                        <apex:repeat value="{!linkedServiceStandardLocations}" var="lssl">
                            <apex:outputText value="{!lssl.Id}" />
                        </apex:dataTable>
                    </div>
                    <div id="view-by-sites-{!accreditationStandardId}" class="coa-tabs-pane">
                    </div>
                </div>
            </div>
        </div>
        <div class="modal-footer" style="height: auto; padding: 20px 0;">
        </div>
    </div>
</apex:component>

I've checked field accessibility on all of these fields, and the object, no problem there.

Update, I've posted a complete version of my controller / component as this is really confounding me!

In the debug log, I've confirmed that linkedServiceStandardLocations does infact return 7 results, and also by outputting the 'Map' of the list, appliesToLinkedServiceStandardLocation, shows 7 text values. However, when I attempt to do:

{!linkedServiceStandardLocations} anywhere on the component, the whole page crashes.

7
  • What if you move the logic to the standardId setter? I've had better luck with that approach. public String standardId { get; set { locations = /*query*/; standardId = value; } public List<MyObject__c> records { get; private set; } Commented May 26, 2016 at 1:56
  • @Adrian Larson will give it a shot. So weird that when I return it as a map of objects by I get the weird string the data is correct but VF merge fields don't work!? When I return it as a list I can't get merge fields to work and attempting to just render the list redirect the whole page crashes! Commented May 26, 2016 at 2:06
  • 2
    Jordan (1) attribute Type can be ID, not String although that isn't the cause of the issue here. (2) Since this is a Sites controller, then I would surmise that the site's guest user doesn't have visibility to the custom object's ID field . Commented May 26, 2016 at 3:48
  • @cropredy, not sure if you're referring to a Community user profile, but the user is authenticated - but I can see the entire record in the debug log, just not in VF? Commented May 26, 2016 at 20:37
  • @Adrian Larson, see my update above, I attempted this, and it didn't change the behavior Commented May 26, 2016 at 20:37

2 Answers 2

1

Jordan

At first I thought this was a Sites VF page, based on your controller class name

If Sites, then user access is determined by the permissions of the site's guest user profile - which is accessed from Setup | Develop | Sites | Public Access Settings.

If a Community User page, then the running user needs access to the field as well as read access to the relevant Sobject(s) Linked_Service_Standard_Location__c in your case.

You were right to think this was a permissions problem, especially if you could see it in the debug log.

Last bit: The reason you could see the values in the debug log is because, as sysad, you can see anything in debug log irrespective of the running user's permissions.

1
  • I was actually running as the authenticated user in the Community. As a weird quirk of (Salesforce Communities at least), even if a user doesn't have access to a relevant sobject if you dereference the fields in a wrapper class you can display them on a VF page. Sobject security kicks in at the VF level, and loses context if you wrap inside of a wrapper. Can't use "inputfield" though Commented May 27, 2016 at 1:37
0

You can add a vf landing page in order to make the component working. Say let's repeat all contact records with one account, your code works fine. Check the code below, I created a new vf page for the component and passed an accountId to stdid:

<apex:page >
  <c:SitesControllerComponent stdid="0012800000ApdWD"/>
</apex:page>

Other I have noticed in your component, the display is not good. Since you just repeat locations, then output all records by <apex:outputText>. So all your locations will just print out side by side, not easy to read.If you like to inherit the standard look from SFDC, warp <apex:repeat> inside of <apex:pageBlockSection> will do the trick.

2
  • I think OP omitted for clarity how the custom component was invoked from the base VF page Commented May 26, 2016 at 3:46
  • I haven't styled anything yet (I just wanted to check the values in the merge fields before I organized and styled things). But when I attempt to output the list the entire page crashes. I understand that this will show an array / object text string. Commented May 26, 2016 at 20:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.