• mgodsey
  • NEWBIE
  • 215 Points
  • Member since 2012

  • Chatter
    Feed
  • 5
    Best Answers
  • 4
    Likes Received
  • 0
    Likes Given
  • 69
    Questions
  • 66
    Replies

I am trying to write a trigger that will create an activity when an opportunity reaches a certain stage.  I want the activity to be assigned to the owner of the opportunity and to be related to the opportunity, but when I try to assign values to the appropriate fields I get 'Field is not writeable' errors.  Here is the code with these fields commented out:

 

--------------------------------------------------------------------------------

trigger CreateActivityAfterClosedWon on Opportunity (after insert, after update) {
 
    List<Task> NewTasks = new List<Task>();
    for (Opportunity opp: Trigger.new){
        if (opp.StageName == '100 - Closed Won - Booked'){
                NewTasks.add(new Task(
                    ActivityDate = Date.today(),
                    //What = opp.Id,
                    //Owner = opp.Owner,
                    Status = 'Closed',
                    Activity_Type__c = 'Project Won',
                    Priority = 'Normal',
                    Subject = opp.Name));
        }
    }

    insert NewTasks;
}

--------------------------------------------------------------------------------------------

 

With these fields commented out, the trigger runs in the sand box and creates activities, but the activities are not related to any object and are assigned to me (because the code ran under my account).

 

Can anybody suggest a solution?


Thanks & Regards,

Jeff

I've right justified a numerical column in an apex:pageblocktable, but it's right next to a text column that is left-justified. I want to add a bit of extra spacing between the two columns, but nothing seems to be working. Below are two things I've tried (I've only included the relevant markup) - can anyone please point out where I'm going wrong?

Thanks!
 
        .number{
            text-align: right;
        }
        .ruiColumnWidth{
            width: 15%;
        }
        .ruiMonthEven{
            background: #F5F5F5;
        }
        .ruiMonthOdd{
        }

<apex:pageBlockTable value="{!ruiWrappers}" var="wrapper" cellpadding="5">
     <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number">
          <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/>
     </apex:column>
     <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}">
            <apex:outputText value="{!wrapper.ruiProbability}"/>
     </apex:column>
</apex:pageBlockTable>
.number{
    text-align: right;
    padding-right: 5px;
}
.ruiColumnWidth{
    width: 15%;
}
.ruiMonthEven{
    background: #F5F5F5;
}
.ruiMonthOdd{
}

<apex:pageBlockTable value="{!ruiWrappers}" var="wrapper">
     <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number">
          <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/>
     </apex:column>
     <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}">
            <apex:outputText value="{!wrapper.ruiProbability}"/>
     </apex:column>
</apex:pageBlockTable>

User-added image
 
I have a project that includes the requirement for the following process: a user clicks a salesforce button, and under certain conditions, a pop-up window appears. On that window should be two, dependent picklist fields. Once they complete those fields and click "Ok", the values in those fields should be mapped to the corresponding fields in Salesforce. If they click that button again under the same conditions, the values they have already selected should default.

I know this is possible using a custom button which re-directs the user to a Visualforce page (so not quite a pop-up) and uses apex:inputFields. However, does anyone know if this would be possible using a custom button that executes JavaScript on click? I'm just not sure if it would be too much overkill to build the dependent picklists on this pop-up page or if there is an easy way to grab the information from the Salesforce fields.

I'm not really looking for the code here, just general thoughs on if this approach is even possible/worth considering.

Thanks!
I'm trying to override the standard Opportunity tab with a custom visualforce page. Below is the page, but it's not availalbe in the dropdown for overriding the standard tab. Does anyone have any idea what I am missing? Thanks!
 
<apex:page standardController="Opportunity" extensions="OpportunityTabExtension" readOnly="true" tabStyle="Opportunity">
    <apex:sectionHeader title="{!$ObjectType.Opportunity.LabelPlural}" subtitle="Home"/>
    <apex:pageBlock title="Recently Viewed">
        <apex:pageBlockTable value="{!recentOpps}" var="opp">
            <apex:column headerValue="Opportunity">
                <apex:outputLink title="Opportunity" value="/{!opp.Id}">
                    <apex:outputfield value="{!opp.Name}"/>
                </apex:outputLink>
            </apex:column>
            <apex:column title="{!$ObjectType.Opportunity.Fields.OwnerId.Label}" value="{!opp.OwnerId}"/>
            <apex:column title="{!$ObjectType.Opportunity.Fields.StageName.Label}" value="{!opp.StageName}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
    <apex:pageBlock title="List Views">
        <apex:ListViews type="Opportunity"/>
    </apex:pageBlock>
</apex:page>

 
I have a custom clone button on an Opportunity visualforce page that when clicked, should 1) confirm that they want to clone the Opportunity 2) check if certain records in the system exist, 3) if they do exist, have the user again click ok to confirm that they want to clone or cancel 3) if the user clicked ok, clone the Opportunity. I tried to use javascript remoting for the first time, and I think it's causing my action method to not fire.

If I click the 'Copy Opportunity without Media Plan' button, both confirmation pop-up alerts are displayed to the user, but nothing happens when they click 'OK.' If I click the 'Copy Opportunity without Media Plan 2' button, which does not have the remote action, the first confirmation pop-up is displayed, and when they click 'OK' the Opportunity clones.

Will javascript remoting not work in this scenario? It's my first time using it, so I don't understand it fully. Do I need to use action:function instead?

Thanks for the help!

Snippet Visualforce Page:
<script type="text/javascript">
        //confirm that they want to clone the Opportuntiy
        function confirmOppOnlyClone(){
            return confirm('Do you want to copy this Opportunity only?');
        }

        //check if other opportunities have been cloned from this one
        function duplicateOppsCheck(){
            var oppId = "{!opportunity.Id}";
            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.OpportunityExtension.duplicateOppsCheck}',
                oppId, function(result, event) {
                    if(event.status){
                        if (result != null){
                            return confirm(result);
                        }
                    }
                }
            );
        }
    </script>

<apex:form >
    <apex:sectionHeader subtitle="{!opportunity.Name}" title="Opportunity"/>
    <apex:pageMessages />
    <apex:pageBlock >
        <apex:pageBlockButtons >

            <apex:commandButton value="Copy Opportunity without Media Plan" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;if(!duplicateOppsCheck()) return false"/>

            <apex:commandButton value="Copy Opportunity without Media Plan 2" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;"/>

Snippet of Controller Extension: 
@RemoteAction
    public static String duplicateOppsCheck (String opportunityId){


        String confirmMessage = 'There is an existing Opportunity that has been copied from this Opportunity. Please confirm that it is not a duplicate.\n\n';
        Boolean returnConfirmMessage = false;

        //if there are any existing opportunities that were copied from the current one, add their names and urls to the confirmation message
        for(Opportunity opp : [SELECT Id, Name FROM Opportunity WHERE ClonedFrom__c =: opportunityId]){
            confirmMessage += 'Name: '+opp.Name +'\n';
            confirmMessage += System.URL.getSalesforceBaseURL().toExternalForm()+'/'+opp.id + '\n\n';
            returnConfirmMessage = true;
        }

        if(returnConfirmMessage){
            return confirmMessage;
        }

        return null;
    }

 
I have to create an account partner relationship in a unit test. I have written the below. However, it is failing at the bolded line, with the error: System.SObjectException: Invalid field AccountFromId. This is strange, right? The same logic is working in another class, and if I look up the partner object in the workbench 'AccountFromId' is clearly a valid field. Any ideas of what is going wrong? Thanks!

            Account acct = UnitTestFactory.makeAccount();
            Account agencyAcct = UnitTestFactory.makeAccount();
            agencyAcct.Type = 'Agency';
            update agencyAcct;

            Partner pa = new Partner();
            pa.AccountFromId = acct.Id;
            pa.AccountToId = agencyAcct.Id;
            insert pa;


  • September 17, 2014
  • Like
  • 0
Our org currently has a custom opportunity button that is displayed in the contact page list view. When creating the new opportunity, the opportunity contact role defaults to the contact the opp was created from by using the following parameter:

conid={!Contact.Id}

