• steve_andersen
  • NEWBIE
  • 5 Points
  • Member since 2005

  • Chatter
    Feed
  • 0
    Best Answers
  • 2
    Likes Received
  • 0
    Likes Given
  • 29
    Questions
  • 66
    Replies
I am building a data entry form with 3 picklists--Account, Opportunity, and a custom child object of opportunity. The idea is you select an Account, and then get a picklist of all Opportunites, when you select an Opp, the child picklist shows up.

I built an interface like this in an scontrol and I'm now replacing it with VF.

I built a client object, which has an Account Id, Account Name, and a list of SelectOptions for available Opportunities:
public class client {
 public Id clientId;
 public String clientName {get{return clientName;} set{clientName = value;}}
 public List<SelectOption> projectOptions {get{return projectOptions;} 
set{projectOptions = value;}} public Map<Id,project> projects {get{return projects;} set{projects = value;}} public client() { projectOptions = new List<SelectOption>(); projects = new Map<Id,project>(); } }

On page load I build out a map of all my clients, each with it's projectOptions. When I debug the client object I get this:
001S0000003VuzSIAS=timesheetController.client: [
clientId=001S0000003VuzSIAS,
clientName=ONE/Northwest,
     projectOptions=(
          System.SelectOption[value="", label="- pick a project -", disabled="false"],     
          System.SelectOption[value="006S0000002JUkiIAG", label="ONE/Northwest 2008 Project", disabled="false"] ),
.
.
.

 But I can't get the project options to show in a picklist. The client picklist works, and when you change it, it rerenders the project section. But the project picklist is empty, and I can't get the project options that I know are there to show up.:

<tbody>
         
 <tr><th><apex:outputText value="AccountNew"/></th>
  <td>
   <apex:selectList value="{!newTaskLog.Account__c}" id="accountselect" 
multiselect="false" size="1"> <apex:selectOptions value="{!clientSelect}"/> <apex:actionSupport event="onchange"
action="{!setupFocusClient}" rerender="projectselect"/> </apex:selectList> </td></tr> <tr><th><apex:outputText value="ProjectNew"/></th> <td> <apex:outputPanel id="projectselect" > <apex:outputText value="{!focusClient.clientName}"/> <apex:selectList value="{!newTaskLog.Opportunity__c}"
multiselect="false" size="1"> <apex:selectOptions value="{!focusClient.projectOptions}"/> <apex:actionSupport event="onchange"
action="{!setupFocusProject}" rerender="taskSelect"/> </apex:selectList> </apex:outputPanel> </td></tr>

Any ideas about what I'm doing wrong?

Thanks,
Steve
 

I've got a need to break street addresses into their component parts. I start with:

MailingStreet: 2400 NW 63rd St
MailingCity: Seattle
MailingState: WA
MailingPostalCode: 98107

And convert it to this:

StreetNumber: 2400
StreetDirection: NW
StreetName: 63 rd
StreetType: St
City: Seattle
State: WA
Postal Code: 98107

The basic strategy is to regex the patterns. There are some libraries in other languages:

Java (http://jgeocoder.sourceforge.net/parser.html)
Python (http://mail.python.org/pipermail/python-list/2007-June/446215.html)
etc.

Anyone taken this on in Apex and want some help making it work?

Thanks,
Steve
Here's my use case for a sites app:

1. Send an email out to Contacts via sf.com
2. Include a "manage my subscriptions" link in the email that has the contact id in it
3. End user clicks on that URL and lands on a sites page
4. End user is asked to enter the email address for which they want to modify subscriptions.
5. If the email they enter matches the email on the contact record, the can
6. change some settings on their contact record and hit save to commit them

I had this working in the authenticated view, but can't get sites to allow me to modify contact records as a public user. I can see why sf.com might not want to allow that. But I also don't want to make a person authenticate for this task.

So I changed things to allow the user to create a custom object that manages the subscription, and then I have a trigger on that object to update the contact record with the changes. So in effect, they are modifying the contact, but with a custom object and a trigger in between.

However, Sites won't let me do this unauthenticated. The checkboxes on my custom object don't show on the vf page. I don't get "authorization required" but the fields just aren't there.

Is Sites seeing my trigger and disallowing my public user because it knows I am going to update a Contact? Or am I screwing things up in a different way?

Here is the page:
Code:
<apex:page Controller="ext_contact_subscriptions" showHeader="False" title="Manage Your Subscriptions" >
<!-- Begin Default Content REMOVE THIS -->
<div style="margin:10px">
<h1>Manage your Subscriptions</h1>
<p>Check what you want to receive from us!</p>
<apex:form >
 <apex:outputPanel id="emailLogin" layout="block" style="margin-left:10px;"> 
  <apex:outputPanel rendered="{!AND(NOT(emailVerified),NOT(success))}" >
   <apex:outputText value="Your email:"/>
   <apex:inputText value="{!enteredEmail}" />
   <apex:commandButton value="submit" action="{!validateEmail}" rerender="emailLogin,subscriptions"/>
  </apex:outputPanel>
  <apex:outputPanel rendered="{!validationError}" layout="block">
  <br/>
   <apex:outputText style="color:#ff0000;" value="That email did not match this subscription. Try another email address."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="subscriptions" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!AND(emailVerified,NOT(success))}">
   <h2>Change your Email if you Wish</h2>
   <br/><br/>
   <apex:outputText value="Your Email: " style="margin-left:10px;"/> <apex:inputField value="{!subscription.Email__c}" /><br/><br/>
   <h2>Your Subscriptions</h2>
   <br/><br/>
   <apex:inputField value="{!subscription.Monthly_eNewsletter__c}" /> <apex:outputText value="eNewsletter"/>
   <br/><br/>
   
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our monthly newsletter."/><br/><br/>
   <apex:inputField value="{!subscription.Action_Alerts__c}" /> <apex:outputText value="Action Alerts"/>
   <br/><br/>
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our periodic notifications about actions."/><br/><br/>
   <apex:commandButton action="{!save}" value="Save" rerender="emailLogin,subscriptions,success"/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="success" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!success}">
   <apex:outputText style="color:#666666;margin-left:10px;" value="Thanks for submitting your changes! They will go into effect immediately."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <!--figure out redirect-->

</apex:form>
</div>
</apex:page>


Here is the controller:

Code:
public class ext_contact_subscriptions {
 
 public Contact contact = new Contact();
 
 public Boolean emailVerified   { get; set; }
 public String enteredEmail    { get; set; }
 public Boolean success     { get; set; }
 public Boolean validationError   { get; set; }
 public string msg       { get; set; }
 
 public Subscription__c subscription { get {return subscription;} set {subscription = value;} }
  
 public ext_contact_subscriptions() {
        contact = [select id, email,Monthly_eNewsletter__c, Action_Alerts__c from contact where id = :ApexPages.currentPage().getParameters().get('id')];
        emailVerified = false;
        validationError = false;
        success = false;
        subscription = new Subscription__c();
        subscription.Contact__c = contact.Id;
        subscription.Email__c = contact.Email;
        subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
        subscription.Action_Alerts__c = contact.Action_Alerts__c;
    }
    
    public PageReference validateEmail() {
     //contact.email = 'steve@test.com';
     if (enteredEmail == contact.email) {
      emailVerified = true;
      validationError = false;
     } else {
      validationError = true; 
     }
     return null; 
    }
    
    
    public PageReference save() {
     
     try {
        // update contact;
       // subscription.contact__c = contact.Id;
     //   subscription.email__c = contact.email;
      //  subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
      //  subscription.Action_Alerts__c = contact.Action_Alerts__c;
        insert subscription;
        
         success = true;
        } catch (exception e) { 
         msg = e.getMessage(); 
        }
     
     return null; 
    }
}

 and here is the trigger:

Code:
trigger subscription_to_contact on subscription__c (after insert) {
 Map<Id,subscription__c> subsToKill = new Map<Id,subscription__c>();
 List<Contact> contactsToProcess = new List<Contact>();
 for (subscription__c sub : Trigger.new) {
  Contact contact = new Contact (    
   id=sub.contact__c,
   Email = sub.email__c,
   Action_Alerts__c = sub.Action_Alerts__c,
   Monthly_eNewsletter__c = sub.Monthly_eNewsletter__c
  );
  contactsToProcess.add(contact);
  subsToKill.put(sub.id,sub);
 }
 if(contactsToProcess.size()>0){
  try {
   update contactsToProcess;  
   //delete subsToKill.values();
        } catch (exception e) { 
         system.debug(e.getMessage()); 
        }  
 } 
}

 Thanks much!

Steve


 

The Winter '09 docs don't seem to have anything about governor limits with the @future call other than the fact you can only invoke 200 @future methods/day/org. I know one of the goals of the @future notation is to allow us to get around the current apex governor limits without killing sf.com servers.

Does anyone know what the @future limits will be? We're thinking of new functionality that would fit into @future methods and want to get a sense of what we'll be dealing with in regard to limits.

Thanks,
Steve
I've set up 3 VF pages to use one controller. As I navigate from page to page, certain state data is being held in variables in the controller. It generally works.

However, the URL in the address bar isn't showing the correct page. I start on page A and when I move to page B via a command link, the URL isn't updating. It appears to stay one page behind.

Here's an example of how I'm moving from one page to the next:
Code:
    public PageReference loadCallList() {
      //set the current campaign
     //set the list of members
  setCallListMembers();
  //redirect to the call list page
  
  return Page.callList;
 }

 If I set the Redirect parameter to true, the URL changes but I also lose my state information.

What am I missing about navigating between pages while not reinstantiating my controller?

Thanks,
Steve

I want to hit google's geocoding api from an @future class on a trigger so I can add lat and lon to records as they change. I have a couple questions:
  1. If I want to hit the rest interface for google's service, I need to supply an api key. Do I need to do anything special to get that key to work from salesforce.com servers? It asks me to identify the calling domain--should that be salesforce.com?
  2. The API will respond to one call every 2 seconds, equating to 50,000 calls a day. What's the best way to deal with that limiter in an apex class? I couldn't find a sleep function.
Thanks,
Steve
I'm just starting with the @future tag and added a future call to a Contact after insert trigger I've got. I added a call to a method which I plan to have geocode the Contact based on address, via a call out to google's geocoding service.

My method is very simple right now:
Code:
public class dataAugmentation { 
 @future
 public static void augmentAddresses(List<id> contactIdsToAugment) {
  List<Contact> ContactsToBeUpdated = new List<Contact>();
  for (Contact thisContact : [Select Id, OtherStreet,OtherCity,OtherState,OtherPostalCode,OtherCountry from Contact where Id IN :contactIdsToAugment]) { 
    thisContact.OtherCountry='Zanzibar';
    ContactsToBeUpdated.add(thisContact);
  
   //callout to web service
   //thisContactToAugment.Country='Zanzibar';
  }  
  update ContactsToBeUpdated;  
 }
}

 My code compiles and runs in the UI, but the future action (Country updated to 'Zanzibar') hasn't happened after an hour. When I try to modify the class that contains the future method, I get this error in the IDE:

Batchable class has jobs pending or in progress
dataAugmentation.cls
Winter 09 Preview/src/unpackaged/classes
line 1
Force.com save problem

I couldn't find any documentation about how future calls get batched and run, but if I had to interpret this error message I would guess that my updates are sitting in a queue waiting to run, and while that is happening, I can't modify the class.

Is that what is going on? Are there ways to monitor what future calls are waiting for execution?

Thanks,
Steve


I've got a wizard for creating a new Opp which I referenced in a previous post. I want the user to have the option of selecting an existing Contact to be the primary Contact on the Opp. On my VF page I need a Contact lookup and then on Save I'll create the ContactRole for the Opportunity and use that Contact Id.

Problem is that I don't think I can get an inputField lookup without instantiating an object and then binding to the field. I can instantiate an Opportunity Contact Role object, but Contact is required on that object so the lookup on my VF page has the big red required flag. Selecting a Contact isn't required for my wizard, so that won't work.

My workaround is to instantiate a completely unrelated custom object that happens to have a Contact lookup field on it. I catch the Contact Id in there, and then us it to create the Contact role. It works. But it's ugly. Sharing this code now just got harder because there is now this dependence on a custom object that has nothing to do with this solution.

Any ideas? Thanks!

Steve
<meta name="GENERATOR" content="BLOCKNOTE.NET">BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt }
I'm trying to do a dynamic page section like Jon outlined here, but I'm having trouble.
 
