Thursday, December 27, 2012

Add Email Button Hidden Issue Outlook Integration:

Add Email Button Hidden Issue Outlook Integration:
After installing Salesforce for Outlook (SFO), the “Add Email” and “Send and/or Add Email” buttons are not visible in Outlook

Possible Causes and Resolutions:
Make sure ‘Email to Salesforce’ is enabled and also ‘Add Email’ feature is enabled in the Outlook configuration that you have been assigned to.

To enable “Email to Salesforce”:
*Requires System Administrator permission
In Salesforce, click Your Name | Setup | Administration setup | Email Administration | Email to Salesforce and make sure the ‘Active’ box is checked

To enable ‘Add Email’ for each user:
In Salesforce, click Your Name | Setup | Administration setup | Desktop Administration | Outlook Configurations, Edit your Outlook Configuration and make sure the ‘Add Email’ box is checked under  “Email Settings”
Check if Salesforce for Outlook is running in System Tray. The ‘Add Email’ button will never display if Salesforce for Outlook is not running in system Tray. Salesforce for Outlook runs only from the system tray and does not have a menu item in Outlook unlike the “Connect for Outlook”
If ‘Email to Salesforce’ and ‘Add Email’ are both enabled in Salesforce and you do not see the ‘Add Email’ or ‘Send and Add Email’ buttons in Outlook, it is possible that either they are disabled by Outlook or the installation failed due to security software or the user who installed the application did not have local administrator permission on the computer.
Outlook 2007: Help | Disabled Items…
Outlook 2007: Tools | Trust Center | Add-ins | Manage - COM Add-ins | Enable Salesforce for Outlook
Outlook 2010: File | Options | Add-ins
Under ‘Manage’ drop down select “Disabled Items” and click on the ‘Go…” button
  • If Salesforce for Outlook is in the disabled item list, select it and click on Enable
  • You need to restart Outlook and Salesforce for Outlook
If the issue persist, and Salesforce for Outlook is listed as Active Application Addins in the Outlook Trust Center,  please check the following settings and make the necessary changes:

For Windows 7:
  1. Click on Start/Control Panel/ User Account / User Accounts
  2. Select Change User Account Control Settings
  3. Make sure to change it to "Never Notify"
  4. Restart the computer
  5. Once it is restore: Restart Outlook and Salesforce for Outlook and attempt to sync again.

For Windows Vista:
  1. Launch MSCONFIG by from the Run menu.
  2. Click on the Tools tab. Scroll down till you find "Disable UAC" . Click on that line
  3. Press the Launch button
  4. A CMD window will open. When the command is done, you can close the window.
  5. Close MSCONFIG. You need to reboot the computer for changes to apply.
If Salesforce for Outlook is running, make sure that you have synced with Salesforce.com using Salesforce for Outlook. The add-in will get its configuration after Salesforce for Outlook finishes sync and ‘Add Email’ button will load in Outlook.If you have recently made any changes to your configuration, you must sync using Salesforce for Outlook for add-in to pickup latest configurations. You can do this by manually initiating Sync or by waiting for Auto Sync to initiate sync to get latest configurations. To sync manually: Right click on the Salesforce for Outlook system tray icon in the taskbar in the right bottom corner of the screen and click on sync and sync now
If none of the steps resolved your issue, please see
  1. How to delete Salesforce for outlook sync database
  2. Salesforce for Outlook Add Email button issues