Now we are trying to completely override the standard 'New' Opportunity page with a Visualforce page. Is there anyway to default the Opportunity Contact Role if I am passing in the contact Id through a custom button? Or will I have to store this Id somewhere, and then write a trigger after insert to create the Opportunity Contact Role?

Below is some of the extension code for the VF page. Thanks for any guidance!

public with sharing class OpportunityNewExtension {
    private Opportunity currentOpp;
   
    //following Ids are passed in through the custom button
    public Id accountId;
    public Id contactId;

    public OpportunityNewExtension(ApexPages.StandardController controller) {
       
        //get information about the opportunity and related account
        currentOpp = (Opportunity)controller.getRecord();
        accountId = ApexPages.currentPage().getParameters().get('accountId');
        Account acct = [SELECT Type, BillingCountry FROM Account WHERE Id=: accountId];

        //set default values for required fields
        currentOpp.StageName = Status.Omit;
        currentOpp.Name = 'Default'; //will be updated via workflow on save
        currentOpp.CloseDate = System.today()+30;
I have a custom command button in a visualforce page that when clicked performs an action. For this action, I refresh a page block that has fields that are required. However, I do not want them to be required at this point, so I use immediate="true", which is partially working. The action isn't actually being prevented, but the field required message is still displayed (screenshot attached). Can anyone explain why this might be happening? Thank you!!

<apex:column headerValue="Add Test">
                    <apex:actionStatus id="addStatus" >
                        <apex:facet name="stop" >
                            <apex:commandButton value="Select" action="{!addToQuoteLineItemWrappers}" reRender="selected,errors" immediate="true" image="{!$Resource.GreenPlus}" status="addStatus">
                                <apex:param value="{!product.Id}" assignTo="{!toSelectId}" name="toSelectId"/>
                            </apex:commandButton>
                        </apex:facet>
                        <apex:facet name="start">
                            <apex:commandButton value="Adding - See Below" disabled="true" status="addStatus" />
                        </apex:facet>
                    </apex:actionStatus>
 </apex:column>
User-added image

I'm having a lot of issues with the developer console when checking test coverage, and I don't know if it is a bug with the console or something wrong with my code. 

1) I run the test in the developer console. The Test Run log is not actually showing up unless I completely close the developer console and then re-open it.
2) After running the test (it succeeds), in the overall code coverage box,  the class says 100%
3) I double click on the class name in the overall code coverage box and it goes to 0%
4) When I look at the drop down of tests for that class, it shows me the following:

All Tests 0%
Test_QuoteLineITemEntryExtension.testSaveMethods 52%
Test_QuoteLineItemEntryExtension.testControllerWithParameters 36%

Why would it be showing 0% for all tests if individual methods provide coverage? Also, there is no red/blue highlighting in the class to show me what is or is not covered.

Has anyone run into this before? It's driving me crazy! Would be happy to post my test class if that helps. Thanks!
I have a custom picklist in a Visualforce page that is conditionally required. When it is required, I want to display the standard red "required" line that you see in Salesforce pages. Using the code below, I've added in the red line. However, I'm at a loss as to how to make it conditional. Does anyone have any advice for how to add in a condition statement? Thanks!

<apex:column headerValue="{!$ObjectType.QuoteLineItem.Fields.AdServer__c.Label}" rendered="{!s.qLine.PricebookEntry.Product2.DisplayAdServer__c}" style="vertical-align:top">
                <apex:outputPanel >              
                <div class="requiredInput">
                    <div class="requiredBlock"></div>
                  <apex:selectList value="{!s.qLine.AdServer__c}" required="{!s.qLine.PricebookEntry.Product2.RequiredAdServer__c}" multiselect="false" size="1">
                      <apex:selectOptions value="{!s.adServerOptions}"/>
                  </apex:selectList>
                </div>
                </apex:outputPanel>
            </apex:column>