I want a user to select a radio, and then display a page section based on that value. I can get the section to render based on the conditional, but I can't get it to change when the radio button is changed. I'm clearly missing something.
 
Here is my radio:
<apex:actionRegion >        
  <apex:outputPanel >        
    <apex:outputLabel value="Apply Opportunity To" for="oppApplicantSelect"/>        
    <apex:selectRadio id="oppApplicantSelect" value="{!oppApplicant}">
      <apex:selectOption itemValue="Contact" itemLabel="Contact"/>
      <apex:selectOption itemValue="Organization" itemLabel="Organization"/>
      <apex:actionSupport event="onchange" rerender="orgSection" status="status"/>
    </apex:selectRadio>
    <apex:actionStatus startText="applying value...{!oppApplicant}" id="status"/>
  </apex:outputPanel>
</apex:actionRegion>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt }
and here is the part of the page I want to render:

<apex:pageBlock title="Organization info" id="orgSection"  rendered="{!oppApplicant == 'Organization'}">
  <apex:outputLabel value="Organization" for="accountField"/>
  <apex:inputField id="accountField" value="{!opportunity.AccountId}"/>
  <apex:outputText value="{!oppApplicant}"/>
</apex:pageBlock>

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } In my controller I've got a String set up to catch the Radio values:
Code:
public String oppApplicant { get {return oppApplicant;} set {oppApplicant = value;} }

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } And in my constructor, I'm setting oppApplicant if I have a querystring variable:
Code:
if(ApexPages.currentPage().getParameters().get('contactId')!=null) {
  oppApplicant = 'Contact';
} else {
  oppApplicant = 'Organization';
}

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } I'll paste the full code of the controller and page below. Thanks for any help!
 
Steve

Full Page:

Code:
<apex:page standardController="Opportunity" tabStyle="Opportunity" extensions="ONEN_controller_NewOppWizard">

   <script >
  //hack to override JavaScript that is setting focus on Date field 
  function setFocusOnLoad() {} 
 </script>
 <apex:sectionHeader title="New Opportunity" subtitle="Use this page to create an opportunity and set contact roles"/>
     <apex:form >
    <apex:pageBlock title="Contact and Organization">     
         <apex:actionRegion >         
          <apex:outputPanel >         
           <apex:outputLabel value="Apply Opportunity To" for="oppApplicantSelect"/>        
           <apex:selectRadio id="oppApplicantSelect" value="{!oppApplicant}">
      <apex:selectOption itemValue="Contact" itemLabel="Contact"/>
      <apex:selectOption itemValue="Organization" itemLabel="Organization"/>
      <apex:actionSupport event="onchange" rerender="orgSection" status="status"/>     
     </apex:selectRadio>
     <apex:actionStatus startText="applying value...{!oppApplicant}" id="status"/>
    </apex:outputPanel>    
   </apex:actionRegion>  
   <apex:outputLabel value="Primary Contact" for="contactField"/> 
   <apex:inputField id="contactField" value="{!conactRelationshipDummy.Contact__c}"/>
  </apex:pageBlock>
  <apex:pageBlock title="Organization info" id="orgSection"  rendered="{!oppApplicant == 'Organization'}">
   <apex:outputLabel value="Organization" for="accountField"/>
   <apex:inputField id="accountField" value="{!opportunity.AccountId}"/>
   <apex:outputText value="{!oppApplicant}"/>
  </apex:pageBlock>
  <apex:pageBlock >
   <apex:outputLabel value="Record Type" for="oppRecordType"/>
   <apex:selectList size="1" id="oppRecordType" value="{!oppRecordTypeId}">
    <apex:selectOptions value="{!recordTypeNameList}"/> 
   </apex:selectList>   
   <apex:commandButton action="{!step2}" value="Continue"/> <apex:commandButton action="{!cancel}" value="Cancel"/>
  </apex:pageBlock>

 </apex:form>
</apex:page>
 
Full Controller:

