1

I have a requirement that after selecting the account from picklist all contacts show appear in table, when I click on the edit button of contact it should redirects me to edit page of that contact and when I hit save button it show go to the vf page only with the selected account and contacts in table. I have done everything but when the page gets redirect after saving the contact, the picklist value is reset and no contact appear in table. How could I retain values in picklist and table.

Controller

public class assignment1_1 
{
    public String accId{get;set;}
    public List<SelectOption> allAccounts{get;set;}
    public List<Contact> conList{get;set;}
    public assignment1_1()
    {
        allAccounts = new List<SelectOption>();
        conList = new List<Contact>();
        List<Account> accList = [Select id, name From Account];
        accList.sort();
        for(Account acc : accList)
        {
            allAccounts.add(new SelectOption(acc.id, acc.name));
        }
    }

    public void search()
    {
        conList.clear();
        for(Contact con : [Select id, name, email, Email_Sent__c From contact Where accountId =: accId])
        {
            conList.add(con);
            conList.sort();
        }
    }
}

Page

<apex:page controller="assignment1_1">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection >
                <apex:actionRegion >
                    <apex:selectList value="{!accId}" size="1">
                        <apex:selectOptions value="{!allAccounts}"/>
                        <apex:actionSupport action="{!search}" event="onchange" reRender="pbs"/>
                    </apex:selectList>
                </apex:actionRegion>
            </apex:pageBlockSection>
            <apex:pageBlockSection id="pbs" >
                <apex:pageBlockTable var="row" value="{!conList}">
                    <apex:column headerValue="Action">
                        <apex:outputLink value="/{!row.id}/e?retURL=/apex/assignment1_1" style="font-weight:bold">Edit</apex:outputLink>&nbsp;|&nbsp;
                        <apex:outputLink value="{!URLFOR($Action.Contact.Delete, row.Id)}" style="font-weight:bold">Del</apex:outputLink>
                    </apex:column>
                    <apex:column value="{!row.name}"/>
                    <apex:column value="{!row.email}"/>
                </apex:pageBlockTable>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

1 Answer 1

6

Why it isn't working right now

The reason why it isn't working now is due to a fundamental property of HTTP. In your situation here, the Account that was selected in the picklist is an excellent example of what is called "state".

Because HTTP is a "stateless" protocol, it doesn't automatically carry over the old "state" of your controller. If you want to retain data after navigating to another page, you need to do it explicitly.

Salesforce has a solution for this called the "viewstate", but I don't think you'll be able to make use of that in this situation. For all intents and purposes, you don't have a "viewstate" in this situation.

How do I make it work?

You're already part of the way there, setting ?returl=/apex/assignment1_1 is one method of transmitting some state information. Everything after the question mark (?) is called the query string of the URL (Uniform Resource Locator).

To 'remember' which Account you previously selected, you'll need to include the Account's Id in the query string for your returl, and you'll need to update your controller's constructor to be able to make use of this additional information.

Where it gets a little bit iffy is that the returl is itself already a part of the query string. You'll need to know how to nest query strings.

In my experience outside of the Salesforce platform, everything in the query string needs to be URL-encoded. This means replacing the reserved characters (including :, /, and ?) with percent-encoded equivalents. ? = %3F.

I haven't had the need to do this myself, so I'm not 100% sure how Salesforce handles it. One of the two following examples should work

<apex:outputLink value="/{!row.id}/e?retURL=/apex/assignment1_1?recId={!acctId}" style="font-weight:bold">Edit</apex:outputLink>&nbsp;|&nbsp;

or

<apex:outputLink value="/{!row.id}/e?retURL=/apex/assignment1_1%3FrecId={!acctId}" style="font-weight:bold">Edit</apex:outputLink>&nbsp;|&nbsp;

I'll leave modifying the controller to you. It's a pretty simple application of using PageReference.getParameters(). You'll also probably want to run your search() method from your constructor if you find that the recId parameter was set in the URL.

4
  • thanks for the reply... I tried both the examples u told me but they are not working...picklist is not reaining its values..
    – Anzar
    Sep 17, 2016 at 22:57
  • @Anzar sounds like you haven't updated your controller's constructor yet.
    – Derek F
    Sep 18, 2016 at 1:09
  • yea I havn't till now, i didn't get what to update in controller's constructor
    – Anzar
    Sep 19, 2016 at 7:46
  • @Anzar The last two sentences of my answer are basically the pseudocode. 1) use getParameters() to get all of the query string parameters as a Map<String, String>. 2) check that map to see if recId exists using containsKey() 3) set acctId and then call search() if recId is in the map.
    – Derek F
    Sep 19, 2016 at 13:33

You must log in to answer this question.

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