Quantcast (http://www.quantcast.com) is seeking a a talented Force Engineer to design and develop complex technical solutions in our highly customized Salesforce instance.

We use Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.

Responsibilities
  • Build flexible, scalable and robust technical solutions to meet dynamic needs of fast-growing and fast-paced business
  • Design, development and deploy complex solutions in our Salesforce instance
  • Build and expand integrations to Salesforce
  • Conduct peer code reviews
  • Analyze and develop solutions to end-user support issues
A little bit about us: Quantcast is a digital advertising company specialized in audience measurement and real-time advertising. As the pioneer of direct audience measurement in 2006, Quantcast has today the most in-depth understanding of digital audiences across the web, allowing marketers and publishers to make the smartest choices as they buy and sell the most effective targeted advertising on the market. For more information about Quantcast, please visit: https://www.quantcast.com/word

If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it.  Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=ot6DYfwU
Quantcast (https://www.quantcast.com/) is seeking a talented Senior Force Solutions Engineer to lead design and development in our highly customized Salesforce instance. 

Quantcast uses Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.

 Responsibilities
  • Build flexible, scalable and robust technical solutions to meet dynamic needs of fastgrowing and fastpaced business
  • Lead Salesforce solution design, development and deployment activities
  • Drive adoption of development methodology best practices
  • Evangelize and faciliate the Force platform across the engineering organization
  • Mentor Salesforce developers in methodology and advanced development skills
A little bit about us: Quantcast is a digital advertising company specialized in audience measurement and real-time advertising. As the pioneer of direct audience measurement in 2006, Quantcast has today the most in-depth understanding of digital audiences across the web, allowing marketers and publishers to make the smartest choices as they buy and sell the most effective targeted advertising on the market. For more information about Quantcast, please visit: https://www.quantcast.com/word

If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it.  Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=oQpiXfwe
I've created a VF page to replace the standard record type selection page. It starts by clicking a custom "New" button with the following URL: /apex/NewMediaPlanOverride?oppid={!Opportunity.Id}

Here is the VF page:
<apex:page controller="NewMediaPlanOverride">
    <apex:form >
         <apex:pageMessages />
        <p style="font-size:20px"> What type of Media Plan are you creating?</p>
        <apex:commandButton action="{!newProposal}" value="Proposal"/>
        <apex:commandButton value="Insertion Order"/>
    </apex:form>

</apex:page>

The code works when I have it written this way:

public with sharing class NewMediaPlanOverride {
    public String oppId {get; set;}
   
    public NewMediaPlanOverride() {
        oppId = ApexPages.currentPage().getParameters().get('oppId');
    }
   
    public PageReference newProposal() {
        Savepoint sp = Database.setSavepoint();
       
        try{
            Quote newQuote = new Quote();
            Recordtype rt = [SELECT Name FROM RecordType WHERE Name = 'Proposal' and SObjectType = 'Quote' Limit 1];
            String recTypeId = rt.Id;
           
            //build the URL that the user will be redirected to
            //Quote is a standard object so the prefix is consistant across orgs
            String nextPage = '/0Q0/e?oppid=' + oppId + '&RecordType=' + recTypeId + '&retURL=%2F'+oppId + '&ent=Quote';
            PageReference pageRef = new PageReference(nextPage);  
            return pageRef;
               
        } catch(Exception e){
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
        }
}

However, since I'm going to have to repeat the redirect logic for different record types, I've tried to put it in its own method. Now when I click the button, it just stays on the same page instead of redirecting.

public with sharing class NewMediaPlanOverride {

    public String oppId {get; set;}

    public NewMediaPlanOverride() {
        oppId = ApexPages.currentPage().getParameters().get('oppId');
    }

    public void newProposal() {
        String recTypeId = getRecordTypeId('Proposal');
        newQuote(recTypeId);
    }

   public PageReference newQuote(String recTypeId){
       Savepoint sp = Database.setSavepoint();

       try{
            Quote newQuote = new Quote();
            //build the URL that the user will be redirected to
            //Quote is a standard object so the prefix is consistant across orgs

            String nextPage = '/0Q0/e?oppid=' + oppId + '&RecordType=' + recTypeId + '&retURL=%2F'+oppId + '&ent=Quote';
            PageReference pageRef = new PageReference(nextPage);  
            System.debug('[MF] nextPage: ' + nextPage);
            System.debug('[MF] pageRef' + pageRef);

            return pageRef;

       } catch(Exception e){

       System.debug('[MF] is there an error?' +e);
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
        }
    }

    public String getRecordTypeID(String type){
        RecordType rt = [SELECT Name FROM RecordType WHERE Name =:type AND SObjectType = 'Quote' Limit 1];
        String recTypeId = rt.Id;
        return recTypeId;
    }
}

Can anyone help me figure out why the second version of this code is not working? Here are the debug statements:
DEBUG|[MF] nextPage: /0Q0/e?oppid=006S00000070yVM&RecordType=012S00000004fibIAA&retURL=%2F006S00000070yVM&ent=Quote

DEBUG|[MF] pageRefSystem.PageReference[/0Q0/e?ent=Quote&oppid=006S00000070yVM&RecordType=012S00000004fibIAA&retURL=%2F006S00000070yVM]

Thank you!

Has anyone successfully created a VF page to replace the standard record type selection page?

I have two record types for the standard Quote object. Rather than having the user use the standard record type selection page when they click "New Quote", I want them redirected to a VF page. On this VF page there will be two buttons - a button called "Proposal" to create a Quote with record type A, and one called "Insertion Order" to create a Quote with record type B.

I've tried reading the previous posts about this, but most are from a few years ago and don't seem to offer working solutions.

I've created a page and controller extension, but it is only working if I hardcode in the Opportunity ID. Is there going to be any way for me to get this Opp ID programmatically? Thank you!

VF Page
<apex:page standardController="Quote" extensions="NewMediaPlanExtension" recordSetVar="quotes">
    <apex:form >
        <p style="font-size:25px"> What type of Media Plan are you creating?</p>
        <br/>
        <apex:commandButton action="{!newProposal}" value="Proposal"/>
    </apex:form>
</apex:page>

Controller
public with sharing class NewMediaPlanExtension {
public ApexPages.StandardSetController sController{get;set;}

public NewMediaPlanExtension(ApexPages.StandardSetController controller){
  sController = controller;
}

public PageReference newProposal(){
  String prefix = Quote.SObjectType.getDescribe().getKeyPrefix();
  String param = 'oppid=006S00000070yVM&RecordType=012S00000004fib';
  return new PageReference('/'+prefix+'/e?noovverride=1&' + param);
}

}

Hi - is it possible to top align a cell in an apex:pageBlockTable, or am I going to have to try and build my own html table instead of using the pageBlockTable?
I'm writing a unit test where I need to assign a territory to a test user. However, DML is not allowed on the UserTerritory object. Is my only option to query for an actual user in the database?
My company is looking to hire a talented senior software engineer and Force.com developer to lead development in our highly customized Salesforce instance. Quantcast uses Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.

This is an opportunity to combine your software engineering capabilities with deep Force.com knowledge to dramatically evolve the platform that people throughout Quantcast rely on and has major implications for our productivity and growth.

A little bit about us: Quantcast is a digital advertising company specialized in audience measurement and real-time advertising. As the pioneer of direct audience measurement in 2006, Quantcast has today the most in-depth understanding of digital audiences across the web, allowing marketers and publishers to make the smartest choices as they buy and sell the most effective targeted advertising on the market. For more information about Quantcast, please visit: https://www.quantcast.com/word

If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it.  Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=oQpiXfwe
I want to have a date field on a visualforce page that does use a calendar widget, but does not include the current date link adjacent to the input field. I tried adding the showdatePicker="false" attribute, but this gets rid of BOTH the calendar widget and current date link.

<apex:inputField value="{!s.CampaignSTARTDate__c}" style="width:70px" required="true" showdatePicker="false" />

When I then added the type="date" attribute, I got the following error message:
Attribute 'type' on component <apex:inputField> in '/apex/quoteLineItemEntryOption4' requires HTML docType version 5.0 or higher in quoteLineItemEntryOption4 at line 183 column 138

I'm not sure of the implications of changing the docType to version 5.0 and I don't like the way the field looks with that type, so I'd prefer not to do it this way. Does anyone know any other workarounds?

Thanks!
I'm trying to build a Visualforce page where as soon as a picklist value is selected/changed, the value is passed to a method in the controller to be used in a dynamic SOQL query. However, I'm having trouble getting the value passed to the controller. I've used this blog post as a starting point, http://blog.jeffdouglas.com/2010/07/13/building-a-dynamic-search-page-in-visualforce/, but I need to use apex:inputField instead because I need to keep the dependent pick lists intact.

When I change the value of TestInventoryType__c I get the alert that the doSearch() function is called, but my second alert comes back null. I would really appreciate if someone could tell me why this is coming back null, and if there is a better way to do this. How could I go about binding the value selected in the Inventory Type picklist to a property in the controller? I need all of this to happen when the picklist value changes without hitting any sort of command button. Thank you!

Here is a snippet of the VF page. The two most relevant lines are bolded:

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">


  <table width="100%" border="0">

  <tr>

    <td width="275" valign="top">

      <!-------This is the Search by picklist section-------------------------->

      <apex:pageBlock title="Search" mode="edit" id="criteria">



      <script type="text/javascript">

      function doSearch() {

        alert('doSearch function');

        alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL

            searchServer(

            document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex].value,

            document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex].value,

            document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex].value,

            document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value

        );

       
      }

      </script>

     <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">

          <apex:param name="creativeFamily" value="" />

          <apex:param name="creativeTypes" value="" />

          <apex:param name="pricingModel" value="" />

          <apex:param name="targetingOption" value="" />

      </apex:actionFunction>


     <apex:pageBlockSection columns="1">

         <apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>
I am trying to use Jeff Douglas' post about dynamic searching and use picklists to search, but I can't get the page to re-render after I have made a selection in the picklist. I've looked through various other posts about this and haven't been able to find anything that works for me. Does anyone see what is going wrong? I think it has to do with doSearch() function not actually being called when changing a picklist value.

Any feedback is much appreciated, thank you!!