Add an email button can disappear and will not load if user's PC profile is corrupted.
To solve this problem recreate the user's local profile. To do this, log in as an administrator, and change the name of the user's profile folder (c:\users\ and locate the folder with the user's folder. Change the name to nameOLD or something). Then have the user log back into the pc and try run the plugin.

Future Annotation:

Future Annotation:

Use the future annotation to identify methods that are executed asynchronously. When you specify future, the method executes when Salesforce has available resources.
For example, you can use the future annotation when making an asynchronous Web service callout to an external service. Without the annotation, the Web service callout is made from the same thread that is executing the Apex code, and no additional processing can occur until the callout is complete (synchronous processing).
Methods with the future annotation must be static methods, and can only return a void type.
public with sharing class DF12FutureController {

    public Contact customer {
        get {
            return [
                SELECT Id, FirstName, LastName, Email
                FROM Contact
                WHERE Id = :ApexPages.currentPage().getParameters().get('id')
                LIMIT 1
            ];
        }
        private set;
    }

    public PageReference createSampleContactIfNecessary() {
        if (ApexPages.currentPage().getParameters().get('id') == null) {
            Contact c = new Contact();
            User currentUser = [
                SELECT Id, FirstName, LastName, Email
                FROM User
                WHERE Id = :UserInfo.getUserId()
            ];
            List<Contact> cList = [
                SELECT Id, FirstName, LastName, Email
                FROM Contact
                WHERE Email = :currentUser.Email
            ];
            if (cList != null && cList.size() > 0) {
                c = cList[0];
            } else {
                c.FirstName = currentUser.FirstName;
                c.LastName = currentUser.LastName;
                c.Email = currentUser.Email;
                insert c;
            }
            PageReference pr = ApexPages.currentPage().setRedirect(true);
            pr.getParameters().put('id', c.id);
            return pr;
        }
        return null;
    }

    @RemoteAction
    public static String requestAllInvoices(String customerId) {
        sendAllInvoices(customerId);
        return 'All invoices have been requested.';
    }

    @future
    private static void sendAllInvoices(String customerId) {
        EmailHelper.emailCustomerInvoices(customerId);
    }

    @isTest
    private static void testCreateSampleContactIfNecessary() {
        DF12FutureController con = new DF12FutureController();
        PageReference pr = Page.DF12Future;
        Test.setCurrentPageReference(pr);
        con.createSampleContactIfNecessary();
        System.assertEquals(1, ApexPages.currentPage().getParameters().size(), 'Page should have the id param.');
    }

    @isTest
    private static void testRequestAllInvoices() {
        Contact c = new Contact(LastName = 'Smith', FirstName = 'Joe', Email = 'test@test.test.test.test');
        insert c;
        String response = DF12FutureController.requestAllInvoices(c.id);
        System.assertEquals('All invoices have been requested.', response, 'The wrong response was returned.');
    }

    @isTest
    private static void testGetCustomer() {
        DF12FutureController con = new DF12FutureController();
        PageReference pr = Page.DF12Future;
        Test.setCurrentPageReference(pr);
        con.createSampleContactIfNecessary();
        System.assertEquals(con.customer.Id, ApexPages.currentPage().getParameters().get('id'), 'Customer retrieved was not correct.');
    }

}
<apex:page docType="html-5.0" controller="DF12FutureController" action="{!createSampleContactIfNecessary}" showHeader="false" standardStylesheets="false">
<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: @future Example</apex:define>

    <apex:define name="header">
        <h1 class="pageTitle">@future Example</h1>
    </apex:define>

    <apex:define name="body">
        <p>A sample contact has been created with the following information:</p>
        <dl>
            <dt>Contact Id:</dt>
            <dd>{!customer.Id}</dd>
            <dt>Contact First Name:</dt>
            <dd>{!customer.FirstName}</dd>
            <dt>Contact Last Name:</dt>
            <dd>{!customer.LastName}</dd>
            <dt>Contact Email:</dt>
            <dd>{!customer.Email}</dd>
        </dl>
        <p>To see the @future method in action, click the button below. (This will send a sample email to the contact above.)</p>
        <button type="button" onclick="DF12Examples.requestInvoices('{!customer.Id}');">Request Invoices</button>
        <div class="pageMask" id="pageMask"></div>
        <div class="pageWait" id="pageWait">working...</div>
    </apex:define>

    <apex:define name="pageScripts">
        <script>

            // startTime and endTime are only being created for logging purposes, but
            // note that I am initializing their values to Date objects. this is so
            // JavaScript doesn't have to guess what kind of variables they are
            // (and therefore, doesn't have to change their datatype mid-execution).
            // this is a best practice for all JS variable declarations to help with
            // performance.
            DF12Examples.startTime = new Date();
            DF12Examples.endTime = new Date();

            // this is the function that gets called when the button is clicked.
            DF12Examples.requestInvoices = function(customerId) {
                document.getElementById("pageMask").style.display = "block";
                document.getElementById("pageWait").style.display = "block";
                DF12Examples.startTime = Date.now();
                DF12FutureController.requestAllInvoices(customerId, DF12Examples.handleResponse);
            };

            // this is the function that gets called when the apex method tagged
            // with the @RemoteAction annotation is completed.
            DF12Examples.handleResponse = function(results, event) {
                document.getElementById("pageMask").style.display = "none";
                document.getElementById("pageWait").style.display = "none";
                if (event.status) {
                    alert("Congratulations! Everything worked! The response from the server is:\n\n" + results);
                }
                DF12Examples.endTime = Date.now();
                if (console) {
                    console.log("elapsed time: " + (DF12Examples.endTime - DF12Examples.startTime) + "ms");
                }
            }

        </script>
    </apex:define>

</apex:composition>
</apex:page>


Tuesday, December 25, 2012

Attachment displays Directory path in the filename:


Attachment displays Directory path in the filename:

When adding an attachment using IE browser to an e-mail being sent from Salesforce, the attachment file name is changed to include the entire file name path (e.g. C;/users/...).

The issue is facing by a user when he is trying to sends an e- mail to partner by adding an attachment on case, the name of the file is changed after uploading.The issue is getting in IE. Initially when we upload the file the name is (Exercise D Model Only.zip) and after attached it is showing as (DSupportSteveDowdenExercise D Model Only.zip) which is not looking correct, Also If we sent e-mail to customer the file is incorrectly named when sent via Salesforce. The issue looks fine in Google chrome and in Firefox browsers.


Resolution
 
  1. Open you Internet Explorer: Tools | Internet Option | Security 
  2. Select Zone to View: Select Local Intranet 
  3. Click Custom Level button 
  4. Under the Settings, look for Miscellaneous 
  5. Look for "Include Local directory path when uploading files to a server" and select Disable. 

Streaming Api vs ActionPoller:

Streaming Api vs ActionPoller:
Streaming api is much better concept than action poller since action poller will send a request depends on time interval you set (this example 15 sec) that is much load on server action.
a)Action Poller:

