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 }" />   

2
  • 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. Commented Jun 6, 2018 at 20:24
  • I added the controller and vf page code Commented Jun 6, 2018 at 20:35

1 Answer 1

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.

1
  • 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. Commented Jun 6, 2018 at 21:07

You must log in to answer this question.

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