Here is my controller class:
public with sharing class quoteLineItemEntryExtensionOption4 {
   
    public Quote theQuote {get;set;}
    public Pricebook2 theBook {get;set;}
   
    private Boolean forcePricebookSelection = false;
    //the soql without the order and limit
    private String soql {get;set;}
   
    //the collection of products to display
    public List<priceBookEntry> availableProducts {get;set;}
   
    //the current sort direction. defaults to asc
    public String sortDir{
        get{
            if (sortDir == null){
                sortDir = 'asc';
            }
            return sortDir;
        }
        set;          
    }
   
    // the current field to sort by. defaults to Quote name
    public String sortField {
        get{
            if (sortField == null){
                sortField = 'Quote';
            }
            return sortField;
        }
        set;
    }
   
    // format the soql for display on the visualforce page
    public String debugSoql {
        get{
            return soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/;
        }
        set;
    }
   
    // init the controller and display some sample data when the page loads
    public quoteLineItemEntryExtensionOption4(ApexPages.StandardController controller){
   
        //get information about the Quote being worked on
        theQuote = database.query('select Id, Pricebook2Id,Pricebook2.Name,CurrencyISOCode from Quote where Id = \'' + controller.getRecord().Id + '\' limit 1');
       
        //Check if the Opp has a pricebook associated yet
        if(theQuote.Pricebook2Id == null){
            Pricebook2[] activepbs = [select ID, Name FROM Pricebook2 WHERE isActive = true limit 2];
            if(activepbs.size() == 2){
                forcePriceBookSelection = true;
                theBook = new Pricebook2();
            } else {
                theBook = activepbs[0];
            }
        }
        else{
            theBook = theQuote.Pricebook2;       
        }
        //this soql just shows the initial results when page is loaded
        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Product2.CreativeFamily__c != null and Pricebook2Id = \'' + theBook.Id + '\'';
        runQuery();
    }
   
    // toggles the sorting of query from asc<-->desc
    public void toggleSort() {
        // simply toggle the direction
        sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
        // run the query again
        runQuery();
    }
   
    // runs the actual query
    public void runQuery() {
        try {
            availableProducts = Database.query(soql  /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/);
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops! There are no results for this search'));
        }
    }
   
    // runs the search with parameters passed via Javascript
    public PageReference runSearch() { 

        String creativeFamily = Apexpages.currentPage().getParameters().get('creativeFamily');
        String creativeTypes = Apexpages.currentPage().getParameters().get('creativeTypes');
        String pricingModel = Apexpages.currentPage().getParameters().get('pricingModel');
        String targetingOptions = Apexpages.currentPage().getParameters().get('targetingOptions');

        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';
        if (!creativeFamily.equals(''))
            soql += ' and Product2.CreativeFamily__c LIKE (\''+creativeFamily+'\')';
        if (!creativeTypes.equals(''))
            soql += ' and Product2.CreativeType__c LIKE (\''+creativeTypes+'\')';
        if (!pricingModel.equals(''))
            soql += ' and Product2.pricingModel__c LIKE (\''+pricingModel+'\')'; 
        if (!targetingOptions.equals(''))
            soql += ' and Product2.TargetingOptions__c LIKE (\''+targetingOptions+'\')';

        // run the query again
        System.debug('[MF] running the query from runSearch method' + soql);
        runQuery();

        return null;
    }
   
    //use apex describe to build the picklist values for Creative Family
    public List<String> creativeFamily{
        get{
            if(creativeFamily == null){
                creativeFamily = new List<String>();
                Schema.DescribeFieldResult field = Product2.CreativeFamily__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeFamily.add(f.getLabel());
                }               
            }
            return creativeFamily;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Creative Type
    public List<String> creativeType{
        get{
            if(creativeType == null){
                creativeType = new List<String>();
                Schema.DescribeFieldResult field = Product2.creativeType__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeType.add(f.getLabel());
                }               
            }
            return creativeType;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Pricing Model
    public List<String> pricingModel{
        get{
            if(pricingModel == null){
                pricingModel = new List<String>();
                Schema.DescribeFieldResult field = Product2.pricingModel__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    pricingModel.add(f.getLabel());
                }               
            }
            return pricingModel;
        }
        set;
    }
   
    //use apex describe to build the picklist values
    public List<String> targetingOptions{
        get{
            if(targetingOptions == null){
                targetingOptions = new List<String>();
                Schema.DescribeFieldResult field = Product2.TargetingOptions__c.getDescribe();
               
                for(Schema.PicklistEntry f : field.getPickListValues()){
                    targetingOptions.add(f.getLabel());
                }
            }
            return targetingOptions;
        }
        set;
    }

}

Here is my VF page:
<apex:page standardController="Quote" extensions="quoteLineItemEntryExtensionOption4" sidebar="false">

  <apex:form >
  <apex:pageMessages id="errors" />

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">

  <table width="100%" border="0">
  <tr> 
    <td width="200" valign="top">

      <apex:pageBlock title="Search" mode="edit" id="criteria">

      <script type="text/javascript">
      function doSearch() {
        searchServer(
          document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex.]value,
          document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex.]value,
          document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex.]value,
          document.getElementById("targetingOptions").options[document.getElementById("targetingOptions").selectedIndex].value
          );
      }
      </script>

      <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
          <apex:param name="creativeFamily" value="" />
          <apex:param name="creativeTypes" value="" />
          <apex:param name="pricingModel" value="" />
          <apex:param name="targetingOptions" value="" />
      </apex:actionFunction>

      <table cellpadding="2" cellspacing="2">
      <tr>
        <td style="font-weight:bold;">Creative Family<br/>
          <select id ="creativeFamily" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeFamily}" var="cFamily">
              <option value="{!cFamily}">{!cFamily}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Creative Type<br/>
          <select id ="creativeType" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeType}" var="cType">
              <option value="{!cType}">{!cType}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Pricing Model<br/>
          <select id ="Pricing Model" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!pricingModel}" var="pm">
              <option value="{!pm}">{!pm}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Targeting Options<br/>
          <select id="targetingOptions" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!targetingOptions}" var="targeting">
              <option value="{!targeting}">{!targeting}</option>
            </apex:repeat>
          </select>
        </td>
      </tr>
      </table>

      </apex:pageBlock>

    </td>
    <td valign="top">

    <apex:pageBlock title="Available Products To Add" mode="edit" id="results">

        <apex:pageBlockTable value="{!availableProducts}" var="product">
            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Product Name" action="{!toggleSort}" reRender="results,debug">
                        <apex:param name="sortfield" value="Product2.Name" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.Name}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Family" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeFamily__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeFamily__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Type" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeType__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeType__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Pricing Model" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.pricingModel__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.PricingModel__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Targeting Options" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.targetingOptions" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.TargetingOptions__c}"/>
            </apex:column>

        </apex:pageBlockTable>

    </apex:pageBlock>

    </td>
  </tr>
  </table>
 
  <apex:pageBlock title="Selected Products">
 
  </apex:pageBlock>


  <apex:pageBlock title="Debug - SOQL" id="debug">
      <apex:outputText value="{!debugSoql}" />          
  </apex:pageBlock>   

  </apex:pageBlock>

  </apex:form>

</apex:page>

I have a class that compares the values of fields on two different Opportunities, and if they have different values some logic occurs. Right now I am using a long list of "IF" statements, but I've been tasked to make it more efficient. Here is a sample of the code right now:

 

//check each field to see if has a different value from the cloned from opp.
//I'm doing this one field at a time, because they have to be added to the Whats Changed field in a specific (page layout) order
//also, a few fields will be treated differently in terms of what goes into the What's Changed field
    if(opp.ClientStrategist__c != clonedFromOpp.ClientStrategist__c){          
        Changes.add(createChangeStringNoChangeDisplay(Opportunity.ClientStrategist__c, fieldToLabel, 'Opportunity'));
    }
            
    if(opp.AccountId != clonedFromOpp.AccountId){
        Changes.add(createChangeStringNoChangeDisplay(Opportunity.AccountId, fieldToLabel, 'Opportunity'));
    }
            
    if(opp.Buyer__c != clonedFromOpp.Buyer__c){
        Changes.add(createChangeStringDisplayChanges(Opportunity.Buyer__c, fieldToLabel, clonedFromOpp.Buyer__c));
    }
            
    if(opp.Agency__c != clonedFromOpp.Agency__c){              
        Changes.add(createChangeStringNoChangeDisplay(Opportunity.Agency__c, fieldToLabel, 'Opportunity'));
    }

 

I want to try and change it so that rather than creating an IF statement for each field, I use a for loop to check each one. Something along the lines of:

 

List<sObjectField> fieldsList = new List<sObjectField>{
    Opportunity.ClientStrategist__c,
    Opportunity.AccountId,
    Opportunity.Buyer__c            
};
            
for(String field: fieldsList){
    if(opp.field != clonedFromOpp.field){
        Changes.add(creativeChangeStringDisplayChanges(field, fieldToLabel, clonedFromOpp.field, 'Opportunity')
    }
}

The issue I'm having is that in some parts I need the sObject Field name (i.e. 'Opportunity.ClientStrategist__c) and in other places I need the variable (i.e. 'opp.ClientStrategist__c).

 

Is there any way I can use the sObject Field name to get the variable? For example, in java I think we chould use something like 

opp.getField(field). Is there something similar in Apex?

 

Thank you in advance for any help!

Quantcast (http://www.quantcast.com) is seeking a a talented Force Engineer to design and develop complex technical solutions in our highly customized Salesforce instance.

We use Salesforce extensively across all aspects of the company, including Sales, Campaign Management and Engineering, making it one of the most critical systems for scaling and running our business.

Responsibilities
  • Build flexible, scalable and robust technical solutions to meet dynamic needs of fast-growing and fast-paced business
  • Design, development and deploy complex solutions in our Salesforce instance
  • Build and expand integrations to Salesforce
  • Conduct peer code reviews
  • Analyze and develop solutions to end-user support issues
A little bit about us: Quantcast is a digital advertising company specialized in audience measurement and real-time advertising. As the pioneer of direct audience measurement in 2006, Quantcast has today the most in-depth understanding of digital audiences across the web, allowing marketers and publishers to make the smartest choices as they buy and sell the most effective targeted advertising on the market. For more information about Quantcast, please visit: https://www.quantcast.com/word

If you are interested or know of anyone that would be a fit, I would welcome the opportunity to speak with you about it.  Here is the link to the job description and to apply online: https://www.quantcast.com/careers/job/?jobid=ot6DYfwU
Hi - is it possible to top align a cell in an apex:pageBlockTable, or am I going to have to try and build my own html table instead of using the pageBlockTable?

We have a formula field, GrossBudget__c, that should only be displayed on the layout if a certain condition is true. I don't want to create a visualforce page to replace the entire standard layout. Is it possible to achieve this by creating a visualforce page for just GrossBudget__c and add in a condition that it should only be visible under a certain condition? And then we can just place that mini visualforce page on the standard layout?

 

If anyone can let me know if this is even possible or point me in the direction of any documentation or blog posts on this it would be greatly appreciated!

I've right justified a numerical column in an apex:pageblocktable, but it's right next to a text column that is left-justified. I want to add a bit of extra spacing between the two columns, but nothing seems to be working. Below are two things I've tried (I've only included the relevant markup) - can anyone please point out where I'm going wrong?

Thanks!
 
        .number{
            text-align: right;
        }
        .ruiColumnWidth{
            width: 15%;
        }
        .ruiMonthEven{
            background: #F5F5F5;
        }
        .ruiMonthOdd{
        }

<apex:pageBlockTable value="{!ruiWrappers}" var="wrapper" cellpadding="5">
     <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number">
          <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/>
     </apex:column>
     <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}">
            <apex:outputText value="{!wrapper.ruiProbability}"/>
     </apex:column>
