2

I have the controller below for a Visualforce page set up on the Contact record as a Detail Page button. The purpose is to allow users to set up multiple tasks at once, but also pre-populate the WhoID, OwnerId, and WhatId for the tasks.

The problem I am running into is when I click the Add Another RDA button on the VF page, it creates an exact clone of the previous task and if I change a value, it changes for all the tasks. How can I make it so that each task is individual of one another, but still able to be created at the same time?

CONTROLLER:

public with sharing class RDATasks{

    public list<Task> listTask{get;set;}

    private final Contact con;
    public RDATasks(ApexPages.StandardController myController){
        listTask = new List<Task>();
        con=(Contact)myController.getRecord();
    }

    public Task task1 = new Task();
        public void RDA(){
            Task1.WhoId = con.Id;
            Task1.OwnerId = UserInfo.getUserId();
//            Task1.WhatId = con.AccountId;
            Task1.RDA__c = TRUE;
            listTask.add(Task1);
        }

    public PageReference saveTask(){
        insert listTask;
            {
            PageReference contactPage = new PageReference('/' + con.Id);
            contactPage.setRedirect(true);
            return contactPage;
            }
    }
}

VISUALFORCE PAGE:

<apex:page standardController="Contact" tabStyle="Contact" sidebar="false" extensions="RDATasks" action="{!RDA}">

<apex:form >

<apex:sectionHeader title="Activities"/>
<apex:repeat value="{!listTask}" var="tsk">
    <apex:pageBlock >
        <apex:pageBlockSection >
            <apex:outputField value="{!Contact.Account.Name}" label="Related To"/>
            <apex:outputField value="{!Contact.Name}" label="Name"/>
            <apex:inputField value="{!tsk.Type_of_RDA__c}" style="width:35%"/>
            <apex:inputField value="{!tsk.Subject}" style="width:45%"/>
            <apex:inputField value="{!tsk.ActivityDate}" style="width:35%"/>
            <apex:inputField value="{!tsk.Status}" />
            <apex:inputField value="{!tsk.Description}" style="width:100%"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:repeat>

    <apex:commandButton value="Add Another RDA" action="{!RDA}"/>
    <apex:commandButton value="Save RDAs" action="{!saveTask}"/>
</apex:form>

</apex:page>
3

Don't share a reference.

Incorrect

As written, every time you add a "new record", you're just manipulating the same reference to task1.

Task task1 = new Task();
public void RDA()
{
    task1.WhatId = con.Id;
    // other fields;
    listTask.add(task1);
}

Correct

Instantiate a new Task record each time you call the method, and the references will not be shared.

public void RDA()
{
    Task record = new Task();
    record.WhatId = con.Id;
    // other fields
    listTask.add(record);
}

More efficient

You don't even have to cache the record at all, and can specify field=value pairs in the constructor, which is significantly faster.

public void RDA()
{
    listTask.add(new Task(
        WhoId = con.Id,
        // other fields
    ));
}
  • Awesome, thanks so much!! Do you know how I would build in the ability to remove a task after calling the RDA method, in case a user changes their mind about creating it? – John Neilan Jan 18 '17 at 21:49
  • That would be a separate question. :) If you have a UI to create new records and you want to remove one of them, you'll need to use a list and remove by index, likely. I recommend you do a bit of research and make an attempt, then post here (as a new question) if you get stuck. – Adrian Larson Jan 18 '17 at 21:57

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.