1

This should be a simple change. I am modifying code from a previous developer so if there are any suggestions they are very welcome.

This is a simple button to call a VF page that will produce a pdf page for printing. Data for the page is pulled from the main record and child rows from another table. I added a new field to the parent it errors when I try to access it. It is a formula field pulling data from a related table. When that did not work, I attempted to add a select for the related table and pull the field that way. Now the select fails when I try to use the lookup id field from the parent. It is almost as if it is working from a select that does not include the fields which I have seen many times in Apex if I forget to add new fields to the select. In this case though, I thought the standard controller included all fields from the parent object. Please advise where I can make the extra fields available. I have been setting some fields to defaults so there may be some inconsistencies in the code. The data point I am trying to get is Type_of_EG_Certification__c.

Initial VF Page:

<apex:page sidebar="false" showHeader="false" tabStyle="Account" 
           standardController="Public_Seminar__c"
           extensions="HotelExtension"
           contentType="application/pdf" renderAs="PDF"
           applyHtmlTag="false" applyBodyTag="false" >

    <head>
        <style type="text/css">
                @page { size:landscape; margin:4px }
                body { font-family: 'Arial Unicode MS'}
                label { font-weight: normal; font-size: 14px; padding-left:4px; padding-top:2px}
                .newpage { page-break-after:always}
                .header { font-weight: normal; font-size: 14px; padding-left:6px; padding-top:2px}
                .header2 { font-weight: normal; font-size: 14px; padding-left:6px; padding-bottom:4px; padding-top:16px}
                .header2b { font-family: Helvetica; font-weight: bolder; font-size: 18px; padding-left:6px; padding-bottom:4px; padding-top:16px}
                .rosterheader { font-weight: bold; font-size: 14px; padding-left:6px; padding-top:8px}
                .field { font-weight: bold; font-size: 11px; padding-left:6px; padding-top:6px}
                .hiddenfield { visibility: hidden}
                .blankline { visibility: hidden; font-weight: bold; font-size: 11px; padding-top:12px}
        </style>
    </head>

    <c:RosterComponent course="{!Public_Seminar__c}" RenderPDF="true" CourseTPECS="true" />    

</apex:page>

VF Component:

<apex:component controller="RosterController">
    <apex:attribute name="CourseTPECS" type="Boolean" description="TODO: Describe me" required="true" />
    <apex:attribute name="course"
                    description="Course Object"
                    type="Public_Seminar__c"
                    required="true"
                    assignTo="{!ControlCourse}"/>
    <apex:attribute name="RenderPDF"
                    description="Render As PDF"
                    type="Boolean"
                    required="true"
                    assignTo="{!onlyIfPDF}"/>

    <apex:form >

        <apex:outputText styleClass="header2b" label="onlyIfPDF" value="{!onlyifPDF}" />
        <apex:outputText styleClass="header2b" label="CourseTPECS" value="{!CourseTPECS}" />

        <apex:outputText rendered="{!onlyIfPDF}" styleClass="hiddenfield" label="" value="{!course.Instructor_1__c}" />
        <apex:outputText rendered="false" styleClass="hiddenfield" label="" value="{!course.Hotel__c}" />

    <apex:pageBlock mode="maindetail" >
        <apex:pageBlockSection title="Oriel STAT A MATRIX-Course Sign-in" columns="1" >
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header2" label="" value="Email roster back 1st day of training to: [email protected]" />
            <apex:outputText rendered="{!onlyIfPDF}" styleClass="blankline" label="" value="hidden field" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header" label="Course Title" value="{!course.Course_Title__c}" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header" label="Course Start Date" value="{!course.Course_Start_Date__c}" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header" label="Instructor" value="{!InstructorName}" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header" label="Location" value="{!course.Location__c}" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header" label="Session Code" value="{!course.Session_Code__c}" />
            <apex:outputText rendered="{!onlyIfPDF}" styleClass="blankline" label="" value="hidden field" />
            <apex:outputText rendered="{!onlyifPDF}" styleClass="header2" label="" value="Please sign in with your initials next to your name and take a moment to confirm your personal information." />


            <apex:pageBlockTable var="item" width="100%" value="{!Attendees}" headerClass="rosterheader">
                <apex:column headerClass="header" styleClass="field" width="15%" headerValue="Name" value="{!item.Name}" />
                <apex:column headerClass="header" styleClass="field" width="5%" headerValue="Initial Here">________</apex:column>
                <apex:column headerClass="header" styleClass="field" width="15%" headerValue="Company" value="{!item.Company_Organization__c }" />
                <apex:column headerClass="header" styleClass="field" width="20%" headerValue="Title" value="{!item.Title__c }" />
                <apex:column headerClass="header" styleClass="field" width="20%" headerValue="Email Address" value="{!item.Email_Address__c }" />
                <apex:column headerClass="header" styleClass="field" width="8%" headerValue="Phone" value="{!item.Attendee_Phone__c }" />
                <apex:column rendered="{!onlyIfPDF}" headerClass="header" styleClass="field" width="8%" headerValue="Stay at Hotel? (Y/-)">______</apex:column>
            </apex:pageBlockTable>

        </apex:pageBlockSection>

    </apex:pageBlock>

    </apex:form>