</apex:pageBlockTable>
.number{
    text-align: right;
    padding-right: 5px;
}
.ruiColumnWidth{
    width: 15%;
}
.ruiMonthEven{
    background: #F5F5F5;
}
.ruiMonthOdd{
}

<apex:pageBlockTable value="{!ruiWrappers}" var="wrapper">
     <apex:column headerValue="Amount" styleClass="number ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}" headerClass="number">
          <apex:outputField value="{!wrapper.rui.RuiPipeline__c}"/>
     </apex:column>
     <apex:column headerValue="Probability" styleClass="ruiColumnWidth {!IF(wrapper.monthType == 'Even', 'ruiMonthEven', 'ruiMonthOdd')}">
            <apex:outputText value="{!wrapper.ruiProbability}"/>
     </apex:column>
</apex:pageBlockTable>

User-added image
 
I have a project that includes the requirement for the following process: a user clicks a salesforce button, and under certain conditions, a pop-up window appears. On that window should be two, dependent picklist fields. Once they complete those fields and click "Ok", the values in those fields should be mapped to the corresponding fields in Salesforce. If they click that button again under the same conditions, the values they have already selected should default.

I know this is possible using a custom button which re-directs the user to a Visualforce page (so not quite a pop-up) and uses apex:inputFields. However, does anyone know if this would be possible using a custom button that executes JavaScript on click? I'm just not sure if it would be too much overkill to build the dependent picklists on this pop-up page or if there is an easy way to grab the information from the Salesforce fields.

I'm not really looking for the code here, just general thoughs on if this approach is even possible/worth considering.

Thanks!
I have a custom clone button on an Opportunity visualforce page that when clicked, should 1) confirm that they want to clone the Opportunity 2) check if certain records in the system exist, 3) if they do exist, have the user again click ok to confirm that they want to clone or cancel 3) if the user clicked ok, clone the Opportunity. I tried to use javascript remoting for the first time, and I think it's causing my action method to not fire.

If I click the 'Copy Opportunity without Media Plan' button, both confirmation pop-up alerts are displayed to the user, but nothing happens when they click 'OK.' If I click the 'Copy Opportunity without Media Plan 2' button, which does not have the remote action, the first confirmation pop-up is displayed, and when they click 'OK' the Opportunity clones.

Will javascript remoting not work in this scenario? It's my first time using it, so I don't understand it fully. Do I need to use action:function instead?

Thanks for the help!

Snippet Visualforce Page:
<script type="text/javascript">
        //confirm that they want to clone the Opportuntiy
        function confirmOppOnlyClone(){
            return confirm('Do you want to copy this Opportunity only?');
        }

        //check if other opportunities have been cloned from this one
        function duplicateOppsCheck(){
            var oppId = "{!opportunity.Id}";
            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.OpportunityExtension.duplicateOppsCheck}',
                oppId, function(result, event) {
                    if(event.status){
                        if (result != null){
                            return confirm(result);
                        }
                    }
                }
            );
        }
    </script>

<apex:form >
    <apex:sectionHeader subtitle="{!opportunity.Name}" title="Opportunity"/>
    <apex:pageMessages />
    <apex:pageBlock >
        <apex:pageBlockButtons >

            <apex:commandButton value="Copy Opportunity without Media Plan" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;if(!duplicateOppsCheck()) return false"/>

            <apex:commandButton value="Copy Opportunity without Media Plan 2" title="Click this to copy the Opportunity only" action="{!cloneRecord}" onClick="if(!confirmOppOnlyClone()) return false;"/>

Snippet of Controller Extension: 
@RemoteAction
    public static String duplicateOppsCheck (String opportunityId){


        String confirmMessage = 'There is an existing Opportunity that has been copied from this Opportunity. Please confirm that it is not a duplicate.\n\n';
        Boolean returnConfirmMessage = false;

        //if there are any existing opportunities that were copied from the current one, add their names and urls to the confirmation message
        for(Opportunity opp : [SELECT Id, Name FROM Opportunity WHERE ClonedFrom__c =: opportunityId]){
            confirmMessage += 'Name: '+opp.Name +'\n';
            confirmMessage += System.URL.getSalesforceBaseURL().toExternalForm()+'/'+opp.id + '\n\n';
            returnConfirmMessage = true;
        }

        if(returnConfirmMessage){
            return confirmMessage;
        }

        return null;
    }

 
I'm having a lot of issues with the developer console when checking test coverage, and I don't know if it is a bug with the console or something wrong with my code. 

1) I run the test in the developer console. The Test Run log is not actually showing up unless I completely close the developer console and then re-open it.
2) After running the test (it succeeds), in the overall code coverage box,  the class says 100%
3) I double click on the class name in the overall code coverage box and it goes to 0%
4) When I look at the drop down of tests for that class, it shows me the following:

All Tests 0%
Test_QuoteLineITemEntryExtension.testSaveMethods 52%
Test_QuoteLineItemEntryExtension.testControllerWithParameters 36%

Why would it be showing 0% for all tests if individual methods provide coverage? Also, there is no red/blue highlighting in the class to show me what is or is not covered.

Has anyone run into this before? It's driving me crazy! Would be happy to post my test class if that helps. Thanks!
Hi - is it possible to top align a cell in an apex:pageBlockTable, or am I going to have to try and build my own html table instead of using the pageBlockTable?
I'm writing a unit test where I need to assign a territory to a test user. However, DML is not allowed on the UserTerritory object. Is my only option to query for an actual user in the database?
I want to have a date field on a visualforce page that does use a calendar widget, but does not include the current date link adjacent to the input field. I tried adding the showdatePicker="false" attribute, but this gets rid of BOTH the calendar widget and current date link.

<apex:inputField value="{!s.CampaignSTARTDate__c}" style="width:70px" required="true" showdatePicker="false" />

When I then added the type="date" attribute, I got the following error message:
Attribute 'type' on component <apex:inputField> in '/apex/quoteLineItemEntryOption4' requires HTML docType version 5.0 or higher in quoteLineItemEntryOption4 at line 183 column 138

I'm not sure of the implications of changing the docType to version 5.0 and I don't like the way the field looks with that type, so I'd prefer not to do it this way. Does anyone know any other workarounds?

Thanks!
I'm trying to build a Visualforce page where as soon as a picklist value is selected/changed, the value is passed to a method in the controller to be used in a dynamic SOQL query. However, I'm having trouble getting the value passed to the controller. I've used this blog post as a starting point, http://blog.jeffdouglas.com/2010/07/13/building-a-dynamic-search-page-in-visualforce/, but I need to use apex:inputField instead because I need to keep the dependent pick lists intact.

When I change the value of TestInventoryType__c I get the alert that the doSearch() function is called, but my second alert comes back null. I would really appreciate if someone could tell me why this is coming back null, and if there is a better way to do this. How could I go about binding the value selected in the Inventory Type picklist to a property in the controller? I need all of this to happen when the picklist value changes without hitting any sort of command button. Thank you!