public with sharing class DF12PollerController {

    // in this example, the 'now' member variable must be part of the
    // page's viewstate, because I only want to display new accounts that
    // have been created after the page was initially loaded. every time
    // the page's actionPoller request comes in, the only way that the
    // controller will know the exact page load time is to serialize a
    // DateTime variable down to the browser.
    private DateTime now { get; set; }
    transient public List<Account> accounts { get; private set; }

    public DF12PollerController() {
        this.now = DateTime.now();
        this.accounts = new List<Account>();
    }

    public void find() {
        this.accounts = [
            SELECT Id, Name, CreatedDate
            FROM Account
            WHERE CreatedDate >= :this.now
        ];
    }

    @isTest
    private static void testFind() {
        DF12PollerController con = new DF12PollerController();
        System.assert(con.now != null, '\'now\' should not be null.');
        System.assert(con.accounts.size() == 0, '\'accounts\' should have zero records.');
        Account a = new Account(Name = 'Test Account');
        insert a;
        con.find();
        System.debug(con.accounts);
        System.assert(con.accounts.size() > 0, '\'accounts\' should have at least 1 record.');
    }

}

<apex:page docType="html-5.0" showHeader="false" standardStylesheets="false" controller="DF12PollerController">
<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: &lt;apex:actionPoller&gt; Example</apex:define>

    <apex:define name="header">
        <h1 class="pageTitle">&lt;apex:actionPoller&gt; Example</h1>
    </apex:define>

    <apex:define name="body">
        <h4>New Accounts</h4>
        <apex:form >
            <apex:outputPanel layout="block" id="target">
                <apex:repeat value="{!accounts}" var="a">
                    <p class="newItemRow">
                        <span class="newItem">{!a.Name}</span>
                        <span class="timeStamp">at {!a.CreatedDate}</span>
                    </p>
                </apex:repeat>
            </apex:outputPanel>
            <apex:actionPoller action="{!find}" rerender="target" interval="20"/>
        </apex:form>
    </apex:define>

</apex:composition>
</apex:page>
b)Streaming Api:

public with sharing class DF12StreamingAPIController {

    public PageReference createPushTopicIfNecessary() {
        List<PushTopic> pt = [
            SELECT Id, Name
            FROM PushTopic
            WHERE Name = 'NewAccounts'
            LIMIT 1
        ];
        if (pt.size() == 0) {
            pt.add(new PushTopic(
                ApiVersion = 23.0,
                Name = 'NewAccounts',
                Description = 'Returns all new accounts.',
                Query = 'SELECT Id, Name, CreatedDate FROM Account'
            ));
            upsert pt;
        }
        return null;
    }

    @isTest
    private static void testCreatePushTopicIfNecessary() {
        List<PushTopic> pt = [SELECT Id, Name FROM PushTopic WHERE Name = 'NewAccounts' LIMIT 1];
        DF12StreamingAPIController con = new DF12StreamingAPIController();
        try {
            con.createPushTopicIfNecessary();
        } catch (DmlException x) {
            System.assert(true, 'Should already be a push topic created for this');
        }
    }

}

<apex:page docType="html-5.0" controller="DF12StreamingAPIController" action="{!createPushTopicIfNecessary}" showHeader="false" standardStylesheets="false">

<apex:styleSheet value="{!$Resource.AdvVFWebinarCSS}"/>