Code:
public class ONEN_controller_NewOppWizard {
 //object to hold opportunity
 Opportunity opportunity = new Opportunity();
 ONEN_RecordTypes OppRecordTypes;
 public OpportunityContactRole oppContactRole { get {return oppContactRole;} set {oppContactRole = value;} }
 public ONEN_Relationship_Contact_2_Contact__c conactRelationshipDummy { get {return conactRelationshipDummy;} set {conactRelationshipDummy = value;} }
 public String oppApplicant { get {return oppApplicant;} set {oppApplicant = value;} }

 
 public Id oppRecordTypeId { get {return oppRecordTypeId;} set {oppRecordTypeId = value;} }
 
 Contact primaryContact = new Contact();
 Account primaryOrg = new Account();
 
 public List<RecordType> recordTypeList {
  get {
   return recordTypeList;
  }
  set {   
   recordTypeList=value;
  }
 }
 
 Id contactId;
 Id accountId;
 //constructor
 public ONEN_controller_NewOppWizard (ApexPages.StandardController controller) {
        this.opportunity = (Opportunity)controller.getRecord();
        conactRelationshipDummy = new ONEN_Relationship_Contact_2_Contact__c();
        opportunity.AccountId = ApexPages.currentPage().getParameters().get('accountId');
        conactRelationshipDummy.Contact__c = ApexPages.currentPage().getParameters().get('contactId');
        
        if(ApexPages.currentPage().getParameters().get('contactId')!=null) {
         oppApplicant = 'Contact';
        } else {
         oppApplicant = 'Organization';
        }
        ONEN_RecordTypes OppRecordTypes = new ONEN_RecordTypes('Opportunity');
  recordTypeList = OppRecordTypes.getRecordTypesForObject();
      //  system.debug(OppRecordTypes);
      //  system.debug(recordTypeList); 
        List<SelectOption> recordTypeOptions = new List<SelectOption>();
        for (RecordType thisRecordType : recordTypeList) {
         recordTypeOptions.add(new SelectOption(thisRecordType.Id,thisRecordType.Name));
        }
  recordTypeNameList = recordTypeOptions;
 }
 
 public List<SelectOption> recordTypeNameList {
  get {
   return recordTypeNameList;
  }
  
  set {

   recordTypeNameList = value;
  }
 }
 
 public PageReference step2() {  
  
  //set name of opp
  String OppNamePrefix;
  String oppAccountName;
  opportunity.RecordTypeId = oppRecordTypeId;
  
  if (conactRelationshipDummy.Contact__c!=null) {
   primaryContact = [select Household_Name__c, FirstName, LastName from Contact where Id=:conactRelationshipDummy.Contact__c];
   opportunity.CR_Contact_Id__c = conactRelationshipDummy.Contact__c;
  }
  
  if (opportunity.AccountId!=null) {
   primaryOrg = [select Name from Account where Id=:opportunity.AccountId];
   oppAccountName = primaryOrg.Name;
  }
  
  if (oppApplicant=='Contact') {
   //get Contact info
   if (primaryContact.Household_Name__c!=null) {
    OppNamePrefix = primaryContact.Household_Name__c;
   } else {
    OppNamePrefix = primaryContact.FirstName + ' ' + primaryContact.LastName;
   }
      
      opportunity.CR_Contact_Role__c = 'Individual Donor';
      opportunity.CR_HHroles__c = true;
        } else {
   OppNamePrefix = oppAccountName;
      opportunity.CR_Contact_Role__c = 'Organizational Donor';
      opportunity.CR_HHroles__c = false;
        }
 
  ONEN_RecordTypes OppRecordTypes = new ONEN_RecordTypes('Opportunity');
  opportunity.Name = OppNamePrefix +  ' ' + system.Today().year() + ' ' + OppRecordTypes.GetOppNamingSuffix(OppRecordTypes.GetRecordTypeName(opportunity.RecordTypeId));
  opportunity.StageName = ONEN_Constants.OPP_DEFAULT_STAGE;
  return Page.newOppWizardStep2; 
 }
 
 public PageReference cancel() {
  PageReference oldPage = new PageReference('/' + conactRelationshipDummy.Contact__c);
        oldPage.setRedirect(true);
        return oldPage;
 }
 
 public PageReference save() {
  insert opportunity;
  PageReference newOpp = new PageReference('/' + opportunity.id +'/e');
        newOpp.setRedirect(true);
        return newOpp;
 }
 
 
}

 

 

I've got a page with a couple forms on it. The main form has some select boxes and one inputField that happens to be a date field.

When the page loads, that date field gets the focus and pops the date picker, which is annoying.



Any ideas how to get it to stop? Here's the code for my form:
 <apex:form >
    <apex:pageBlock title="Create a Payment Schedule" mode="edit">
        <apex:panelGrid columns="3" id="theGrid"  cellpadding="4">
            <apex:outputText value="# of Installments" styleClass="labelCol"/>
            <apex:outputText value="Date of 1st Installment" styleClass="labelCol"/>
            <apex:outputText value="Interval" styleClass="labelCol"/>            
            <apex:selectList value="{!numberofinstallments}" id="installmentCount" multiselect="false" size="1">
                <apex:selectOptions value="{!items}"/>
            </apex:selectList>
            <apex:inputField value="{!thisInstallment.Date__c}"/> 
            <apex:outputPanel id="thePanel">
                <apex:selectList value="{!interval}" id="intervals" multiselect="false" size="1">
                    <apex:selectOptions value="{!intervals}"/>                
                </apex:selectList>
                <apex:selectList value="{!intervalunit}" id="intervalunits" multiselect="false" size="1">
                    <apex:selectOptions value="{!intervalunits}"/>                
                </apex:selectList>
            </apex:outputPanel>
        </apex:panelGrid>
    <apex:pageBlockButtons >
    <apex:commandButton rerender="installmenttable" value="Next"/>
    </apex:pageBlockButtons>
    
    </apex:pageBlock>
    </apex:form>

 

I've got a nice S-Control that lets me see all my time entries for the week on one page. I see a view of the data and if I hit the edit button on an entry, I flip to an edit form.

I want to rebuild this in VisualForce and I'm struggling around how to produce that pattern.

In JS I had a Div with the HTML for displaying the record, and when I hit the edit button, I replaced the complete contents of the DIV with an edit form. On save, I replace the contents again, back to the view HTML.

If I'm displaying a list of entries in VF, I can easily display them as outputText or inputFields. And I know how to rerender elements. But any ideas on the best way to flip between view and edit modes?

Thanks!

Steve
I'm creating a UI for updating CampaignMember Statuses. I get all the members of a Campaign to a list and then bind that list of CampaignMembers to a dataTable. When the inputFields show up on the page, the Status picklist isn't limited to Statuses on my current campaign.

Here's the relevant controller code:
public List<CampaignMember> getMembers() {
allMembers.clear();
allMembers = [Select Contact.FirstName, Contact.LastName, Status from CampaignMember where CampaignId=:currentCampaignId];
return allMembers;
}

 
And the page code:
<apex:dataTable value="{!members}" var="member" id="theTable" rowClasses="odd,even" styleClass="tableClass" cellpadding="4">
    <apex:column >
 <apex:facet name="header">Status</apex:facet>
 <apex:inputField value="{!member.Status}"/>
    </apex:column>
.
.
.

 Seems to me that the picklist should be limited to available Status variables, just like it is in the UI.

Barring a change to that behavior, how is this for a plan of attack?
  • get my campaignmembers and bind them to a dataTable
  • create a new SelectList in each row
  • get items with a SOQL to CampaignMemberStatus, pulling only Statuses for this Campaign
  • and when the user updates the campaign members, somehow get that selected value from each row and put it in member.status for each campaignmember
Is that right? How would I easily match up the object with the selected status? That's the part I'm worried about.

Thanks,

Steve



I want to have a string in each row of a data table that includes the Row number.

Payment 1, Payment 2, Payment 3, etc.

In js I would just use the row counter. Anything analogous in a VF datatable?

Thanks,
Steve
I've got some Apex that gets triggered by Opportunity changes. I'm getting a weird error that I can't comprehend

20080528201313.794:Class.ONEN_TEST_Opp_AddCampaignMbrship.OppToCampaign_NotCampMbr: line 183, column 9: DML Operation executed in 180 ms

System.DmlException: Update failed. First exception on row 0 with id 006S00000029WJ6IAM; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY,