Here is a snippet of the VF page. The two most relevant lines are bolded:

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">


  <table width="100%" border="0">

  <tr>

    <td width="275" valign="top">

      <!-------This is the Search by picklist section-------------------------->

      <apex:pageBlock title="Search" mode="edit" id="criteria">



      <script type="text/javascript">

      function doSearch() {

        alert('doSearch function');

        alert(document.getElementById("creativeFamily")); //THIS COME BACK NULL

            searchServer(

            document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex].value,

            document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex].value,

            document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex].value,

            document.getElementById("targetingOption").options[document.getElementById("targetingOption").selectedIndex].value

        );

       
      }

      </script>

     <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">

          <apex:param name="creativeFamily" value="" />

          <apex:param name="creativeTypes" value="" />

          <apex:param name="pricingModel" value="" />

          <apex:param name="targetingOption" value="" />

      </apex:actionFunction>


     <apex:pageBlockSection columns="1">

         <apex:inputField value="{!Quote.TestInventoryType__c}" id="creativeFamily" onchange="doSearch();"/>
I am trying to use Jeff Douglas' post about dynamic searching and use picklists to search, but I can't get the page to re-render after I have made a selection in the picklist. I've looked through various other posts about this and haven't been able to find anything that works for me. Does anyone see what is going wrong? I think it has to do with doSearch() function not actually being called when changing a picklist value.

Any feedback is much appreciated, thank you!!

Here is my controller class:
public with sharing class quoteLineItemEntryExtensionOption4 {
   
    public Quote theQuote {get;set;}
    public Pricebook2 theBook {get;set;}
   
    private Boolean forcePricebookSelection = false;
    //the soql without the order and limit
    private String soql {get;set;}
   
    //the collection of products to display
    public List<priceBookEntry> availableProducts {get;set;}
   
    //the current sort direction. defaults to asc
    public String sortDir{
        get{
            if (sortDir == null){
                sortDir = 'asc';
            }
            return sortDir;
        }
        set;          
    }
   
    // the current field to sort by. defaults to Quote name
    public String sortField {
        get{
            if (sortField == null){
                sortField = 'Quote';
            }
            return sortField;
        }
        set;
    }
   
    // format the soql for display on the visualforce page
    public String debugSoql {
        get{
            return soql /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/;
        }
        set;
    }
   
    // init the controller and display some sample data when the page loads
    public quoteLineItemEntryExtensionOption4(ApexPages.StandardController controller){
   
        //get information about the Quote being worked on
        theQuote = database.query('select Id, Pricebook2Id,Pricebook2.Name,CurrencyISOCode from Quote where Id = \'' + controller.getRecord().Id + '\' limit 1');
       
        //Check if the Opp has a pricebook associated yet
        if(theQuote.Pricebook2Id == null){
            Pricebook2[] activepbs = [select ID, Name FROM Pricebook2 WHERE isActive = true limit 2];
            if(activepbs.size() == 2){
                forcePriceBookSelection = true;
                theBook = new Pricebook2();
            } else {
                theBook = activepbs[0];
            }
        }
        else{
            theBook = theQuote.Pricebook2;       
        }
        //this soql just shows the initial results when page is loaded
        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Product2.CreativeFamily__c != null and Pricebook2Id = \'' + theBook.Id + '\'';
        runQuery();
    }
   
    // toggles the sorting of query from asc<-->desc
    public void toggleSort() {
        // simply toggle the direction
        sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
        // run the query again
        runQuery();
    }
   
    // runs the actual query
    public void runQuery() {
        try {
            availableProducts = Database.query(soql  /*+ ' order by ' + sortField + ' ' + sortDir + ' limit 20'*/);
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops! There are no results for this search'));
        }
    }
   
    // runs the search with parameters passed via Javascript
    public PageReference runSearch() { 

        String creativeFamily = Apexpages.currentPage().getParameters().get('creativeFamily');
        String creativeTypes = Apexpages.currentPage().getParameters().get('creativeTypes');
        String pricingModel = Apexpages.currentPage().getParameters().get('pricingModel');
        String targetingOptions = Apexpages.currentPage().getParameters().get('targetingOptions');

        soql = 'select Id, Pricebook2Id, IsActive, Product2.Name, Product2.Segment__c, Product2.CreativeType__c, Product2.CreativeFamily__c, Product2.PricingModel__c, Product2.TargetingOptions__c, Product2.IsActive, Product2.Description, UnitPrice from PricebookEntry where IsActive=true and CurrencyISOCode = \'' + theBook.CurrencyISOCode + '\' and Pricebook2Id = \'' + theBook.Id + '\'';
        if (!creativeFamily.equals(''))
            soql += ' and Product2.CreativeFamily__c LIKE (\''+creativeFamily+'\')';
        if (!creativeTypes.equals(''))
            soql += ' and Product2.CreativeType__c LIKE (\''+creativeTypes+'\')';
        if (!pricingModel.equals(''))
            soql += ' and Product2.pricingModel__c LIKE (\''+pricingModel+'\')'; 
        if (!targetingOptions.equals(''))
            soql += ' and Product2.TargetingOptions__c LIKE (\''+targetingOptions+'\')';

        // run the query again
        System.debug('[MF] running the query from runSearch method' + soql);
        runQuery();

        return null;
    }
   
    //use apex describe to build the picklist values for Creative Family
    public List<String> creativeFamily{
        get{
            if(creativeFamily == null){
                creativeFamily = new List<String>();
                Schema.DescribeFieldResult field = Product2.CreativeFamily__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeFamily.add(f.getLabel());
                }               
            }
            return creativeFamily;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Creative Type
    public List<String> creativeType{
        get{
            if(creativeType == null){
                creativeType = new List<String>();
                Schema.DescribeFieldResult field = Product2.creativeType__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    creativeType.add(f.getLabel());
                }               
            }
            return creativeType;
        }
        set;
    }
   
    //use apex describe to build the picklist values for Pricing Model
    public List<String> pricingModel{
        get{
            if(pricingModel == null){
                pricingModel = new List<String>();
                Schema.DescribeFieldResult field = Product2.pricingModel__c.getDescribe();
               
                for(Schema.Picklistentry f : field.getPickListValues()){
                    pricingModel.add(f.getLabel());
                }               
            }
            return pricingModel;
        }
        set;
    }
   
    //use apex describe to build the picklist values
    public List<String> targetingOptions{
        get{
            if(targetingOptions == null){
                targetingOptions = new List<String>();
                Schema.DescribeFieldResult field = Product2.TargetingOptions__c.getDescribe();
               
                for(Schema.PicklistEntry f : field.getPickListValues()){
                    targetingOptions.add(f.getLabel());
                }
            }
            return targetingOptions;
        }
        set;
    }

}