<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: Streaming API Example</apex:define>

    <apex:define name="header">
        <h1 class="pageTitle">Streaming API Example</h1>
    </apex:define>

    <apex:define name="body">
        <h4>New Accounts</h4>
        <div id="target"></div>

        <div class="cheatLinkSeparator">
            <a class="cheatLink" href="{!$Page.DF12Poller}" title="Open apex:actionPoller Example">apex:actionPoller Example</a>
        </div>

    </apex:define>

    <apex:define name="pageScripts">
        <script src="{!URLFOR($Resource.streaming_api_js, 'cometd.js')}"></script>
        <script src="{!URLFOR($Resource.streaming_api_js, 'jquery-1.5.1.js')}"></script>
        <script src="{!URLFOR($Resource.streaming_api_js, 'json2.js')}"></script>
        <script src="{!URLFOR($Resource.streaming_api_js, 'jquery.cometd.js')}"></script>
        <script>
            (function($) {
                $(document).ready(function() {

                    // first, connect to the salesforce cometd endpoint
                    $.cometd.init({
                        url: location.protocol + "//" + location.hostname + "/cometd/23.0/",
                        requestHeaders: { Authorization : "OAuth {!$Api.Session_Id}" }
                    });

                    // second, subscribe to a PushTopic (i.e., a "channel")
                    $.cometd.subscribe("/topic/NewAccounts", function(message) {
                        $("#target").append(
                            "<p class='newItemRow'><span class='newItem'>" +
                            message.data.sobject.Name +
                            "</span><span class='timeStamp'>at " +
                            message.data.sobject.CreatedDate +
                            "</span></p>"
                        );
                    });

                }) // end document.ready
            })(jQuery)
        </script>
    </apex:define>

</apex:composition>
</apex:page>





Best Practice View State 3:

Best Practice View State 3:
This is a good example to reduce view state using visualforce remoting. You can observe following example results by chrome developer inspect (Ctrl+Shft+I) .Main difference between a remoting and a actionfunction method call and results.By using remoting you can call method with attributes directly from page where as actionfunction not also the call back function returns only results in remoting but using standard visualforce tags it brings html that you can see below .
a)Remoting:

public with sharing class DF12RemotingController {

    @RemoteAction
    public static List<Contact> doSearch(String customerLastName) {
        // be careful when doing LIKE queries with '%' wildcards on both
        // sides of the query term, especially when using non-indexed
        // fields, as performance can suffer
        customerLastName = '%' + customerLastName + '%';
        return [
            SELECT Id, FirstName, LastName
            FROM Contact
            WHERE LastName LIKE :customerLastName
            ORDER BY LastName, FirstName
            LIMIT 200
        ];
    }

    @isTest
    private static void testDoSearch() {
        List<Contact> control = new List<Contact>();
        control.add(new Contact(LastName = 'Smith', FirstName = 'Joe1', Email = 'test@test.test.test.test'));
        control.add(new Contact(LastName = 'Smith', FirstName = 'Joe2', Email = 'test@test.test.test.test'));
        insert control;
        List<Contact> actual = DF12RemotingController.doSearch('Smith');
        System.assert(actual.size() == 2, 'There should be two contacts named Smith here.');
    }

}

<apex:page controller="DF12RemotingController" docType="html-5.0" showHeader="false" standardStylesheets="false">

<apex:styleSheet value="{!$Resource.AdvVFWebinarCSS}"/>

<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: JavaScript Remoting Example</apex:define>

    <apex:define name="header">
        <h1 class="pageTitle">Find Customer</h1>
        <h4>JavaScript Remoting Example</h4>
    </apex:define>

    <apex:define name="body">

        <input id="searchField" type="text" placeholder="Enter Last Name"/>
        <button type="button" onclick="console.log('Step 1: Search button clicked.');DF12Examples.handleButtonClick();">Search</button>
        <table cellpadding="0" cellspacing="0">
            <thead></thead>
            <tfoot></tfoot>
            <tbody id="results"></tbody>
        </table>

        <div class="cheatLinkSeparator">
            <a class="cheatLink" href="{!$Page.DF12Action}" title="Open apex:actionFunction Example">apex:actionFunction Example</a>
        </div>

    </apex:define>

    <apex:define name="pageScripts">
        <script>

            // startTime and endTime are only being created for logging purposes, but
            // note that I am initializing their values to Date objects. this is so
            // JavaScript doesn't have to guess what kind of variables they are
            // (and therefore, doesn't have to change their datatype mid-execution).
            // this is a best practice for all JS variable declarations to help with
            // performance.
            DF12Examples.startTime = new Date();
            DF12Examples.endTime = new Date();

            // gets called when the 'Search' button is clicked
            DF12Examples.handleButtonClick = function() {
                console.log('Step 2: JS function handleButtonClick() called.');
                DF12Examples.startTime = Date.now();
                var searchTerm = document.getElementById("searchField").value;
                // call the apex controller method tagged w/ the @RemoteAction annotation.
                // the syntax is ControllerName.methodName(methodArguments, jsCallbackFunctionName, options).
                // the 'options' argument is optional.
                console.log('Step 3: JS function that maps to Apex controller method doSearch(String customerLastName) - via @RemoteAction annotation - called.');
                DF12RemotingController.doSearch(searchTerm, DF12Examples.renderResults);
            };

            // this is the js callback function that will execute when the @RemoteAction method
            // in the apex controller is done executing. it will always receive two arguments
            // passed from the controller method: 1) the JSON-encoded results, and an 'event'
            // object, which tells you if everything went ok on the server side.
            DF12Examples.renderResults = function (results, event) {
                console.log('Step 4: Results recieved. JavaScript function renderResults() called.');
                // if the apex method completed execution, event.status is true.
                if (event.status) {
                    // if there was an exception, you should handle it here.
                    if (event.type === "exception") {
                        // do stuff
                    } else {
                        // this is the empty <tbody> tag on the page
                        var container = document.getElementById("results"),
                                 html = [];
                        for (var i=0, j=results.length; i<j; i++) {
                            html.push("<tr><td>");
                            html.push(results[i].LastName + ", " + results[i].FirstName);
                            html.push("</td></tr>");
                        }
                        // this won't work in IE, because IE doesn't handle setting
                        // innerHTML for <tr> or <tbody> tags. *sigh*. To get this
                        // working in IE, you'd need to use document.createElement()
                        // for every DOM node you want to create, then use appendChild()
                        // to attach them to the correct parent.
                        container.innerHTML = html.join("");
                    }
                }
                DF12Examples.endTime = Date.now();
                if (console) {
                    console.log("elapsed time: " + (DF12Examples.endTime - DF12Examples.startTime) + "ms");
                }
            };

        </script>
    </apex:define>