ONENLABS_Opp_TriggerMirrorPaymentUpdate: execution of AfterUpdate

caused by: System.DmlException: Update failed. First exception on row 0 with id a0SS000000002piMAA; first error: UNKNOWN_EXCEPTION, assertion failed

Trigger.ONENLABS_Opp_TriggerMirrorPaymentUpdate: line 40, column 9

Class.ONEN_TEST_Opp_AddCampaignMbrship.OppToCampaign_NotCampMbr: line 183, column 9

I've got this code working on other servers, but with this new install I get an Update error with no helpful information. The record exists and looks fine but won't update.

Can anyone help me out with what this "assertion failed" error means? I don't think it means that one of my test assertions is failing, as it's not reporting the expected and actual values.

I also can't replicate these apex errors by manipulating data in the UI, and I have another test that does basically the same thing and doesn't cause errors.

I've ruled out governor limits, since I get no messages, and I don't seem to have conflicting triggers or workflow that is out of sequence. Just this weird DML exception.

Thanks!


I created a custom object and created a lookup relationship to Contact. I then pulled it via the Force.com IDE (12.0.2.200803272100). I then tried to modify it but always got this error on the Contact lookup field:

Code:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'relationshipLabel'. One 
 of '{"http://soap.sforce.com/2006/04/metadata":relationshipName, "http://soap.sforce.com/
 2006/04/metadata":required, "http://soap.sforce.com/2006/04/metadata":restrictedAdminField, 
 "http://soap.sforce.com/2006/04/metadata":scale, "http://soap.sforce.com/2006/04/
 metadata":startingNumber, "http://soap.sforce.com/2006/04/metadata":summarizedField, "http://
 soap.sforce.com/2006/04/metadata":summaryFilterItems, "http://soap.sforce.com/2006/04/
 metadata":summaryForeignKey, "http://soap.sforce.com/2006/04/metadata":summaryOperation, 
 "http://soap.sforce.com/2006/04/metadata":trueValueIndexed, "http://soap.sforce.com/2006/04/
 metadata":type}' is expected.

The error is thrown here:

Code:
<fields>
        <fullName>Contact__c</fullName>
        <inlineHelpText>Evaluator</inlineHelpText>
        <label>Contact</label>
        <referenceTo>Contact</referenceTo>
        <relationshipLabel>Evaluations</relationshipLabel>
        <relationshipName>Evaluations</relationshipName>
        <type>Lookup</type>
    </fields>
 
Since the file was unaltered from the way Salesforce.com created it, I'm not sure what to do. I appear to have the latest Force.com IDE.

Steve

I want to create a simple one page wizard that is hit from a link off an Opp. The goal is to create a new Opp, after letting the user select a different Account and set values for some Opp fields. I thought I would use the standard Opp controller and then just pass some values to pre-populate the inputFields, but I can't figure out how to do that:

Code:
<apex:page standardController="opportunity">
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Choose an Organization</h1>
  <apex:form>
  <apex:inputField id="newOppAccountId" value="{!opportunity.accountid}"/> <p/>
  <apex:inputField id="newOppCloseDate" value="{!opportunity.closedate}"/> <p/>
  <apex:inputField id="newOppAmount" value="{!opportunity.amount}"/> <p/>
  <apex:inputField id="newOppName" value="{!opportunity.name}"/> <p/>
  <apex:commandButton action="{!save}" value="Create Matching Gift"/>
  </apex:form>
  <!-- End Default Content REMOVE THIS -->
</apex:page>

 Ideally, I'd just grab some values off the querystring and set the inputFields to them. I can't find any examples or threads where this is addressed. Am I off the mark?

Thanks!

Steve
I was just playing with the latest metadata api with a new customer of mine. We have a whole bunch of custom objects and code in a private package. We installed it the other day, and then I tried to add a field to an object with the metadata api. I got this error:

Save error: Cannot add new entity into an installed package (attempted to add type CustomField named ONEN_Household__c.Junk__c)

Which sounds like once I install code via a private appexchange, it won't be modifiable. Is that behavior expected with the metadata api?

For me it would mean that I have to ditch the idea of packaging and go to a full metadata API deployment model where we don't package stuff up, but instead drag text files around. Is that right?

Thanks,
Steve
I'm working with the Plone <-> Salesforce.com integration and creating cases from my website. I'm not using web-to-case, just using the API to create Cases and the Related Contact and Account.

Is there any way to fire the default Case Assignment rule when a Case is created via the API? Seems like there are two ways to fire the rules:
  1. Create the Case via web-to-lead
  2. Create the case in the UI, and check the Assignment Rule checkbox
Am I missing the handy-dandy FireAssignmentRule field on the Case?

Thanks,
Steve
I was happily using the new IDE yesterday as I created my first Apex email service. I deployed it successfully to production and the service successfully processed inbound email.

Today, I can't deploy changes I've made. In the deployment wizard, I get a null pointer error as it's trying to develop a deployment plan.

I changed my class code, but there are no errors and the tests pass, so not sure why it would be bombing like this.

Any ideas what this might be or how to troubleshoot such an error in deployment?

Thanks,

Steve
Hi all,

My name is Steve Andersen. I'm a long-time Salesforce consultant (you may know me as gokubi, "Developer Hero" at Dreamforce '07). I do Salesforce implementations at a place called ONE/Northwest (www.onenw.org). We're a growing Seattle-based nonprofit that helps environmental organizations transform the way they communicate, build relationships and partner with people and institutions. We develop websites, databases, email newsletters, collaboration and citizen engagement tools – and the strategies to use these tools to engage people in influencing decisions that impact the environment. We operate on a movement-wide scale, strengthening connections between groups working on a range of issues and approaches to protecting the environment.

Our CRM team is swamped by demand. I think it's because we deliver killer Salesforce implementations, with deep customization using S-Controls and Apex. We're currently seeking a technologist experienced in developing and implementing Salesforce to come work with us in Seattle.

Check out the Job Description

If you go to our website you'll see an application form. It's a web-to-lead-ish form, but it was created via our Plone integration. On the Plone side we've got a drag and drop interface for constructing the form the way we want it to look, then we map the fields to Salesforce objects. In this case, we're mapping to the Lead object. On submission, the Lead is created and we use a simple Apex trigger to connect that Lead with our CRM Job Application Campaign. We get an email via workflow, and then we check a Console that is pointing to that Campaign.

We're using Campaign Member Statuses to move applicants through the process, and have some simple email templates ready for dealing with all those people who apply but don't even really know what CRM is...

It took me about 2 hours to create the form, modify the Lead object with some job applicant-type fields, and create the Campaign, email templates, and Console. I love rapid development in Salesforce and Plone!

If you're interested, I'd love to talk to you. Come join a killer team doing great work with modern software. It's a ton of fun!

Thanks,
Steve
Here's my use case for a sites app:

1. Send an email out to Contacts via sf.com
2. Include a "manage my subscriptions" link in the email that has the contact id in it
3. End user clicks on that URL and lands on a sites page
4. End user is asked to enter the email address for which they want to modify subscriptions.
5. If the email they enter matches the email on the contact record, the can
6. change some settings on their contact record and hit save to commit them

I had this working in the authenticated view, but can't get sites to allow me to modify contact records as a public user. I can see why sf.com might not want to allow that. But I also don't want to make a person authenticate for this task.

So I changed things to allow the user to create a custom object that manages the subscription, and then I have a trigger on that object to update the contact record with the changes. So in effect, they are modifying the contact, but with a custom object and a trigger in between.

However, Sites won't let me do this unauthenticated. The checkboxes on my custom object don't show on the vf page. I don't get "authorization required" but the fields just aren't there.

Is Sites seeing my trigger and disallowing my public user because it knows I am going to update a Contact? Or am I screwing things up in a different way?