Here is my VF page:
<apex:page standardController="Quote" extensions="quoteLineItemEntryExtensionOption4" sidebar="false">

  <apex:form >
  <apex:pageMessages id="errors" />

  <apex:pageBlock title="MANAGE MEDIA PLAN FLIGHTS" mode="edit">

  <table width="100%" border="0">
  <tr> 
    <td width="200" valign="top">

      <apex:pageBlock title="Search" mode="edit" id="criteria">

      <script type="text/javascript">
      function doSearch() {
        searchServer(
          document.getElementById("creativeFamily").options[document.getElementById("creativeFamily").selectedIndex.]value,
          document.getElementById("creativeTypes").options[document.getElementById("creativeTypes").selectedIndex.]value,
          document.getElementById("pricingModel").options[document.getElementById("pricingModel").selectedIndex.]value,
          document.getElementById("targetingOptions").options[document.getElementById("targetingOptions").selectedIndex].value
          );
      }
      </script>

      <apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,debug,errors">
          <apex:param name="creativeFamily" value="" />
          <apex:param name="creativeTypes" value="" />
          <apex:param name="pricingModel" value="" />
          <apex:param name="targetingOptions" value="" />
      </apex:actionFunction>

      <table cellpadding="2" cellspacing="2">
      <tr>
        <td style="font-weight:bold;">Creative Family<br/>
          <select id ="creativeFamily" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeFamily}" var="cFamily">
              <option value="{!cFamily}">{!cFamily}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Creative Type<br/>
          <select id ="creativeType" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!creativeType}" var="cType">
              <option value="{!cType}">{!cType}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Pricing Model<br/>
          <select id ="Pricing Model" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!pricingModel}" var="pm">
              <option value="{!pm}">{!pm}</option>
            </apex:repeat>
          </select>       
        </td>
      </tr>
      <tr>
        <td style="font-weight:bold;">Targeting Options<br/>
          <select id="targetingOptions" onchange="doSearch();">
            <option value=""></option>
            <apex:repeat value="{!targetingOptions}" var="targeting">
              <option value="{!targeting}">{!targeting}</option>
            </apex:repeat>
          </select>
        </td>
      </tr>
      </table>

      </apex:pageBlock>

    </td>
    <td valign="top">

    <apex:pageBlock title="Available Products To Add" mode="edit" id="results">

        <apex:pageBlockTable value="{!availableProducts}" var="product">
            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Product Name" action="{!toggleSort}" reRender="results,debug">
                        <apex:param name="sortfield" value="Product2.Name" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.Name}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Family" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeFamily__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeFamily__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Creative Type" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.creativeType__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.CreativeType__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Pricing Model" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.pricingModel__c" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.PricingModel__c}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">
                    <apex:commandLink value="Targeting Options" action="{!toggleSort}" rerender="results,debug">
                        <apex:param name="sortField" value="Product2.targetingOptions" assignTo="{!sortField}"/>
                    </apex:commandLink>
                </apex:facet>
                <apex:outputField value="{!product.Product2.TargetingOptions__c}"/>
            </apex:column>

        </apex:pageBlockTable>

    </apex:pageBlock>

    </td>
  </tr>
  </table>
 
  <apex:pageBlock title="Selected Products">
 
  </apex:pageBlock>


  <apex:pageBlock title="Debug - SOQL" id="debug">
      <apex:outputText value="{!debugSoql}" />          
  </apex:pageBlock>   

  </apex:pageBlock>

  </apex:form>

</apex:page>

I am trying to write a trigger that will create an activity when an opportunity reaches a certain stage.  I want the activity to be assigned to the owner of the opportunity and to be related to the opportunity, but when I try to assign values to the appropriate fields I get 'Field is not writeable' errors.  Here is the code with these fields commented out:

 

--------------------------------------------------------------------------------

trigger CreateActivityAfterClosedWon on Opportunity (after insert, after update) {
 
    List<Task> NewTasks = new List<Task>();
    for (Opportunity opp: Trigger.new){
        if (opp.StageName == '100 - Closed Won - Booked'){
                NewTasks.add(new Task(
                    ActivityDate = Date.today(),
                    //What = opp.Id,
                    //Owner = opp.Owner,
                    Status = 'Closed',
                    Activity_Type__c = 'Project Won',
                    Priority = 'Normal',
                    Subject = opp.Name));
        }
    }

    insert NewTasks;
}

--------------------------------------------------------------------------------------------

 

With these fields commented out, the trigger runs in the sand box and creates activities, but the activities are not related to any object and are assigned to me (because the code ran under my account).

 

Can anybody suggest a solution?


Thanks & Regards,

Jeff

I am using a standard controller extension to custom clone Opportunities. It will allow Opportunities to be cloned with their Opportunity Teams (among other objects). However, I'm having trouble getting the access level for the team member to clone as well. From looking at the community boards I know that I need to insert an OpportunityShare record as well, but that hasn't helped. Even if the team member had Read/Write access on the original Opp, on the clone they just have Read access.

 

Can anyone take a peek at my code below and let me know where I've gone wrong? Thanks!!

 

public class OpportunityCloneExtension{
     
    //Variable to hold current record
    Opportunity currentRecord;
     
    //Standard constructor method
    public OpportunityCloneExtension(ApexPages.StandardController controller){
        currentRecord = (Opportunity)controller.getRecord();
    } 
     
    public PageReference cloneRecord(){
        //Variable to hold the new record
        Opportunity newRecord;
        Savepoint sp = Database.setSavepoint();
         
        try{
            //------Cloning the Opportunity-----------
            //get all the creatable fields from the object so they can be cloned
            String oppSOQL = CSUtils.getCreatableFieldsSOQL('Opportunity',   'id=\''+currentRecord.id+'\'');
             
            //query for the current Opportunity and clone it, replacing a few field values first
            currentRecord = (Opportunity)Database.query(oppSOQL);
            newRecord = currentRecord.clone(false);
            newRecord.ApprovalStatus__c = Status.NotSubmitted;
            newRecord.Type = 'Existing Client: Campaign Renewal';
            newRecord.SalesPlanner__c = null;
            newRecord.RequestType__c = null;
            newRecord.DeliverableDueDate__c = null;
            newRecord.PORequired__c = null;
            newRecord.PONumber__c = null;
            newRecord.PrePay__c = null;
            newRecord.Campaign_Event__c = null;
            newRecord.ExistingConversionVolume__c = null;
             
            newRecord.ClonedFrom__c = currentRecord.id;
             
            insert newRecord;
          
            //--------Cloning the Opp Team Test--------
            List<OpportunityTeamMember> relatedTeamMembers = new List<OpportunityTeamMEmber>();
            for(OpportunityTeamMember tm : [SELECT OpportunityAccessLevel, OpportunityId, UserId, TeamMemberRole FROM OpportunityTeamMember WHERE OpportunityId =: CurrentRecord.id]){
                OpportunityTeamMember otm = tm.clone(false);
                otm.OpportunityID = newRecord.Id;
                relatedTeamMembers.add(otm);
            } 
            
            insert relatedTeamMembers;   
            
            List<OpportunityShare> relatedOppShare = new List<OpportunityShare>();
            for(OpportunityShare os : [SELECT OpportunityAccessLevel,OpportunityId,RowCause, UserOrGroupID FROM OpportunityShare WHERE OpportunityID =:CurrentRecord.id AND RowCause = 'Sales Team']){
                OpportunityShare nOS = os.clone(false);
                nOS.OpportunityID = newRecord.id;
                relatedOppShare.add(nOS);
                
            }
            
            insert relatedOppShare;    
           
         
        } catch(Exception e){
            Database.rollback(sp);
            ApexPages.addMessages(e);
            return null;
        }
         
        return new PageReference('/'+newRecord.id);
    }     
}

 

  • September 18, 2013
  • Like
  • 0

I have a trigger on Opportunity that updates a text field on the Opportunity called WhatChanged__c. It's comparing the values on two related Opportunities and seeing if they are different. I need to reference the Field Label in the WhatChanged__c value, and I want to make it dynamic so that if we change any field labels/api names in the future the code will automatically handle the change.

 

Here is the relevant part of trigger:

 