</apex:composition>
</apex:page>
b)Without Remoting:

public with sharing class DF12ActionController {

    public String customerLastName { get; set; }
    public List<Contact> searchResults { get; private set; }

    public void doSearch() {
        // be careful when doing LIKE queries with '%' wildcards on both
        // sides of the query term, especially when using non-indexed
        // fields, as performance can suffer
        customerLastName = '%' + customerLastName + '%';
        searchResults = [
            SELECT Id, FirstName, LastName
            FROM Contact
            WHERE LastName LIKE :customerLastName
            ORDER BY LastName, FirstName
            LIMIT 200
        ];
    }

    @isTest
    private static void testDoSearch() {
        Contact c = new Contact(LastName = 'Smith', FirstName = 'Joe');
        insert c;
        DF12ActionController con = new DF12ActionController();
        con.customerLastName = 'Smith';
        con.doSearch();
        System.assert(con.searchResults.size() > 0, 'Should have found at least one contact');
    }

}

<apex:page controller="DF12ActionController" docType="html-5.0" showHeader="false" standardStylesheets="false">
<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: &lt;apex:actionFunction&gt; Example</apex:define>

    <apex:define name="header">
        <h1 class="pageTitle">Find Customer</h1>
        <h4>&lt;apex:actionFunction&gt; Example</h4>
    </apex:define>

    <apex:define name="body">
        <apex:form >
            <apex:actionFunction name="findMeSomeCustomers" action="{!doSearch}" reRender="customers" oncomplete="DF12Examples.handleActionFunctionCompletion();">
                <apex:param name="customerLastName" assignTo="{!customerLastName}" value=""/>
            </apex:actionFunction>
            <input id="searchField" type="text" placeholder="Enter Last Name"/>
            <button type="button" onclick="console.log('Step 1: Search button clicked.');DF12Examples.handleButtonClick();">Search</button>
            <apex:outputPanel layout="block" id="customers">
                <apex:dataTable value="{!searchResults}" var="sr">
                    <apex:column >{!sr.LastName}, {!sr.FirstName}</apex:column>
                </apex:dataTable>
            </apex:outputPanel>
        </apex:form>
    </apex:define>

    <apex:define name="pageScripts">
        <script>

            // startTime and endTime are only being created for logging purposes, but
            // note that I am initializing their values to Date objects. this is so
            // JavaScript doesn't have to guess what kind of variables they are
            // (and therefore, doesn't have to change their datatype mid-execution).
            // this is a best practice for all JS variable declarations to help with
            // performance.
            DF12Examples.startTime = new Date();
            DF12Examples.endTime = new Date();

            // gets called when the 'Search' button is clicked
            DF12Examples.handleButtonClick = function() {
                console.log('Step 2: JS function handleButtonClick() called.');
                DF12Examples.startTime = Date.now();
                // the JS function findMeSomeCustomers is automatically created for you
                // when you use an actionFunction tag (see above). the argument
                // being passed into this function corresponds to the param tag
                // nested inside the actionFunction tag.
                console.log('Step 3: JS function that maps to Apex controller method doSearch() - via apex:actionFunction tag - called.');
                findMeSomeCustomers(document.getElementById('searchField').value);
            };

            // gets called when the apex controller method that is bound to the
            // actionFunction tag's 'action' attribute (in this case, 'doSearch()')
            // completes processing
            DF12Examples.handleActionFunctionCompletion = function() {
                console.log('Step 4: AJAX call complete. Re-rendering apex:dataTable component.');
                DF12Examples.endTime = Date.now();
                if (console) {
                    console.log(
                        'elapsed time: ' +
                        (DF12Examples.endTime - DF12Examples.startTime) +
                        'ms'
                    );
                }
            };

        </script>
    </apex:define>