Here is the page:
Code:
<apex:page Controller="ext_contact_subscriptions" showHeader="False" title="Manage Your Subscriptions" >
<!-- Begin Default Content REMOVE THIS -->
<div style="margin:10px">
<h1>Manage your Subscriptions</h1>
<p>Check what you want to receive from us!</p>
<apex:form >
 <apex:outputPanel id="emailLogin" layout="block" style="margin-left:10px;"> 
  <apex:outputPanel rendered="{!AND(NOT(emailVerified),NOT(success))}" >
   <apex:outputText value="Your email:"/>
   <apex:inputText value="{!enteredEmail}" />
   <apex:commandButton value="submit" action="{!validateEmail}" rerender="emailLogin,subscriptions"/>
  </apex:outputPanel>
  <apex:outputPanel rendered="{!validationError}" layout="block">
  <br/>
   <apex:outputText style="color:#ff0000;" value="That email did not match this subscription. Try another email address."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="subscriptions" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!AND(emailVerified,NOT(success))}">
   <h2>Change your Email if you Wish</h2>
   <br/><br/>
   <apex:outputText value="Your Email: " style="margin-left:10px;"/> <apex:inputField value="{!subscription.Email__c}" /><br/><br/>
   <h2>Your Subscriptions</h2>
   <br/><br/>
   <apex:inputField value="{!subscription.Monthly_eNewsletter__c}" /> <apex:outputText value="eNewsletter"/>
   <br/><br/>
   
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our monthly newsletter."/><br/><br/>
   <apex:inputField value="{!subscription.Action_Alerts__c}" /> <apex:outputText value="Action Alerts"/>
   <br/><br/>
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our periodic notifications about actions."/><br/><br/>
   <apex:commandButton action="{!save}" value="Save" rerender="emailLogin,subscriptions,success"/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="success" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!success}">
   <apex:outputText style="color:#666666;margin-left:10px;" value="Thanks for submitting your changes! They will go into effect immediately."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <!--figure out redirect-->

</apex:form>
</div>
</apex:page>


Here is the controller:

Code:
public class ext_contact_subscriptions {
 
 public Contact contact = new Contact();
 
 public Boolean emailVerified   { get; set; }
 public String enteredEmail    { get; set; }
 public Boolean success     { get; set; }
 public Boolean validationError   { get; set; }
 public string msg       { get; set; }
 
 public Subscription__c subscription { get {return subscription;} set {subscription = value;} }
  
 public ext_contact_subscriptions() {
        contact = [select id, email,Monthly_eNewsletter__c, Action_Alerts__c from contact where id = :ApexPages.currentPage().getParameters().get('id')];
        emailVerified = false;
        validationError = false;
        success = false;
        subscription = new Subscription__c();
        subscription.Contact__c = contact.Id;
        subscription.Email__c = contact.Email;
        subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
        subscription.Action_Alerts__c = contact.Action_Alerts__c;
    }
    
    public PageReference validateEmail() {
     //contact.email = 'steve@test.com';
     if (enteredEmail == contact.email) {
      emailVerified = true;
      validationError = false;
     } else {
      validationError = true; 
     }
     return null; 
    }
    
    
    public PageReference save() {
     
     try {
        // update contact;
       // subscription.contact__c = contact.Id;
     //   subscription.email__c = contact.email;
      //  subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
      //  subscription.Action_Alerts__c = contact.Action_Alerts__c;
        insert subscription;
        
         success = true;
        } catch (exception e) { 
         msg = e.getMessage(); 
        }
     
     return null; 
    }
}

 and here is the trigger:

Code:
trigger subscription_to_contact on subscription__c (after insert) {
 Map<Id,subscription__c> subsToKill = new Map<Id,subscription__c>();
 List<Contact> contactsToProcess = new List<Contact>();
 for (subscription__c sub : Trigger.new) {
  Contact contact = new Contact (    
   id=sub.contact__c,
   Email = sub.email__c,
   Action_Alerts__c = sub.Action_Alerts__c,
   Monthly_eNewsletter__c = sub.Monthly_eNewsletter__c
  );
  contactsToProcess.add(contact);
  subsToKill.put(sub.id,sub);
 }
 if(contactsToProcess.size()>0){
  try {
   update contactsToProcess;  
   //delete subsToKill.values();
        } catch (exception e) { 
         system.debug(e.getMessage()); 
        }  
 } 
}

 Thanks much!

Steve


 

I noticed that triggers aren't allowed on OpportunityContactRole yet. Having triggers on OpportunityContactRole, CampaignMember, and the like is crucial to being able to enforce business processes end to end.

For example, I wrote a sample trigger that rolls up Opportunity Amounts to the primary Contacts on those Opps. This shows the revenue history for a Contact, and is really helpful to the groups I build databases for. But a person's OppContactRole can be deleted, changed, or added without triggering the code that will re-tally the Amounts, and the roll-ups will drift from the correct value.

If I can put a similar trigger on OppContactRole, it will be impossible for the tally to get out of date, as long as I've built two good triggers.

Apex is great stuff. Amazingly simple and powerful. Just wanted to pass on this initial thought.

Thanks!

Steve
Howdy all,

I've implemented dependent selectLists in the interface below. The issue I'm having is that the lists only work when only 1 set exists. IE: 1 row for time entry in this case. When I add a row to the interface, it creates a new timeEntry instance and the selectLists in the bottom-most row work properly, but any above that do not work.

Is there a way to dynamically rerender a row in a table or some VF component? Ideally, each row or each outputPanel would have a different ID but I can't seem to set the rerender="" attribute dynamically.

Code:
<apex:actionRegion >
<apex:selectList value="{!selectedProject}" size="1">
<apex:selectOptions value="{!ProjectOptions}" />
<apex:actionSupport event="onchange" rerender="mondayTask" status="loading" />
</apex:selectList>
</apex:actionRegion>                  

<apex:outputPanel id="mondayTask">
<apex:selectList value="{!taskId}" size="1" multiselect="false">
<apex:selectOptions value="{!taskItems}"/>
</apex:selectList>
</apex:outputPanel>




Here is the code for the VF section:
Code:
<apex:outputPanel id="mondayTable"> 

 <apex:form >
 <table cellpadding = "0" cellspacing = "0">
  <tr class = "header">
        <td>Projects</td>
        <td>Tasks</td>
        <td>Description</td>
        <td width = "50">Time</td>
       </tr>
  <apex:repeat value="{!mondayTime}" var="t">
 <tr>
  <td>
   <apex:actionRegion >
          <apex:selectList value="{!selectedProject}" size="1">
           <apex:selectOptions value="{!ProjectOptions}" />
     <apex:actionSupport event="onchange" rerender="mondayTask" status="loading" />
          </apex:selectList>
         </apex:actionRegion>                  
        </td>
        <td>
   <apex:outputPanel id="mondayTask">
          <apex:selectList value="{!taskId}" size="1" multiselect="false">
         <apex:selectOptions value="{!taskItems}"/>
       </apex:selectList>
         </apex:outputPanel>
        </td>
  <td><apex:inputText value="{!t.description}" /></td>
  <td><apex:inputText value="{!t.hours}" /></td>
 </tr>
  </apex:repeat>
  <tr>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td><apex:commandButton action="{!addEntry}" value="add row" rerender="mondayTable" status="loading"/></td>
   <td><apex:commandButton action="{!saveMondayTime}" value="save" /></td>
  </tr>
 </table>
 </apex:form>
 </apex:outputPanel>

 



I am building a data entry form with 3 picklists--Account, Opportunity, and a custom child object of opportunity. The idea is you select an Account, and then get a picklist of all Opportunites, when you select an Opp, the child picklist shows up.

I built an interface like this in an scontrol and I'm now replacing it with VF.

I built a client object, which has an Account Id, Account Name, and a list of SelectOptions for available Opportunities:
public class client {
 public Id clientId;
 public String clientName {get{return clientName;} set{clientName = value;}}
 public List<SelectOption> projectOptions {get{return projectOptions;} 
set{projectOptions = value;}} public Map<Id,project> projects {get{return projects;} set{projects = value;}} public client() { projectOptions = new List<SelectOption>(); projects = new Map<Id,project>(); } }