//continue if there are cloned Opps moving into the pending stage
    if(!pendingClonedOpps.isEmpty()){
//get all the labels for Opportunity fields and put them in a map, keyed to the field api name String objectType ='Opportunity'; Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe(); Schema.SObjectType leadSchema = schemaMap.get(objectType); Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap(); Map<String, String> fieldAPIName = new Map<String, String>(); for(String fieldName : fieldMap.keySet()){ fieldAPIName.put(fieldName, fieldMap.get(fieldName).getDescribe().getLabel()); } for(Opportunity opp : pendingClonedOpps){ //List to store all of the names of fields that have changed List<String> Changes = new List<String>(); //get the related Cloned Opportunity record Opportunity clonedFromOpp = ClonedOppIDToClonedOpp.get(opp.ClonedFrom__c); if(opp.Buyer__c != clonedFromOpp.Buyer__c){ String fieldName = 'buyer__c'; String Label = fieldAPIName.get(fieldName); String oldBuyer = clonedFromOpp.Buyer__c; Changes.add(Label+': '+oldBuyer); } opp.WhatChanged__c = CSUtils.join(Changes, ' '); }

It's working, but the part I'm not happy with is the line String fieldName = 'buyer__c'. If the API name for that field ever changes, I will need to update the fieldName variable. Is there a way to dynamically get the API name, in a similar way to how I am getting the field name? Can I create a Map that stores <Field, String>? This is my first time working with Describe.field() methods so I think I'm confusing myself!

 

Any help is much appreciated! Thanks!

  • September 11, 2013
  • Like
  • 0

I want to be able to query for all creatable fields on an object without having to hardcode each field into the SOQL query. I have a method that builds the SOQL query and it works great except for when the WHEN statement includes id in: a collection of records.

 

Here is the method:

/**
    *Returns a dynamic SOQL statement for the whole object, includes only creatable fields since we will be inserting a cloned result of this query
    */
    public static string getCreatableFieldsSOQL(String objectName, String whereClause){
        String selects = '';
        
        if(whereClause == null || whereClause == ''){
            return null;
        }
        
        //get a map of field names and field tokens
        Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(objectName.toLowerCase()).getDescribe().Fields.getMap();
        List<String> selectFields = new List<String>();
        
        if(fMap!=null){
            for(Schema.SObjectField ft : fMap.values()){ //loop through all field tokens (ft)
                Schema.DescribeFieldResult fd = ft.getDescribe(); //describe each field (fd)
                if (fd.isCreateable()){ //field is creatable
                    selectFields.add(fd.getName());
                }
            }
        }

 

Here is where I invoke the method:

String oppSOQL = CSUtils.getCreatableFieldsSOQL('Opportunity', 'id in' + clonedFromOppIDs);
        system.debug('[MF] oppSOQL: ' + oppSOQL);
        
        for(Opportunity opp : (List<Opportunity>)Database.query(oppSOQL)){
            ClonedOppIDtoClonedOpp.put(opp.id, opp);
        }

 "clonedFromOppIDs" is a set of Opportunity IDs. However, when I try to execute this code I get the error message: System.QueryException: unexpected token: '{' . This is the debug log (I removed most of the fields to make it easier to read):

 

16:56:07.493 (493363000)|USER_DEBUG|[28]|DEBUG|[MF] oppSOQL: SELECT ApprovedTerms__c,Rate_Type__c,WhatChanged__c FROM Opportunity WHERE id in{006Q000000BmT4XIAV}
16:56:07.493 (493388000)|SYSTEM_METHOD_EXIT|[28]|System.debug(ANY)
16:56:07.493 (493412000)|SYSTEM_METHOD_ENTRY|[30]|Database.query(String)
16:56:07.494 (494079000)|EXCEPTION_THROWN|[30]|System.QueryException: unexpected token: '{'

 

I've tried making the WHERE clause 'id in: ' + clonedFromOppIDs but I get the same error message. Does anyone know if there is anyway I can get around this? Or have other suggestions for how to systematically query all fields without typing each one it? Any help would be much appreciated, thank you!!

  • September 10, 2013
  • Like
  • 0

I have a VF page and Controller Extension that allows me to clone a custom object (ProposalFlight__c) record. The ProposalFlight__c record has a lookup field to another custom object, called Geo__c. Using the VF page (which overrides the custom clone button) and the Controller Extension, I am able to clone both ProposalFlight__c and Geo__c at the same time. However, I'm really struggling with creating the unit test for the controller extension.

 

VF Page:

<apex:page standardController="ProposalFlight__c" extensions="ProposalFlightCloneExtension" 
    action="{!cloneRecord}">
    <apex:pageMessages />
</apex:page>

 

Controller Extension (I've replaced the fields that are actually in the queury with (all Fields) just to make it reasier to read here):

 

public class ProposalFlightCloneExtension{
    
    //Variable to hold current record
     ProposalFlight__c currentRecord;
     
     //Standard constructor method
     public ProposalFlightCloneExtension(ApexPages.StandardController controller){
         currentRecord = (ProposalFlight__c)controller.getRecord();
     } 
     
      public PageReference cloneRecord(){
         //Variable to hold the new record
         ProposalFlight__c newRecord;
         Savepoint sp = Database.setSavepoint();
         
         try{
         
             //first clone the Geo Record
             Geo__c clonedGeo;
             
             for(Geo__c relatedGeo: [SELECT (All Fields) FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE id=: currentRecord.id)]){
                 Geo__c newGeo = relatedGeo.clone(false);
                 clonedGeo = newGeo;
             } 
             insert clonedGeo;
             
             //now clone the Proposal Flight
             currentRecord = [SELECT (All Fields) FROM ProposalFlight__c WHERE id=:currentRecord.id];
             newRecord = currentRecord.clone(false);
             newRecord.ApprovalStatus__c = Status.NotSubmitted;
             newRecord.ClonedFrom__c = currentRecord.id;
             newRecord.Geo__c = clonedGeo.ID;
             newRecord.GeoTargetSummary__c = clonedGeo.Text__c;
             insert newRecord;

         }catch(Exception e){
             Database.rollback(sp);
             ApexPages.addMessages(e);
             return null;
         }
         
         return new PageReference('/'+newRecord.id);
     }

}

 

 

My Unit Test so far:

 

@isTest (SeeAllData = True)
private class Test_ProposalFlightCloneExtension{
    
    static testMethod void testProposalFlightClone(){
    
        //create test data
        Account acct = UnitTestFactory.makeAccount();
        Opportunity opp = UnitTestFactory.makeMasterCPMOpp(acct.id);
        ProposalFlight__c pf = UnitTestFactory.makeCPMPF(opp.id);
        Geo__c geo = [SELECT Id FROM Geo__c WHERE Id in (SELECT Geo__c FROM ProposalFlight__c WHERE Id =: pf.Id)];
        
        //Go to Page
        Test.setCurrentPage(Page.ProposalFlightClone);
        
        //Set Parameters that would be passed in
        ApexPages.currentPage().getParameters().put('Id', pf.Id);
        
        //Instantiate a new controller with all parameters in place
        ProposalFlightCloneExtension ext = new ProposalFlightCloneExtension(new ApexPages.StandardController(pf));
        
        PageReference pageRef = Page.ProposalFlightClone;

    
    }

}

 The unit test passes, but is only covering 12% of the class. It doesn't cover any of the actual cloning logic. If anyone could point me in the right direction I would really appreciate it. Thank you!

 

  • September 05, 2013
  • Like
  • 0

Can anyone point me in the direction of any triggers that are used to automatically re-establish revenue schedules (for example, if the Opp Close Date changes). Is this even possible?

 

Thank you so much for the help!

Hi,

 

I have a visualforce page where I populate a PageBlockDataTable with a list<sObject> using StandardSetController.getRecords(). There are some fields in the table that are inputFields to allow edits. Pagination is implemented and works fine if nothing is edited.

 

I read that either cancel() or save() needs to be run before moving to another page otherwise visualforce will throw an error saying 'modified rows exist in the collection'. So when records are edited, I have a javascript that detect changes and prompts user whether to save or cancel before moving to next page, which then through calling actionFunction runs the StandardSetController's cancel() / save() and then next() / previous() / setPageNumber(x) in a method in the page's controller.

 

Problem: After running that, let's say cancel() and next(), getResultSize() becomes lesser and the collection shrunk. Although getPageNumber() appear to be working, something is wrong as there are lesser pages now in the paginated table. Debug log shows that getResultSize() has indeed become lesser after ApexPages.StandardSetController.cancel() is run.

 

Any idea what could be wrong? any feedback/solution recommended is much appreciated. Thanks.

 

 

I have functionality in a form so when the users click on the button, the button goes disabled. The only problem I have is that in a <apex:pageBlockButtons> block, where two sets of buttons are created, only the top set of buttons becomes disabled. This was put into place to prevent the users from double-clicking the buttons, however they end up double-clicking the lower set of buttons because those buttons do not become disabled.

 

         <apex:pageBlockButtons id="productButtons">
            <apex:actionStatus rendered="{!NOT(readOnly)}" id="applyButtonStatus">
               <apex:facet name="stop">
                  <apex:commandButton id="applyButtonActive" action="{!calcRevenue}" value="Apply Changes/Calculate Revenue" status="applyButtonStatus" disabled="false" rerender="productTypeSelectionBlock"/>
               </apex:facet>
               <apex:facet name="start">
                  <apex:commandButton id="applyButtonDisabled" action="{!calcRevenue}" value="Applying Changes..." status="applyButtonStatus" disabled="true" rerender="productTypeSelectionBlock"/>
               </apex:facet>
            </apex:actionStatus>
         </apex:pageBlockButtons>

 

Is there any way to get this to work inside of the pageBlockButtons block, or do I just have to create two sets of buttons? If I create two sets, then they'll disable independently of each other, which isn't ideal.