</apex:composition>
</apex:page>





Best Practice View State 2:

Best Practice View State 2:
This is a good example to reduce your view state using transient keyword.You can test this by removing transient keyword for one of attribute in controller try to save and note down your view state size.

public with sharing class DF12TransientController {

    // we keep the 'client' member variable as part of the viewstate,
    // because we want to track the state of something that we're attempting
    // to edit. all other variables are read-only on the VF page, so we
    // can make them 'transient' and remove them from viewstate. if you
    // want to see the difference made on the page's viewstate, remove the
    // 'transient' keyword from the 3 collections below and look at the
    // viewstate inspector from the dev footer.
    public Contact client { get; private set; }
    transient public List<Contact> connections { get; private set; }
    transient public List<Account> previousEmployers { get; private set; }
    transient public Set<String> hashTags { get; private set; }

    public DF12TransientController() {
        this.client = retrieveClient();
        this.connections = retrieveConnections();
        this.previousEmployers = retrievePreviousEmployers();
        this.hashTags = retrieveHashTags();
    }

    // just retrieve a sample contact ... any one will do
    private Contact retrieveClient() {
        return [
            SELECT
                Title,
                Phone,
                Name,
                MobilePhone,
                MailingStreet,
                MailingState,
                MailingPostalCode,
                MailingCountry,
                MailingCity,
                LastName,
                Id,
                HomePhone,
                FirstName,
                Email,
                Birthdate,
                AssistantPhone,
                AssistantName,
                AccountId
            FROM Contact
            LIMIT 1
        ];
    }

    // clearly, these aren't really 'connections' to the client above.
    // we just want some sample data to put on the page.
    private List<Contact> retrieveConnections() {
        return [
            SELECT Id, Name
            FROM Contact
            OFFSET 1
        ];
    }

    // dummy data
    private List<Account> retrievePreviousEmployers() {
        List<Account> a = new List<Account>();
        a.add(new Account(Name = 'GE'));
        a.add(new Account(Name = 'Siemens'));
        a.add(new Account(Name = 'EADS'));
        return a;
    }

    // dummy data
    private Set<String> retrieveHashTags() {
        Set<String> s = new Set<String>();
        s.add('#where');
        s.add('#dreamforce');
        s.add('#pto');
        s.add('#highlights');
        s.add('#bestpractice');
        s.add('#protip');
        s.add('#iwantapony');
        s.add('#hr');
        return s;
    }

    public void save() {
        try {
            insert client;
        } catch (Exception x) {
            client.addError(x.getMessage());
        }
    }

    @isTest
    private static void testGetMemberVariables() {
        List<Contact> c = new List<Contact>();
        c.add(new Contact(LastName = 'Smith1', FirstName = 'Joe1', Email = 'test@test.test.test.test'));
        c.add(new Contact(LastName = 'Smith2', FirstName = 'Joe2', Email = 'test@test.test.test.test'));
        insert c;
        DF12TransientController con = new DF12TransientController();
        System.assert(con.client != null, 'There should be a contact here.');
        System.assert(con.connections.size() > 0, 'There should be connections here.');
        System.assertEquals(3, con.previousEmployers.size(), 'There should be 3 employers here.');
        System.assertEquals(8, con.hashtags.size(), 'There should be 8 hashtags here.');
    }

}