On page load I build out a map of all my clients, each with it's projectOptions. When I debug the client object I get this:
001S0000003VuzSIAS=timesheetController.client: [
clientId=001S0000003VuzSIAS,
clientName=ONE/Northwest,
     projectOptions=(
          System.SelectOption[value="", label="- pick a project -", disabled="false"],     
          System.SelectOption[value="006S0000002JUkiIAG", label="ONE/Northwest 2008 Project", disabled="false"] ),
.
.
.

 But I can't get the project options to show in a picklist. The client picklist works, and when you change it, it rerenders the project section. But the project picklist is empty, and I can't get the project options that I know are there to show up.:

<tbody>
         
 <tr><th><apex:outputText value="AccountNew"/></th>
  <td>
   <apex:selectList value="{!newTaskLog.Account__c}" id="accountselect" 
multiselect="false" size="1"> <apex:selectOptions value="{!clientSelect}"/> <apex:actionSupport event="onchange"
action="{!setupFocusClient}" rerender="projectselect"/> </apex:selectList> </td></tr> <tr><th><apex:outputText value="ProjectNew"/></th> <td> <apex:outputPanel id="projectselect" > <apex:outputText value="{!focusClient.clientName}"/> <apex:selectList value="{!newTaskLog.Opportunity__c}"
multiselect="false" size="1"> <apex:selectOptions value="{!focusClient.projectOptions}"/> <apex:actionSupport event="onchange"
action="{!setupFocusProject}" rerender="taskSelect"/> </apex:selectList> </apex:outputPanel> </td></tr>

Any ideas about what I'm doing wrong?

Thanks,
Steve
 

Hi Experts,
I would like to code for a new button in Visualforce Page that will direct me to an Opportunity (in Edit mode) with some fields automatically filled up using the information passing as parameters from my calling Visualforce Page. Please help!
Best regards,
Boi Hue
 
  • December 04, 2008
  • Like
  • 0
Here's my use case for a sites app:

1. Send an email out to Contacts via sf.com
2. Include a "manage my subscriptions" link in the email that has the contact id in it
3. End user clicks on that URL and lands on a sites page
4. End user is asked to enter the email address for which they want to modify subscriptions.
5. If the email they enter matches the email on the contact record, the can
6. change some settings on their contact record and hit save to commit them

I had this working in the authenticated view, but can't get sites to allow me to modify contact records as a public user. I can see why sf.com might not want to allow that. But I also don't want to make a person authenticate for this task.

So I changed things to allow the user to create a custom object that manages the subscription, and then I have a trigger on that object to update the contact record with the changes. So in effect, they are modifying the contact, but with a custom object and a trigger in between.

However, Sites won't let me do this unauthenticated. The checkboxes on my custom object don't show on the vf page. I don't get "authorization required" but the fields just aren't there.

Is Sites seeing my trigger and disallowing my public user because it knows I am going to update a Contact? Or am I screwing things up in a different way?

Here is the page:
Code:
<apex:page Controller="ext_contact_subscriptions" showHeader="False" title="Manage Your Subscriptions" >
<!-- Begin Default Content REMOVE THIS -->
<div style="margin:10px">
<h1>Manage your Subscriptions</h1>
<p>Check what you want to receive from us!</p>
<apex:form >
 <apex:outputPanel id="emailLogin" layout="block" style="margin-left:10px;"> 
  <apex:outputPanel rendered="{!AND(NOT(emailVerified),NOT(success))}" >
   <apex:outputText value="Your email:"/>
   <apex:inputText value="{!enteredEmail}" />
   <apex:commandButton value="submit" action="{!validateEmail}" rerender="emailLogin,subscriptions"/>
  </apex:outputPanel>
  <apex:outputPanel rendered="{!validationError}" layout="block">
  <br/>
   <apex:outputText style="color:#ff0000;" value="That email did not match this subscription. Try another email address."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="subscriptions" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!AND(emailVerified,NOT(success))}">
   <h2>Change your Email if you Wish</h2>
   <br/><br/>
   <apex:outputText value="Your Email: " style="margin-left:10px;"/> <apex:inputField value="{!subscription.Email__c}" /><br/><br/>
   <h2>Your Subscriptions</h2>
   <br/><br/>
   <apex:inputField value="{!subscription.Monthly_eNewsletter__c}" /> <apex:outputText value="eNewsletter"/>
   <br/><br/>
   
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our monthly newsletter."/><br/><br/>
   <apex:inputField value="{!subscription.Action_Alerts__c}" /> <apex:outputText value="Action Alerts"/>
   <br/><br/>
   <apex:outputText style="color:#666666;margin-left:10px;" value="Receive our periodic notifications about actions."/><br/><br/>
   <apex:commandButton action="{!save}" value="Save" rerender="emailLogin,subscriptions,success"/>
  </apex:outputPanel>
 </apex:outputPanel>
 <apex:outputPanel id="success" layout="block" style="margin-left:10px;">
  <apex:outputPanel rendered="{!success}">
   <apex:outputText style="color:#666666;margin-left:10px;" value="Thanks for submitting your changes! They will go into effect immediately."/>
  </apex:outputPanel>
 </apex:outputPanel>
 <!--figure out redirect-->

</apex:form>
</div>
</apex:page>


Here is the controller:

Code:
public class ext_contact_subscriptions {
 
 public Contact contact = new Contact();
 
 public Boolean emailVerified   { get; set; }
 public String enteredEmail    { get; set; }
 public Boolean success     { get; set; }
 public Boolean validationError   { get; set; }
 public string msg       { get; set; }
 
 public Subscription__c subscription { get {return subscription;} set {subscription = value;} }
  
 public ext_contact_subscriptions() {
        contact = [select id, email,Monthly_eNewsletter__c, Action_Alerts__c from contact where id = :ApexPages.currentPage().getParameters().get('id')];
        emailVerified = false;
        validationError = false;
        success = false;
        subscription = new Subscription__c();
        subscription.Contact__c = contact.Id;
        subscription.Email__c = contact.Email;
        subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
        subscription.Action_Alerts__c = contact.Action_Alerts__c;
    }
    
    public PageReference validateEmail() {
     //contact.email = 'steve@test.com';
     if (enteredEmail == contact.email) {
      emailVerified = true;
      validationError = false;
     } else {
      validationError = true; 
     }
     return null; 
    }
    
    
    public PageReference save() {
     
     try {
        // update contact;
       // subscription.contact__c = contact.Id;
     //   subscription.email__c = contact.email;
      //  subscription.Monthly_eNewsletter__c = contact.Monthly_eNewsletter__c;
      //  subscription.Action_Alerts__c = contact.Action_Alerts__c;
        insert subscription;
        
         success = true;
        } catch (exception e) { 
         msg = e.getMessage(); 
        }
     
     return null; 
    }
}

 and here is the trigger:

Code:
trigger subscription_to_contact on subscription__c (after insert) {
 Map<Id,subscription__c> subsToKill = new Map<Id,subscription__c>();
 List<Contact> contactsToProcess = new List<Contact>();
 for (subscription__c sub : Trigger.new) {
  Contact contact = new Contact (    
   id=sub.contact__c,
   Email = sub.email__c,
   Action_Alerts__c = sub.Action_Alerts__c,
   Monthly_eNewsletter__c = sub.Monthly_eNewsletter__c
  );
  contactsToProcess.add(contact);
  subsToKill.put(sub.id,sub);
 }
 if(contactsToProcess.size()>0){
  try {
   update contactsToProcess;  
   //delete subsToKill.values();
        } catch (exception e) { 
         system.debug(e.getMessage()); 
        }  
 } 
}

 Thanks much!

Steve


 

The Winter '09 docs don't seem to have anything about governor limits with the @future call other than the fact you can only invoke 200 @future methods/day/org. I know one of the goals of the @future notation is to allow us to get around the current apex governor limits without killing sf.com servers.

Does anyone know what the @future limits will be? We're thinking of new functionality that would fit into @future methods and want to get a sense of what we'll be dealing with in regard to limits.

Thanks,
Steve
I've set up 3 VF pages to use one controller. As I navigate from page to page, certain state data is being held in variables in the controller. It generally works.

However, the URL in the address bar isn't showing the correct page. I start on page A and when I move to page B via a command link, the URL isn't updating. It appears to stay one page behind.

Here's an example of how I'm moving from one page to the next:
Code:
    public PageReference loadCallList() {
      //set the current campaign
     //set the list of members
  setCallListMembers();
  //redirect to the call list page
  
  return Page.callList;
 }

 If I set the Redirect parameter to true, the URL changes but I also lose my state information.

What am I missing about navigating between pages while not reinstantiating my controller?

Thanks,
Steve