</apex:component>

Controller:
This is where I get the error at line 34 attempting to get the Course__c object into mainCourse. The error states controlCourse.Course_Code__c is not available. enter image description here

public with sharing class RosterController {
    public Public_Seminar__c controlCourse;
    public Boolean onlyIfHTML;
    public Boolean courseTPECS;
    public Boolean onlyIfPDF;
    private Hotel__c hotel;
    private Public_Attendee__c attendee;
    private Contact instructor;
    private Course__c mainCourse;

    public ApexPages.StandardSetController setCon {
        get {
            if (setCon == null) {
                setCon = new ApexPages.StandardSetController(Database.getQueryLocator(                    
                    [SELECT Name, Title__c, Payment_Status__c, Company_Organization__c, Attendee_Phone__c, Email_Address__c
                     FROM Public_Attendee__c 
                     WHERE Public_Course__c = :controlCourse.Id AND Payment_Status__c IN ('Paid', 'Payment Pending')]));
            }
            return setCon;
        }
        set;
    }

    public void setControlCourse(Public_Seminar__c arg_course) {
        controlCourse = arg_course;

        hotel = [SELECT Name, Name__c, Street__c, City__c, State__c, PostalCode__c,
                 Phone__c, Continental_Included__c, WiFi_Included__c, Projector_Provided__c,
                 Screen_Provided__c, Power_Cord_Provided__c, Flip_Pads_Provided__c
                 FROM Hotel__c WHERE Id = :controlCourse.Hotel__c];

        instructor = [SELECT Name FROM Contact WHERE Id = :controlCourse.Instructor_1__c];

        mainCourse = [SELECT Type_of_EG_Certification__c FROM Course__c WHERE Id = :controlCourse.Course_Code__c];
    }

    public Public_Seminar__c getControlCourse() {
        return controlCourse;
    }

    public Boolean getonlyIfHTML() {
        return onlyIfHTML;
    }

    public void setonlyIfHTML(Boolean arg) {
        if (arg == true) {
          onlyIfPDF = false;
          onlyIfHTML = true;
        }
        else {
          onlyIfPDF = true;
          onlyIfHTML = false;
        }
        return;
    }

    public Boolean getonlyIfPDF() {
        return onlyIfPDF;
    }

    public void setonlyIfPDF(Boolean arg) {
        if (arg == true) {
          onlyIfPDF = true;
          onlyIfHTML = false;
        }
        else {
          onlyIfPDF = false;
          onlyIfHTML = true;
        }
        return;
    }

    public Boolean getcourseTPECS() {
        return mainCourse.Type_of_EG_Certification__c == 'TPECS';
    }

    public Hotel__c getHotelObject() {
        return hotel;
    }

    public List<Public_Attendee__c> getAttendees() {
        return (List<Public_Attendee__c>) setCon.getRecords();
    }

    public String getHotelName() {
        return hotel.Name__c;
    }

    public String getHotelStreet() {
        return hotel.Street__c;
    }

    public String getHotelContact() {
        return hotel.Street__c;
    }

    public String getHotelCityStateZip() {
        if (hotel.PostalCode__c != null) {
            return hotel.City__c + ', ' + hotel.State__c + hotel.PostalCode__c;
        }
        else {
            return hotel.City__c + ', ' + hotel.State__c;
        }
    }

    public String getHotelPhone() {
        return hotel.Phone__c;
    }

    public String getHotelContIncl() {
        if (hotel.Continental_Included__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getHotelWiFiIncl() {
        if (hotel.WiFi_Included__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getHotelProjBy() {
        if (hotel.Projector_Provided__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getHotelScreenBy() {
        if (hotel.Screen_Provided__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getHotelCordBy() {
        if (hotel.Power_Cord_Provided__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getHotelFlipBy() {
        if (hotel.Flip_Pads_Provided__c) {
            return 'Yes';
        }
        else {
            return 'No';
        }
    }

    public String getInstructorName() {
        return instructor.Name;
    }
}

Thanks for the detailed answer. I made the changes and that error was cleared, but I am still having problems getting the true/false value into the component.

Controller changes:

mainCourse = [SELECT Type_of_EG_Certification__c FROM Course__c 
                WHERE Id IN (SELECT Course_Code__c FROM Public_Seminar__c WHERE Id = :controlCourse.Id)]; 

public Boolean getcourseTPECS() {
    if (mainCourse.Type_of_EG_Certification__c == 'TPECS')
        return true;
    else
        return false;
}

New component call gets error - Error: Unknown property 'Public_Seminar__cStandardController.CourseTPCES' on save:

<c:RosterComponent course="{!Public_Seminar__c}" RenderPDF="true" isTPECS="{!CourseTPCES}" />    

Attribute in component:

<apex:attribute name="isTPECS" 
                type="Boolean" 
                description="Is TPECS course?" 
                required="true" />

What is causing the error in the VFP component call? I am using the same technique as InstructorName. What am I missing?

One other question I have, is it necessary to use the assignTo or can I just use the name of the attribute in the body of the component. If it is required, then it must be defined in the controller?

1 Answer 1

3

The standard controller for Public_Seminar__c on your containing page, which is responsible for querying the record that you assignTo="{!ControlCourse}" to pass into the Visualforce component, doesn't "know" that you have a dependency on the field Course_Code__c.

Standard controllers only pull those fields that they need to render the page, or that they're explicitly asked to pull via addFields().

In this case, I think the easiest fix for you is just to use a semi-join:

mainCourse = [
    SELECT Type_of_EG_Certification__c 
    FROM Course__c 
    WHERE Id IN (SELECT Course_Code__c 
                 FROM Public_Seminar__c 
                 WHERE Id = :controlCourse.Id)
]; 

Then you remove any dependency on the part of your component on how the parent page queries its record.

4
  • Please see the addition to the question, I ran into another problem. Mar 16, 2019 at 18:35
  • @JerryWelliver That might be worthy of its own post, but the short answer is that you can't reference a property in the component controller in your main page like that.
    – David Reed
    Mar 16, 2019 at 20:14
  • Thanks for answering. I need to the Boolean courseTPECS in the component so I can use it in the render clause to determine the proper text to display. How can I address the property in the component? Mar 16, 2019 at 20:23
  • @JerryWelliver Your component's custom controller should query the relevant fields and generate the property inside the component.
    – David Reed
    Mar 17, 2019 at 23:26

You must log in to answer this question.

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