0

I have a page loaded from a button on a custom object to create an email. It renders the body and subject from an email template and displays the results for possible edit with a rich text field. I have two potential templates and I created radio buttons to select the appropriate template. If a different template is picked, I want to re-display the subject and body data for the selected template merged with the current data record. I coded everything to rerender the body section, but got the error cannot rerender a rich text object.

I was thinking a workaround would be to close the page and reload it. If the template is changed, the new template value is stored in the data record so it would be a simple matter to reload the page with the new template. My issue is that I cannot determine the correct method to close the current page from the controller and initiate the same page to reload on the same record. I've done quite a bit of VF recently, but some of the basic concepts still are not quite clear. Any help is appreciated.

Controller: public class AffEngpdfExtension { public ID callersId; private String transferUrl;

public String recipientEmail { get; set; }
public String ccEmail { get; set; }
public String bccEmail { get; set; }
public String subjectEmail { get; set; }
public String bodyEmail { get; set; }
public String templateBody { get; set; }
public String docName { get; set; }
public String TransferPage { get; set; }
public String targetObjectId { get; set; }
public String whatId { get; set; }
public String engagementId { get; set; }
public String ownerId { get; set; }
public String emailTemplateId { get; set; }
public String emailTemplateName { get; set; }
public Affiliate_Consulting_Engagement__c affEngage;

// Constructor
public AffEngpdfExtension(ApexPages.StandardController stdController) {

    //Set fields to be included in record retrieve
    stdController.addFields(new List<String>
        { 'Name', 'User_Email__c', 'Oversight_Email__c', 'Sales_Rep_Email__c', 'User_Contact__c', 
          'Consulting_Engagement__c', 'User__c', 'Email_Template_Id__c', 'Email_Template_Name__c'});

    affEngage = (Affiliate_Consulting_Engagement__c)stdController.getRecord();

    //Save values for email
    callersId = stdController.getRecord().id;
    this.recipientEmail = affEngage.User_Email__c;
    targetObjectId = affEngage.User_Contact__c;
    ccEmail = affEngage.Oversight_Email__c + ';' + affEngage.Sales_Rep_Email__c;
    List<Contact> senderEmail = 
        [SELECT Id, Email FROM Contact WHERE pse__Salesforce_User__c=:UserInfo.getUserId() LIMIT 1];
    bccEmail = senderEmail[0].Email;
    whatId = callersId;
    engagementId = affEngage.Consulting_Engagement__c;
    ownerId = affEngage.User__c;

    //Render body and subject from template
    emailTemplateId = affEngage.Email_Template_Id__c;
    emailTemplateName =affEngage.Email_Template_Name__c;
    if (String.isBlank(emailTemplateId) || String.isBlank(emailTemplateName)) {
        emailTemplateName = 'AffEngEmailReg';
        emailTemplateId = '';
    } 

    EmailTemplate templateId = [select Id, HTMLValue from EmailTemplate where developerName = :emailTemplateName];
    emailTemplateId = templateId.Id;

    Messaging.SingleEmailMessage email = 
        Messaging.renderStoredEmailTemplate(templateId.Id, affEngage.User_Contact__c, callersId);
    subjectEmail = email.getSubject();
    bodyEmail = email.getHTMLBody();

    //Fix <p> tags spacing issues
    bodyEmail = bodyEmail.replaceall('<p style="', '<p style="margin-top:0px; margin-bottom:0px;');
    bodyEmail = bodyEmail.replaceall('<p>', '<p style="margin-top:0px; margin-bottom:0px;>');
    templateBody = bodyEmail;

    //PDF document name
    docName = affEngage.Name + '-' + affEngage.Engagement_Code__c;
}

//Template radio button changed
public PageReference changeTemplate() {

    EmailTemplate ChangetemplateId = [select Id, HTMLValue from EmailTemplate where developerName = :emailTemplateName];
    emailTemplateId = changeTemplateId.Id;

    Messaging.SingleEmailMessage changeEmail = 
        Messaging.renderStoredEmailTemplate(changeTemplateId.Id, targetObjectId, callersId);
    subjectEmail = changeEmail.getSubject();
    bodyEmail = changeEmail.getHTMLBody();

    //Fix <p> tags spacing issues
    bodyEmail = bodyEmail.replaceall('<p style="', '<p style="margin-top:0px; margin-bottom:0px;');
    bodyEmail = bodyEmail.replaceall('<p>', '<p style="margin-top:0px; margin-bottom:0px;>');
    templateBody = bodyEmail;
    return null;
}

// Email content...
public PageReference emailPdf() {

    if(String.isBlank(this.TransferPage)) {
        ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 
           'Internal Error: missing TransferPage in pdfExtension'));
        return null; // early out
    }

    if(String.isBlank(this.subjectEmail)) {
        subjectEmail = docName;
    }

    String tempstr = this.bodyEmail;
    tempstr = tempstr.replaceall('[^\\W\\D]*','');
    if (String.isBlank(tempstr)) {
        bodyEmail = 'Document(s) attached for your review.';
    }

    transferUrl = '/apex/' + TransferPage + '?scontrolCaching=1&id=' + callersId;
    PageReference pdfPage = new PageReference(transferUrl);
    Blob reportPdf;
    try {
        reportPdf = pdfPage.getContentAsPDF();
    }
    catch (Exception e) {
        reportPdf = Blob.valueOf(e.getMessage());
    }

    // Create email  ---------------------------------
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();

    message.setTargetObjectId(targetObjectId);    //Contact id
    message.setWhatId(whatId);                    //Affiliage Engagement

    List<String> addresses = new List<String>();
    addresses.clear(); 

    if (!String.isBlank(this.ccEmail)) {
        addresses = this.ccEmail.split(';');
        message.setCcAddresses(addresses);
    } 
    addresses.clear();

    if (!String.isBlank(this.bccEmail)) {
        addresses = this.bccEmail.split(';');
        message.setBccAddresses(addresses);
    }
    addresses.clear();

    message.setSubject(subjectEmail);
    message.setHtmlBody(bodyEmail);

    // Attach PDF to email and send
    Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
    attachment.setContentType('application/pdf');
    attachment.setFileName(TransferPage + '_' + docName + '.pdf'); 
    attachment.setInline(false);
    attachment.setBody(reportPdf);
    message.setFileAttachments(new Messaging.EmailFileAttachment[]{ attachment });

    //Create activities on contact and Affiliate Engagement
    message.setSaveAsActivity(true);


    try {
        Messaging.SendEmailResult[] resultMail = 
            Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ message });

        resultMail[0].getErrors();

        //display success or error message
        if (resultMail[0].isSuccess()) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,
               'Email with PDF attachment sent to ' + this.recipientEmail + ' ' +
                                                      this.ccEmail + ' ' +
                                                      this.bccEmail));

            //Create email Activity for main Engagement also
            Task newTask = new Task();
            newTask.WhoId = targetObjectId;
            newTask.WhatId = engagementId;
            newTask.Subject = 'Email: ' + subjectEmail; 
            newTask.ActivityDate = date.Today(); 
            newTask.Status = 'Completed'; 
            newTask.Priority = 'Normal'; 
            newTask.OwnerId = ownerId; 
            newTask.IsReminderSet = false; 
            newTask.IsRecurrence = false; 
            newTask.TaskSubType = 'Email'; 
            insert newTask;            

            //Store Template ID and Name in Affiliate record
            affEngage.Email_Template_Id__c = emailTemplateId;
            affEngage.Email_Template_Name__c = emailTemplateName;
            update affEngage;

        } else {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
               'Email failed - ' + resultMail[0].getErrors().get(0).getMessage()));
        }

    } catch (System.EmailException ex) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,
               'Email exception caught - ' + ex.getMessage()));
    }
    return null;
}
}