I want to hit google's geocoding api from an @future class on a trigger so I can add lat and lon to records as they change. I have a couple questions:
  1. If I want to hit the rest interface for google's service, I need to supply an api key. Do I need to do anything special to get that key to work from salesforce.com servers? It asks me to identify the calling domain--should that be salesforce.com?
  2. The API will respond to one call every 2 seconds, equating to 50,000 calls a day. What's the best way to deal with that limiter in an apex class? I couldn't find a sleep function.
Thanks,
Steve
I'm just starting with the @future tag and added a future call to a Contact after insert trigger I've got. I added a call to a method which I plan to have geocode the Contact based on address, via a call out to google's geocoding service.

My method is very simple right now:
Code:
public class dataAugmentation { 
 @future
 public static void augmentAddresses(List<id> contactIdsToAugment) {
  List<Contact> ContactsToBeUpdated = new List<Contact>();
  for (Contact thisContact : [Select Id, OtherStreet,OtherCity,OtherState,OtherPostalCode,OtherCountry from Contact where Id IN :contactIdsToAugment]) { 
    thisContact.OtherCountry='Zanzibar';
    ContactsToBeUpdated.add(thisContact);
  
   //callout to web service
   //thisContactToAugment.Country='Zanzibar';
  }  
  update ContactsToBeUpdated;  
 }
}

 My code compiles and runs in the UI, but the future action (Country updated to 'Zanzibar') hasn't happened after an hour. When I try to modify the class that contains the future method, I get this error in the IDE:

Batchable class has jobs pending or in progress
dataAugmentation.cls
Winter 09 Preview/src/unpackaged/classes
line 1
Force.com save problem

I couldn't find any documentation about how future calls get batched and run, but if I had to interpret this error message I would guess that my updates are sitting in a queue waiting to run, and while that is happening, I can't modify the class.

Is that what is going on? Are there ways to monitor what future calls are waiting for execution?

Thanks,
Steve


I've got a wizard for creating a new Opp which I referenced in a previous post. I want the user to have the option of selecting an existing Contact to be the primary Contact on the Opp. On my VF page I need a Contact lookup and then on Save I'll create the ContactRole for the Opportunity and use that Contact Id.

Problem is that I don't think I can get an inputField lookup without instantiating an object and then binding to the field. I can instantiate an Opportunity Contact Role object, but Contact is required on that object so the lookup on my VF page has the big red required flag. Selecting a Contact isn't required for my wizard, so that won't work.

My workaround is to instantiate a completely unrelated custom object that happens to have a Contact lookup field on it. I catch the Contact Id in there, and then us it to create the Contact role. It works. But it's ugly. Sharing this code now just got harder because there is now this dependence on a custom object that has nothing to do with this solution.

Any ideas? Thanks!

Steve
<meta name="GENERATOR" content="BLOCKNOTE.NET">BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt }
I'm trying to do a dynamic page section like Jon outlined here, but I'm having trouble.
 
I want a user to select a radio, and then display a page section based on that value. I can get the section to render based on the conditional, but I can't get it to change when the radio button is changed. I'm clearly missing something.
 
Here is my radio:
<apex:actionRegion >        
  <apex:outputPanel >        
    <apex:outputLabel value="Apply Opportunity To" for="oppApplicantSelect"/>        
    <apex:selectRadio id="oppApplicantSelect" value="{!oppApplicant}">
      <apex:selectOption itemValue="Contact" itemLabel="Contact"/>
      <apex:selectOption itemValue="Organization" itemLabel="Organization"/>
      <apex:actionSupport event="onchange" rerender="orgSection" status="status"/>
    </apex:selectRadio>
    <apex:actionStatus startText="applying value...{!oppApplicant}" id="status"/>
  </apex:outputPanel>
</apex:actionRegion>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt }
and here is the part of the page I want to render:

<apex:pageBlock title="Organization info" id="orgSection"  rendered="{!oppApplicant == 'Organization'}">
  <apex:outputLabel value="Organization" for="accountField"/>
  <apex:inputField id="accountField" value="{!opportunity.AccountId}"/>
  <apex:outputText value="{!oppApplicant}"/>
</apex:pageBlock>

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } In my controller I've got a String set up to catch the Radio values:
Code:
public String oppApplicant { get {return oppApplicant;} set {oppApplicant = value;} }

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } And in my constructor, I'm setting oppApplicant if I have a querystring variable:
Code:
if(ApexPages.currentPage().getParameters().get('contactId')!=null) {
  oppApplicant = 'Contact';
} else {
  oppApplicant = 'Organization';
}

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="GENERATOR" content="BLOCKNOTE.NET">
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } I'll paste the full code of the controller and page below. Thanks for any help!
 
Steve

Full Page:

Code:
<apex:page standardController="Opportunity" tabStyle="Opportunity" extensions="ONEN_controller_NewOppWizard">

   <script >
  //hack to override JavaScript that is setting focus on Date field 
  function setFocusOnLoad() {} 
 </script>
 <apex:sectionHeader title="New Opportunity" subtitle="Use this page to create an opportunity and set contact roles"/>
     <apex:form >
    <apex:pageBlock title="Contact and Organization">     
         <apex:actionRegion >         
          <apex:outputPanel >         
           <apex:outputLabel value="Apply Opportunity To" for="oppApplicantSelect"/>        
           <apex:selectRadio id="oppApplicantSelect" value="{!oppApplicant}">
      <apex:selectOption itemValue="Contact" itemLabel="Contact"/>
      <apex:selectOption itemValue="Organization" itemLabel="Organization"/>
      <apex:actionSupport event="onchange" rerender="orgSection" status="status"/>     
     </apex:selectRadio>
     <apex:actionStatus startText="applying value...{!oppApplicant}" id="status"/>
    </apex:outputPanel>    
   </apex:actionRegion>  
   <apex:outputLabel value="Primary Contact" for="contactField"/> 
   <apex:inputField id="contactField" value="{!conactRelationshipDummy.Contact__c}"/>
  </apex:pageBlock>
  <apex:pageBlock title="Organization info" id="orgSection"  rendered="{!oppApplicant == 'Organization'}">
   <apex:outputLabel value="Organization" for="accountField"/>
   <apex:inputField id="accountField" value="{!opportunity.AccountId}"/>
   <apex:outputText value="{!oppApplicant}"/>
  </apex:pageBlock>
  <apex:pageBlock >
   <apex:outputLabel value="Record Type" for="oppRecordType"/>
   <apex:selectList size="1" id="oppRecordType" value="{!oppRecordTypeId}">
    <apex:selectOptions value="{!recordTypeNameList}"/> 
   </apex:selectList>   
   <apex:commandButton action="{!step2}" value="Continue"/> <apex:commandButton action="{!cancel}" value="Cancel"/>
  </apex:pageBlock>

 </apex:form>
</apex:page>
 
Full Controller:

Code:
public class ONEN_controller_NewOppWizard {
 //object to hold opportunity
 Opportunity opportunity = new Opportunity();
 ONEN_RecordTypes OppRecordTypes;
 public OpportunityContactRole oppContactRole { get {return oppContactRole;} set {oppContactRole = value;} }
 public ONEN_Relationship_Contact_2_Contact__c conactRelationshipDummy { get {return conactRelationshipDummy;} set {conactRelationshipDummy = value;} }
 public String oppApplicant { get {return oppApplicant;} set {oppApplicant = value;} }

 
 public Id oppRecordTypeId { get {return oppRecordTypeId;} set {oppRecordTypeId = value;} }
 
 Contact primaryContact = new Contact();
 Account primaryOrg = new Account();
 
 public List<RecordType> recordTypeList {
  get {
   return recordTypeList;
  }
  set {   
   recordTypeList=value;
  }
 }
 
 Id contactId;
 Id accountId;
 //constructor
 public ONEN_controller_NewOppWizard (ApexPages.StandardController controller) {
        this.opportunity = (Opportunity)controller.getRecord();
        conactRelationshipDummy = new ONEN_Relationship_Contact_2_Contact__c();
        opportunity.AccountId = ApexPages.currentPage().getParameters().get('accountId');
        conactRelationshipDummy.Contact__c = ApexPages.currentPage().getParameters().get('contactId');
        
        if(ApexPages.currentPage().getParameters().get('contactId')!=null) {
         oppApplicant = 'Contact';
        } else {
         oppApplicant = 'Organization';
        }
        ONEN_RecordTypes OppRecordTypes = new ONEN_RecordTypes('Opportunity');
  recordTypeList = OppRecordTypes.getRecordTypesForObject();
      //  system.debug(OppRecordTypes);
      //  system.debug(recordTypeList); 
        List<SelectOption> recordTypeOptions = new List<SelectOption>();
        for (RecordType thisRecordType : recordTypeList) {
         recordTypeOptions.add(new SelectOption(thisRecordType.Id,thisRecordType.Name));
        }
  recordTypeNameList = recordTypeOptions;
 }
 
