Thursday, January 29, 2009

How can the controller read the page?

Let's suppose you have a page (or part of a page) that you want to send via email. How can you get the contents of the page in the controller?

Since the contents of the page cannot be obtained by the controller, why not let the page send its contents to the controller?

VisualForce page:

<apex:page controller="MyEmail">
    <div ID="renderedPage">
        ... Put here the HTML content you want to get (it could be the entire page) ...
    </div>
    <apex:form >
        <apex:actionFunction name="setApexHTML" action="{!sendEmail}" rerender="AJAXSection">
            <apex:param name="strHTML" value="" />
        </apex:actionFunction>
    </apex:form>
    <apex:outputPanel id="AJAXSection"></apex:outputPanel>
    <script language="javascript">
        function getJSHTMLData() {
            var divPage = element = document.getElementById('renderedPage');
            var strHTML = divPage.innerHTML;
            setApexHTML(strHTML);
        }

        // Execute on load
        var previousOnload = window.onload;
        window.onload = function() {
            if (previousOnload) {
                previousOnload();
            }
            getJSHTMLData();
            alert('Email sent');
        }
    </script>
</apex:page>
Controller:
public class MyEmail {
    public void sendEmail() {
        List<String> emailAddress;
        String htmlContent = ApexPages.currentPage().getParameters().get('strHTML');

        // Send email
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        // To
        emailAddress = new List<String>();
        emailAddress.add('user@acme.com');
        mail.setToAddresses(emailAddress);

        // Cc
        emailAddress = new List<String>();
        emailAddress.add('smith@gmail.com');
        mail.setCcAddresses(emailAddress);

        // Reply to
        mail.setReplyTo('support@acme.com');
        mail.setSenderDisplayName('Acme Support');

        // Bcc
        mail.setBccSender(true); // Set to True if you want to BCC yourself on the email.

        // Contents
        mail.setSubject('You have mail!');
        mail.setHtmlBody(htmlContent);
        mail.setUseSignature(false);

        // Send email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}
How does this code works?
  1. When the VisualForce page loads, part of the JavaScript code (lines 19-25) gets executed.
  2. This calls the getJSHTMLData() method (lines 12-16) which
    1. Gets the contents of the <DIV> (lines 2-4)
    2. Calls the setApexHTML(strHTML) method with that information
  3. The setApexHTML(strHTML) method (lines 6-8) sends the data in the strHTML parameter to the SendEmail() method in the controller.
  4. The SendEmail() method
    1. Gets the data from the parameter (line 4)
    2. Creates and sends the email (line 6-32).
Althogh this code calls the Javascript when it loads, it could easily be changed to have the method called by JavaScript when an event happens (for example the onClick event of a HTML button)

No comments:

Post a Comment