VF page:

<apex:page sidebar="false" showHeader="false" tabStyle="Account" 
       standardController="Affiliate_Consulting_Engagement__c"
       extensions="AffEngpdfExtension"
       applyHtmlTag="false" applyBodyTag="false" >

<head>
    <style type="text/css">
        div#footer {text-align:center;position:fixed;bottom:0px;left:0px;width:100%;padding:8px;font-size:12px;color:Red;}
        body { font-family: 'Arial Unicode MS'; width: 900px; }
        a:link {text-decoration: none; color:Black; }
        .header { font-size: 20px; }
        .header2 { font-size: 18px; color:Black; }
        .sectionheader { font-size: 14px; font-weight: bold; text-decoration: underline; color: #0000CD; }
        .label { font-size: 13px;}
        .field { font-size: 13px; }
        .label2 { font-size: 12px; text-align: center; }
        .field2 { font-size: 12px; text-align: center; }
        .label3 { font-size: 12px; }
        .field3 { font-size: 12px; }
        .newpage { page-break-after:always }
    </style>
</head>  


<!-- generic markup for pdfExtension is in a form by itself... -->
<apex:form >
    <apex:pageBlock >
        <apex:pageMessages ></apex:pageMessages>

        <apex:pageBlockSection columns="1" >

            <apex:selectRadio value="{!emailTemplateName}" >
                <apex:selectOption itemValue="AffEngEmailReg" itemlabel="Simple"/>
                <apex:selectOption itemValue="AffEngEmailMM" itemlabel="Multi-Month"/>
                <apex:actionsupport event="onchange" action="{!changeTemplate}"/>
            </apex:selectRadio>

        </apex:pageBlockSection>

        <apex:pageBlockSection columns="1" >

            <apex:pageBlockSectionItem dataStyle="text-align:left;">
                <apex:commandLink action="{!emailPdf }" value="Email PDF" styleClass="btn" id="btnEmail">
                    <apex:param name="TransferPage"
                            assignTo="{!TransferPage}"
                               value="AffiliateEngagementPdf" />
                </apex:commandLink>
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem dataStyle="text-align:left;">
                <apex:outputLabel for="recipientEmail" value="To:"/> 
                <apex:outputText value="{!recipientEmail }"/>
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem dataStyle="text-align:left;">
                <apex:outputLabel for="ccEmail" value="cc: "/> 
                <apex:inputText value="{!ccEmail }" size="100"/>
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem dataStyle="text-align:left;">
                <apex:outputLabel for="recipientEmail" value="bcc:"/> 
                <apex:inputText value="{!bccEmail }" size="100"/>
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem dataStyle="text-align:left;">
                <apex:outputLabel for="subjectEmail" value="Email Subject (Optional)"/> 
                <apex:inputText value="{!subjectEmail }" size="100" />
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem dataStyle="text-align:left;" id="templateBody">
                <apex:outputLabel for="bodyEmail" value="Email Text (Optional)" /> 
                <apex:inputTextarea value="{!bodyEmail}" rows="20" cols="80" richText="true" style="line-height:normal;"/>
            </apex:pageBlockSectionItem>

        </apex:pageBlockSection>
    </apex:pageBlock>   

</apex:form>

<c:AffEngComponent Engage="{!Affiliate_Consulting_Engagement__c }" />
<c:AffEngPDFRelatedLists Engage="{!Affiliate_Consulting_Engagement__c }" />   

  • You could try using javascript to reload the entire page, or put the visualforce page in an iframe and reload that. Would help to see a code sample on how your page is currently organized. – battery.cord Jun 6 '18 at 20:24
  • I added the controller and vf page code – Jerry Welliver Jun 6 '18 at 20:35
2

Theoretically you should just need a refresh no? Commit the template value to your record, refresh the page, requery the record, and render the template. Get rid of the re-render altogether and it should treat as synchronous operation and do a full refresh.

public PageReference toggleTemplate() {
    if (record.template1__c) {
        record.template1__c = false;
        record.template2__c = true;
    } else {
        record.template1__c = true;
        record.template2__c = false;
    }

    //Setup reference to the page for redirect    
    PageReference newPage = new PageReference('/apex/Affiliate_Engagement?scontrolCaching=1&id=' + callersId);
    newPage.setRedirect(true);
    return newPage;
}

The page should do a refresh, you might need to return a null pagereference instead to trigger the refresh, can't remember or test right now.

  • That was my first thought, but I didn't know for sure how best to do it. I have been digging around and found redirect that seems to work. – Jerry Welliver Jun 6 '18 at 21:07

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.