 public List<SelectOption> recordTypeNameList {
  get {
   return recordTypeNameList;
  }
  
  set {

   recordTypeNameList = value;
  }
 }
 
 public PageReference step2() {  
  
  //set name of opp
  String OppNamePrefix;
  String oppAccountName;
  opportunity.RecordTypeId = oppRecordTypeId;
  
  if (conactRelationshipDummy.Contact__c!=null) {
   primaryContact = [select Household_Name__c, FirstName, LastName from Contact where Id=:conactRelationshipDummy.Contact__c];
   opportunity.CR_Contact_Id__c = conactRelationshipDummy.Contact__c;
  }
  
  if (opportunity.AccountId!=null) {
   primaryOrg = [select Name from Account where Id=:opportunity.AccountId];
   oppAccountName = primaryOrg.Name;
  }
  
  if (oppApplicant=='Contact') {
   //get Contact info
   if (primaryContact.Household_Name__c!=null) {
    OppNamePrefix = primaryContact.Household_Name__c;
   } else {
    OppNamePrefix = primaryContact.FirstName + ' ' + primaryContact.LastName;
   }
      
      opportunity.CR_Contact_Role__c = 'Individual Donor';
      opportunity.CR_HHroles__c = true;
        } else {
   OppNamePrefix = oppAccountName;
      opportunity.CR_Contact_Role__c = 'Organizational Donor';
      opportunity.CR_HHroles__c = false;
        }
 
  ONEN_RecordTypes OppRecordTypes = new ONEN_RecordTypes('Opportunity');
  opportunity.Name = OppNamePrefix +  ' ' + system.Today().year() + ' ' + OppRecordTypes.GetOppNamingSuffix(OppRecordTypes.GetRecordTypeName(opportunity.RecordTypeId));
  opportunity.StageName = ONEN_Constants.OPP_DEFAULT_STAGE;
  return Page.newOppWizardStep2; 
 }
 
 public PageReference cancel() {
  PageReference oldPage = new PageReference('/' + conactRelationshipDummy.Contact__c);
        oldPage.setRedirect(true);
        return oldPage;
 }
 
 public PageReference save() {
  insert opportunity;
  PageReference newOpp = new PageReference('/' + opportunity.id +'/e');
        newOpp.setRedirect(true);
        return newOpp;
 }
 
 
}

 

 

I apologized if this has been asked before, but I've searched through the discussion boards and haven't seen anything like this yet.

I've overidden the "New" standard button for the Task object with a custom VF page. This works fine in almost all cases except for this case

1. Override the Task object's "New" functionality with any S-control or VF page
2. Use the "Create new" dropdown menu on left nav to start the page flow for creating a new record.
3. Click "Continue" on Recordtype selection page (as far as I have tested, object has to go through the Recordtype selection page to reproduce this behavior)
4. On the next page, without submitting, select "Create New" on the left nav to repeat steps 2 - 4 again.
5. On the 3rd or 4th try, I am redirected to the default page to create a new task, instead of the custom VF page.

I have been able to reproduced this with the Contact object with a simple html s-control instead of a VF page

Is this a standard Salesforce behavior for users who seem to be stuck in the "Create New" loop?

It is possible that some users would use the "Create New" dropdown on the left nav to restart the page flow for convenience when they've made a mistake in their data entry, instead of cancelling out their current flow before restarting the "Create New" flow. I guess this could be a very rare use case, but I would like to know if this is a bug, or a "feature" by Salesforce?

Thanks in advance ..
I've got a page with a couple forms on it. The main form has some select boxes and one inputField that happens to be a date field.

When the page loads, that date field gets the focus and pops the date picker, which is annoying.



Any ideas how to get it to stop? Here's the code for my form:
 <apex:form >
    <apex:pageBlock title="Create a Payment Schedule" mode="edit">
        <apex:panelGrid columns="3" id="theGrid"  cellpadding="4">
            <apex:outputText value="# of Installments" styleClass="labelCol"/>
            <apex:outputText value="Date of 1st Installment" styleClass="labelCol"/>
            <apex:outputText value="Interval" styleClass="labelCol"/>            
            <apex:selectList value="{!numberofinstallments}" id="installmentCount" multiselect="false" size="1">
                <apex:selectOptions value="{!items}"/>
            </apex:selectList>
            <apex:inputField value="{!thisInstallment.Date__c}"/> 
            <apex:outputPanel id="thePanel">
                <apex:selectList value="{!interval}" id="intervals" multiselect="false" size="1">
                    <apex:selectOptions value="{!intervals}"/>                
                </apex:selectList>
                <apex:selectList value="{!intervalunit}" id="intervalunits" multiselect="false" size="1">
                    <apex:selectOptions value="{!intervalunits}"/>                
                </apex:selectList>
            </apex:outputPanel>
        </apex:panelGrid>
    <apex:pageBlockButtons >
    <apex:commandButton rerender="installmenttable" value="Next"/>
    </apex:pageBlockButtons>
    
    </apex:pageBlock>
    </apex:form>

 

I want to use visual force to modify this screen and add one of my custom fields to it.  is this possible?  I am not sure what controller I need to extend.  Please offer your advise.

Thanks
I've got a nice S-Control that lets me see all my time entries for the week on one page. I see a view of the data and if I hit the edit button on an entry, I flip to an edit form.

I want to rebuild this in VisualForce and I'm struggling around how to produce that pattern.

In JS I had a Div with the HTML for displaying the record, and when I hit the edit button, I replaced the complete contents of the DIV with an edit form. On save, I replace the contents again, back to the view HTML.

If I'm displaying a list of entries in VF, I can easily display them as outputText or inputFields. And I know how to rerender elements. But any ideas on the best way to flip between view and edit modes?

Thanks!

Steve
I'm creating a UI for updating CampaignMember Statuses. I get all the members of a Campaign to a list and then bind that list of CampaignMembers to a dataTable. When the inputFields show up on the page, the Status picklist isn't limited to Statuses on my current campaign.

Here's the relevant controller code:
public List<CampaignMember> getMembers() {
allMembers.clear();
allMembers = [Select Contact.FirstName, Contact.LastName, Status from CampaignMember where CampaignId=:currentCampaignId];
return allMembers;
}

 
And the page code:
<apex:dataTable value="{!members}" var="member" id="theTable" rowClasses="odd,even" styleClass="tableClass" cellpadding="4">
    <apex:column >
 <apex:facet name="header">Status</apex:facet>
 <apex:inputField value="{!member.Status}"/>
    </apex:column>
.
.
.

 Seems to me that the picklist should be limited to available Status variables, just like it is in the UI.

Barring a change to that behavior, how is this for a plan of attack?
  • get my campaignmembers and bind them to a dataTable
  • create a new SelectList in each row
  • get items with a SOQL to CampaignMemberStatus, pulling only Statuses for this Campaign
  • and when the user updates the campaign members, somehow get that selected value from each row and put it in member.status for each campaignmember
Is that right? How would I easily match up the object with the selected status? That's the part I'm worried about.

Thanks,

Steve



Hi,
Is there a way I can display all fields of an object in edit mode (input fields) just like an <apex:detail /> tag displays all fields in the detail mode?



Thanks in advance!

Thanks,
NG
Has anyone had any success in deploying CustomField changes to the User or Task standard objects using the Force.com IDE?

For the User object, I'm getting the following error message:
  unable to obtain exclusive access to this record

For the Task object, I'm getting the following error messages:
  Field 'Subject' in 'Task' is not a picklist field
  Entity Enumeration Or ID: bad value for restricted picklist field: Task

I have been able to deploy changes on the Account and Opportunity, but have been unsuccessful in deploying to User and Task objects.

Thanks