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; }
    – Adrian Larson
    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 .
    – cropredy
    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
    – cropredy
    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.

Not the answer you're looking for? Browse other questions tagged .