<apex:page controller="DF12TransientController" docType="html-5.0" showHeader="false" standardStylesheets="false">
<apex:composition template="DF12Template">

    <apex:define name="pageTitle">DF '12: transient Keyword Example</apex:define>

    <apex:define name="pageStylesheets">
        <apex:stylesheet value="{!$Resource.df_css}"/>
    </apex:define>

    <apex:define name="header">
        <h1 class="pageTitle"><span class="keyword">transient</span> Example</h1>
    </apex:define>

    <apex:define name="body">
        <apex:form >
            <h3>Client Information</h3>
            <apex:pageBlock >
                <apex:pageBlockButtons location="top">
                    <apex:commandButton action="{!save}" value="Save"/>
                </apex:pageBlockButtons>
                <apex:pageBlockSection columns="2">
                    <apex:inputField value="{!client.FirstName}"/>
                    <apex:inputField value="{!client.LastName}"/>
                    <apex:inputField value="{!client.Email}"/>
                    <apex:inputField value="{!client.Phone}"/>
                    <apex:inputField value="{!client.MobilePhone}"/>
                    <apex:inputField value="{!client.MailingStreet}"/>
                    <apex:inputField value="{!client.MailingCity}"/>
                    <apex:inputField value="{!client.MailingState}"/>
                    <apex:inputField value="{!client.MailingPostalCode}"/>
                    <apex:inputField value="{!client.MailingCountry}"/>
                    <apex:inputField value="{!client.HomePhone}"/>
                    <apex:inputField value="{!client.Birthdate}"/>
                    <apex:inputField value="{!client.AssistantName}"/>
                    <apex:inputField value="{!client.AssistantPhone}"/>
                    <apex:inputField value="{!client.Title}"/>
                    <apex:inputField value="{!client.AccountId}"/>
                </apex:pageBlockSection>
            </apex:pageBlock>
            <h3>Connections</h3>
            <apex:repeat value="{!connections}" var="c">
                <apex:outputText value="{!c.Name}, "/>
            </apex:repeat>
            <apex:outputText value=" and 500+ more."/>
            <h3>Previous Employers</h3>
            <apex:dataTable value="{!previousEmployers}" var="e">
                <apex:column value="{!e.Name}"/>
            </apex:dataTable>
            <h3>Frequently Used Hashtags</h3>
            <apex:dataTable value="{!hashTags}" var="h">
                <apex:column value="{!h}"/>
            </apex:dataTable>
        </apex:form>
    </apex:define>

</apex:composition>
</apex:page>



Monday, December 24, 2012

Best Practice View State 1:

Best Practice View State 1:


This is a good example to understand view state functionality how it is responding when you use form tag in your page.

public with sharing class AdvVFWebinarViewStateExtension {



    /* instance variables */
    public  Account                      acc             { get; set; }
    public  Contact                      primaryContact  { get; set; }
    public  Opportunity                  opp             { get; set; }
    private List<Contact>                allContacts     { get; set; }
    private List<OpportunityContactRole> oppRoles        { get; set; }
    public  Boolean                      isDecisionMaker { get; set; }
    public  String                       moreNames       { get; set; }



    /* constructor */
    public AdvVFWebinarViewStateExtension(ApexPages.StandardController sc) {
        this.acc            = (Account)sc.getRecord();
        this.primaryContact = new Contact();
        this.opp            = new Opportunity(StageName = 'Prospecting');
        this.allContacts    = new List<Contact>();
        this.oppRoles       = new List<OpportunityContactRole>();
    }



    /* page actions */
    public PageReference save() {
        PageReference currPage = ApexPages.currentPage().setRedirect(false);
        try {
            upsertAccount();
            upsertOpportunity();
            upsertContacts();
            upsertOpportunityContactRoles();
        } catch (DmlException x) {
            this.allContacts.clear();
            this.oppRoles.clear();
            return currPage;
        }
        return new PageReference('/' + this.acc.Id);
    }



    /* private methods */
    private void upsertAccount() {
        upsert this.acc;
    }


    private void upsertOpportunity() {
        this.opp.AccountId = this.acc.Id;
        upsert this.opp;
    }


    private void upsertContacts() {

        // deal with the primary contact first
        this.primaryContact.AccountId = this.acc.Id;
        this.allContacts.add(this.primaryContact);

        // now let's deal with the additional contact names that were supplied.
        // let's break apart the comma-separated list of names first, then separate
        // each of _those_ items into first name and last name
        List<String> moreNamesList = (moreNames != null && moreNames != '') ? moreNames.split(',') : new List<String>();
        List<String> firstLast;
        String lName;
        if (moreNamesList.size() > 0) {
            for (String s : moreNamesList) {
                s = s.trim();
                firstLast = s.split(' ');
                lName = firstLast.size() > 1 ? firstLast[1] : 'UNKNOWN';
                this.allContacts.add(new Contact(FirstName = firstLast[0], LastName = lName, AccountId = this.acc.Id));
            }
        }

        upsert this.allContacts;
    }


    private void upsertOpportunityContactRoles() {

        Boolean primary;
        String oppRole;
        for (Contact c : this.allContacts) {
            if (c.Id == this.primaryContact.Id) {
                primary = true;
                oppRole = isDecisionMaker ? 'Decision Maker' : 'Influencer';
            } else {
                primary = false;
                oppRole = 'Influencer';
            }
            this.oppRoles.add(new OpportunityContactRole(ContactId = c.Id, isPrimary = primary, OpportunityId = this.opp.Id, Role = oppRole));
        }

        upsert this.oppRoles;
    }


    @isTest
    private static void testSaveSuccessful() {
        AdvVFWebinarViewStateExtension vse = getInstance();
        // valid close date (must be greater or equal to today)
        vse.opp.CloseDate = Date.today() + 30;
        PageReference pr = vse.save();
        System.assert(vse.acc.Id != null, 'Account insertion not successful.');
        System.assert(vse.primaryContact.Id != null, 'Contact insertion not successful.');
        System.assert(vse.opp.Id != null, 'Opportunity insertion not successful.');
        List<OpportunityContactRole> ocr = [SELECT Id FROM OpportunityContactRole WHERE OpportunityId = :vse.opp.Id];
        System.assert(ocr != null && ocr.size() == 3, 'Opportunity-Contact Role insertion not successful.');
        System.assert(pr.getUrl().indexOf(vse.acc.Id) != -1, 'Should have been redirected to account detail page.');
    }


    @isTest
    private static void testSaveFailedBecauseOfOpportunityValidationRule() {
        AdvVFWebinarViewStateExtension vse = getInstance();
        // invalid close date (must be greater or equal to today)
        vse.opp.CloseDate = Date.today() - 30;
        PageReference pr1 = Page.AdvVFWebinarViewState;
        PageReference pr2 = vse.save();
        System.assert(pr1.getUrl() == pr2.getUrl(), 'Should not have been redirected.');
    }


    private static AdvVFWebinarViewStateExtension getInstance() {
        PageReference pageToTest = Page.AdvVFWebinarViewState;
        Test.setCurrentPageReference(pageToTest);
        AdvVFWebinarViewStateExtension vse = new AdvVFWebinarViewStateExtension(new ApexPages.StandardController(new Account()));
        vse.acc.Name = 'New Account';
        vse.primaryContact.FirstName = 'First';
        vse.primaryContact.LastName = 'Last';
        vse.opp.Name = 'New Opp';
        vse.isDecisionMaker = false;
        vse.moreNames = 'Bah Bah, Dah Dah';
        return vse;
    }



}

<apex:page standardController="Account" extensions="AdvVFWebinarViewStateExtension">

    <apex:styleSheet value="{!$Resource.AdvVFWebinarCSS}"/>
    <apex:includeScript value="{!$Resource.jquery_1_8_3}"/>
    <apex:includeScript value="{!$Resource.AdvVFWebinarJS}"/>

    <apex:sectionHeader title="View State Example" subtitle="Opportunity QuickStart"/>

    <apex:form styleClass="vfWebinarForm">

        <a class="cheatLink" href="javascript:void(0);" onclick="VFWebinar.autoFillForm();" title="Autofill this form">Quick Fill for Demonstration</a>

        <apex:pageMessages />

        <apex:pageBlock mode="edit">

            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Save" action="{!save}"/>
            </apex:pageBlockButtons>

            <apex:pageBlockSection title="Contact Info" columns="1">
                <apex:inputField value="{!primaryContact.FirstName}"/>
                <apex:inputField value="{!primaryContact.LastName}"/>
                <apex:inputField value="{!primaryContact.Phone}"/>
                <apex:inputField value="{!primaryContact.Email}"/>
                <apex:pageBlockSectionItem >
                    <label for="{!$Component.isDecisionMaker}">Decision Maker</label>
                    <apex:inputCheckbox id="isDecisionMaker" value="{!isDecisionMaker}"/>
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <label for="{!$Component.moreNames}">Additional Contact Names</label>
                    <apex:inputText id="moreNames" styleClass="moreNames" value="{!moreNames}"/>
                </apex:pageBlockSectionItem>
            </apex:pageBlockSection>

            <apex:pageBlockSection title="Account Info" columns="1">
                <apex:inputField value="{!Acc.Name}"/>
                <apex:inputField value="{!Acc.Industry}"/>
                <apex:inputField value="{!Acc.BillingCity}"/>
            </apex:pageBlockSection>

            <apex:pageBlockSection title="Opportunity Info" columns="1">
                <apex:inputField value="{!Opp.Name}"/>
                <apex:inputField value="{!Opp.Amount}"/>
                <apex:inputField value="{!Opp.CloseDate}"/>
                <apex:inputField value="{!Opp.StageName}"/>
            </apex:pageBlockSection>

        </apex:pageBlock>

        <script>VFWebinar.init();</script>

    </apex:form>

</apex:page>

You can observe view state without fill values and add some data try to put some validation like close date should not less than today and fill the form with date less than today try to save it gives an error but you can see view state size increase due to input hidden tag works and saves your rest of your data in view state .