• Denise Crosby
  • NEWBIE
  • 120 Points
  • Member since 2017
  • Salesforce Administrator
  • Brock Group

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 16
    Questions
  • 62
    Replies
Hello. I wrote an Apex trigger that works fine to update a custom field on the opportunity when an opportunitylineitem is updated. The problem is when I try to import 200 records I get the error: UpdateOpptyProductText: System.LimitException: Too many SOQL queries: 101. Many thanks for helping.
 
trigger UpdateOpptyProductText on OpportunityLineItem (after insert, after update) {
    for (OpportunityLineItem oli : Trigger.New) {
      
        Opportunity o = [select id from Opportunity where id =: oli.OpportunityId];
        o.Opportunity_Products__c = '';
        OpportunityLineItem[] lis = [Select id, name, product2id from opportunitylineitem where opportunityid=:o.Id];
        
        integer count = 0;
        for (OpportunityLineItem li : lis) {
            if (count > 0) {
                o.Opportunity_Products__c += '; ';
            }
            Product2 p = [select id,name from Product2 where id =: li.Product2Id];
            o.Opportunity_Products__c += p.name;
            count ++;
        } 
        update o;
    }
}

 
I am trying to update a custom object using REST api like this:

REST method:
POST
 
URI endpoint: 
/services/data/v41.0/sobjects/estimator__c
 
Request header:
Content-Type: application/json; charset=UTF-8
Accept: application/json
 
Request body:
{
  "id" : "a014100000OsY9iAAF",
  "active__c" : "false"

}
 
I get error

INVALID_FIELD
  • message: The Id field should not be specified in the sobject data.
  • errorCode: INVALID_FIELD
Can someone help me understand what format I need to use for an update? I am new to APIs. Many thanks
Hello. I have a custom object contractor__c child object under opportunity. If a contractor__c is created, I need to make sure one and only one contractor__c is marked as primary for the opportunity. I tried an Apex trigger like this but it's not working. If I set the first contractor as primary, it will also set the second contractor as primary. And if I turn the primary flag off for the first contractor, it does not turn on the primary flag for the second contractor. Any help is appreciated.
 
trigger VerifyOnlyOnePrimaryContractor on Contractor__c (before insert, before update) {
    
    for(Contractor__c c: trigger.new){
        string O = c.Opportunity__c;
        string thisContractor = c.ID;
        //if this contractor is marked primary, make all the others for the same opportunity not primary
        if(c.Primary__c){
            List<contractor__c> cList = [Select id from Contractor__c where Opportunity__c = :O and id <> :thisContractor];
            
            for(contractor__c con : cList){
                con.Primary__c = FALSE;
            }
            update cList;
        }
        
        else{
            //if no contractors are marked as primary, set one of them as primary
            string primary = 'no';
            List<contractor__c> cList1 = [Select id,primary__c from Contractor__c where Opportunity__c = :O];
            if(cList1.size() == 0){
                c.Primary__c = TRUE;
            }
            else
            {
                for(contractor__c con1 : cList1){
                    if(con1.Primary__c){
                        primary = 'yes';
                    }
                }
                if(primary == 'no'){
                    
                    c.Primary__c = TRUE;
                }
            }
        }
        
    }                                                                                                                                                                                                       
}

 
I created a lightning component to override the standard "new" opportunity. The problem is that when I implement the force:hasRecordId interface, the recordId shows in my debugger as "undefined". I need to use the current id of the account or contact to pre-populate fields in my component. How can I do this?

Here is the documentation I found, which seems to explain that recordId is undefined in my situation.

https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_interfaces_force_hasrecordid.htm

The recordId attribute is set only when you place or invoke the component in an explicit record context. For example, when you place the component directly on a record page layout, or invoke it as an object-specific action from a record page or object home. In all other cases, such as when you invoke the component as a global action, or create the component programmatically inside another component, recordIdisn’t set, and your component shouldn’t depend on it.
These unsupported contexts include a few contexts that might seem like they should have access to the current record. Examples of these other contexts include the following:
Invoking the component from a global action (even when you’re on a record page)
Invoking the component from header or footer navigation in a community (even if the page shows a record)
force:hasRecordId and force:hasSObjectName are unsupported in these contexts. While the marker interfaces still add the relevant attribute to the component, accessing either attribute generally returns null or undefined.

Thanks for helping.
Hello.
The "View Source" button in Trailhead does not work in Chrome. It works in IE. Am I doing something wrong? 

User-added image

 
Hello.
My markup works ok on the desktop but when I test on mobile, the sitelookup field expands if I select an account with a long name. Then the screen becomes unusable (can't press the Save button or read the other fields. Is there an SLDS class to prevent a field from resizing to fit the selected name?
<lightning:layout >
        <lightning:layoutItem padding="around-small" size="{!v.screenSize}" class="slds-align_absolute-center">
            <lightning:card iconName="standard:opportunity" title="New Opportunity">
                <form class="slds-form--stacked">         
                    
                    <lightning:input aura:id="oppform" label="Opportunity Name"
                                     name="oppname"
                                     value="{!v.newOpp.Name}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <lightning:input type="number" aura:id="oppform" label="Revenue"
                                     name="revenue"
                                     value="{!v.newOpp.Amount}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <lightning:input type="date" aura:id="oppform" label="Estimated Close Date"
                                     name="closedate"
                                     value="{!v.newOpp.CloseDate}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <c:strike_lookup aura:id="sitelookup"                                     
                                     value="{!v.siteID}"
                                     label="Site"
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select a site"
                                     iconName="standard:account"
                                     filter="{!v.filter}"
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small "
                                     required="true"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   Enter a site. You may enter more sites after saving. Do not enter a contractor or EPC.</small></i></div></p>
                    <br/>
                    
                    <c:strike_lookup aura:id="ownerlookup" 
                                     value="{!v.newOpp.AccountId}"
                                     label="Owner" 
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select an owner"
                                     iconName="standard:account"
                                     filter="type = 'owner'"
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small"
                                     required="true"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   Site owner. Do not enter a contractor or EPC.</small></i></div></p>
                    <br/>
                    
                    <c:strike_lookup aura:id="contractorlookup"                                     
                                     value="{!v.contractorID}"
                                     label="Contractor" 
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select a contractor"
                                     iconName="standard:account"
                                     filter="type = 'contractor'"                                     
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   (Optional) CG or EPC. If bidding to multiple contractors, you may enter more contractors after saving.</small></i></div></p>                    
                    
                    <p>     <div class="slds-text-color_error" >     <ui:outputText value="{!v.Err}" /></div></p>
                   
                    <lightning:button label="Save"
                                      class="slds-m-around_small"
                                      variant="brand"
                                      onclick="{!c.clickCreate}"/>
                </form>
            </lightning:card>
        </lightning:layoutItem>
    </lightning:layout>
 
doInit: function(component) {
        var userAgent = navigator.userAgent || navigator.vendor || window.opera;
        if(userAgent.match( /iPad/i ) || userAgent.match( /iPhone/i ) || userAgent.match( /iPod/i ) || userAgent.match( /Android/i )) {
            component.set("v.screenSize", 12);
        } else component.set("v.screenSize", 6);
    },

Thanks
Denise
Hello Salesforce experts,
I was going through my Salesforce Dev601 training manual from Developing Lightning Components. In the second chapter, there's this:
<aura:attribute name="student" type="Contact" access="public" 
default="{'sobjectType':'Contact','Name':'John Smith',PhotoUrl:'/services/images/photo/003B0000009VnYcIAK'}"/>
Was just wondering how that works? Name and PhotoUrl are not fields in the Contact object, so can I define this student attribute default with any name/value pairs I want even though I define it as a type of Contact? So confused...

Thanks for helping.
Hello.
I am creating a lightning component to override the New Opportunity button. Stagename is excluded, as I populate that field with an Apex trigger. What is the most efficient way to search for the account? I have 85,000 accounts, so should I use a combo box.... I need an idea on what to use.  Right now, the user has to enter the AccountID to save. Thanks in advance! 

NewOpp.apxc
public class NewOpp {
    
    @AuraEnabled
    public static void saveOpp(Opportunity opp) {
        system.debug('opp:' + opp);

        insert opp;
        //return opp.id;
    }
}

NewOpp.cmp
<aura:component controller="NewOpp" implements="flexipage:availableForAllPageTypes,lightning:actionOverride" access="global" >
    <aura:attribute name="opps" type="Opportunity[]"/>

    
    <aura:attribute name="newOpp" type="Opportunity"
                    default="{ 'sobjectType': 'Opportunity',
                             'Name': '',
                             'AccountId': '',
                             'CloseDate': '',
                             'Amount': 0 }"/>
    
    <lightning:card iconName="standard:opportunity" title="New Opportunity">
        <form class="slds-form--stacked">         
            <lightning:input aura:id="oppform" label="Owner"
                             name="ownername"
                             value="{!v.newOpp.AccountId}"
                             required="true"/>
            
            <lightning:input aura:id="oppform" label="Opportunity Name"
                             name="oppname"
                             value="{!v.newOpp.Name}"
                             required="true"/>
            
            <lightning:input type="number" aura:id="oppform" label="Revenue"
                             name="revenue"
                             value="{!v.newOpp.Amount}"
                             required="true"/>
            
            <lightning:input type="date" aura:id="oppform" label="Estimated Close Date"
                             name="closedate"
                             value="{!v.newOpp.CloseDate}"
                             required="true"/>
            <lightning:button label="Save"
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreate}"/>

        </form>
    </lightning:card>
</aura:component>

NewOppController.js
({
    clickCreate: function(component, event, helper) {
        var validOpp = component.find('oppform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validOpp){
            // Create the new expense
            var newOpp = component.get("v.newOpp");
            console.log("Create opp: " + JSON.stringify(newOpp));
            helper.createOpp(component, newOpp);
        }
    }
})

NewOppHelper.js
({
    createOpp: function(component, opp) {
    var action = component.get("c.saveOpp");
    action.setParams({
        "opp": opp
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            var opps = component.get("v.opps");
            opps.push(response.getReturnValue());
            component.set("v.opps", opps);
          //  var urlOpp = $A.get("e.force:navigateToURL");
          //  urlOpp.setParams({
          //      "url": response.getReturnValue()
                
          //  });
          //  urlOpp.fire();
         
        }
    });
    $A.enqueueAction(action);
},

})

Thanks so much for your help!
 
Hello Salesforce experts,
I am creating my first lightning component to get a list of contacts from an account, display input fields for an event subject and description and then create/save that event back to Salesforce. I am stuck on the creation of the event. I may be missing something very basic. Was wondering if anyone could point me in the right direction.

ContactListController.aspx
public with sharing class ContactListController {
    @AuraEnabled
    public static List<Contact> getContacts(Id recordId) {
        return [Select Id, FirstName, LastName, Email, Phone, Title From Contact Where AccountId = :recordId];
    }
}
NewMeeting.cmp
<aura:component controller="ContactListController" implements="force:lightningQuickAction,force:hasRecordId" access="global">
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="Account" type="Account" />
    <aura:attribute name="Contacts" type="Contact" />
    <aura:attribute name="Columns" type="List" />
    
 <!--   <aura:attribute name="EventID" type="String" access="Public" default=""/>   
    <aura:attribute name="newEvent" type="Object" access="Private" />
    <aura:attribute name="newEventFields" type="Object" access="Private" />   -->
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <force:recordData aura:id="accountRecord"
                      recordId="{!v.recordId}"
                      targetFields="{!v.Account}"
                      layoutType="FULL"
                      />

    <lightning:card iconName="standard:contact" title="{! 'New Meeting for ' + v.Account.Name}">
   <!--     <lightning:input Name="Subject" value="{!v.newEventFields.Subject}" label="Subject" placeholder="Subject" /> -->
        <lightning:input Name="Subject" value="Subject" label="Subject" placeholder="Subject" /> 

        <br/>
        <lightning:textarea Name="Desc" value="Notes from your meeting" label="Description" placeholder="Notes from your meeting" />
        <br/>
        <lightning:datatable data="{! v.Contacts }" columns="{! v.Columns }"  />
    </lightning:card>
    
    <div class="slds-text-align_center">
        <lightning:button variant="brand" label="Save" onclick="{!c.onSave}" />
    </div>
    
</aura:component>

NewMeetingController.js
({
    doInit : function(component, event, helper) {
        helper.onInit(component,event,helper);
    }
})

NewMeetingHelper.js
({
    onInit: function(component,event,helper) {
        component.set("v.Columns",[
            {label:"First Name", fieldName:"FirstName", type:"text"},
            {label:"Last Name", fieldName:"LastName", type:"text"},
            {label:"Title", fieldName:"Title", type:"text"}
        ]);
        
        var action = component.get("c.getContacts");
        action.setParams({
            recordId: component.get("v.recordId")
        });
        action.setCallback(this, function(data) {
            component.set("v.Contacts", data.getReturnValue()); 
        });
        $A.enqueueAction(action);
    }
})

I tried doing something like this in my helper Javascript, but couldn't get it working:
if (component.get('v.EventID') == '') { 
            component.find("newEvent").getNewRecord(
                "Event", // sObject type (objectApiName)
                null,      // recordTypeId
                false,     // skip cache?
                $A.getCallback(function() {
                    var rec = component.get("v.newEvent");
                	})
            )}






 
Hi. I have a VF page with custom controller on a global action to create an event. After saving, I need the SF1 mobile app to redirect to the event I just created. I've research this and tried several things, but nothing seems to work on mobile.

I tried the below in my save method, but I get "You can't view this page, either because you don't have permission or because the page isn't supported on mobile devices."
insert ev;
PageReference nextPage = new PageReference('/one/one.app#/sObject/' + ev.Id);
    return nextPage;
I've also tried this, but it does nothing:
 
insert ev;
return new ApexPages.StandardController(ev).view();
How can I get this working on a mobile device? Thanks !


 
Hello developers,
I am fairly new to SF development. I have a custom VF page on a global quick action that creates an event. I want to make the vertical spacing on the page more appealing when viewed in SF1. I tried using the new lightningstylesheets="true" tag available in Winter 18, but it still doesn't look very good. I'd like to have more vertical spacing between my inputfields, for starters. Two other strange things I've noticed: searching on the account field cancels out of the screen on iPhone and after saving it navigates back to the home screen. I'd like it to navigate to the new event. Any help or advice is greatly appreciated.
 
<apex:page controller="NewMeeting" lightningStylesheets="true">
<apex:form >
  
<apex:pageBlock >
<apex:pageMessages />
<apex:pageBlockSection id="eventInformation" columns="1">

    <apex:inputfield label="{!accountLabel}" value="{!dummyContact.AccountId}" >
        <apex:actionSupport action="{!changeAccount}" event="onchange" rerender="eventInformation" />
    </apex:inputField>
    <apex:selectList label="{!contactLabel}" value="{!contactId}" size="1" rendered="{!showContactOptions}" id="contactselectlist">
        <apex:selectOptions value="{!contactOptions}" />
        <apex:actionSupport action="{!changeContact}" event="onchange" rerender="eventInformation" />
    </apex:selectList>
    <apex:pageBlockSectionItem rendered="{!!showContactOptions}"/>
    <apex:inputfield value="{!ev.subject}"/> 
    <apex:inputfield value="{!ev.description}"/>     
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}" /> 
   <apex:commandbutton value="Cancel" action="{!cancel}" /> 
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
      
</apex:form>
</apex:page>
Hi. I created a custom controller to save both an event and a contact. Here's the code. I have an error at line 20 after entering the last name for the contact. The error states the last name is required. I am lost.
 
<apex:page controller="NewEventwithContactController" >
<apex:form >
<apex:slds >
        
<div class="slds-scope"> 
<apex:pageBlock title="New Meeting">
<apex:pageMessages />
<apex:pageBlockSection id="eventInformation">
    <apex:inputfield value="{!ev.description}"/> 
    <apex:inputfield value="{!ev.WhatID}"  />
	<apex:inputField value="{!Newcontact.firstName}"  />
    <apex:inputField value="{!Newcontact.lastName}"  />
    <apex:inputField value="{!Newcontact.email}" />     
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}" immediate="true"/>  
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
    
</div>
</apex:slds>       
</apex:form>
</apex:page>


public class NewEventwithContactController {

public event ev { get; set; }
   
public contact NewContact { get; set; }
    
public NewEventwithContactController (){
    Newcontact = new Contact();
    ev = new event();
    ev.CurrencyIsoCode = UserInfo.getDefaultCurrency();
    ev.OwnerId = UserInfo.getUserId();
    ev.StartDateTime = Datetime.now().addMinutes(-Datetime.now().minute());
    ev.EndDateTime = Datetime.now().addMinutes(60-Datetime.now().minute());  
    ev.Subject = 'New Meeting';
}
    
public PageReference save() {
    if (ev.WhatID != null)
      	{ NewContact.AccountId = ev.WhatID; }
      insert NewContact;
      ev.WhoId = NewContact.Id;
    return new ApexPages.StandardController(ev).save();
  }  
   
}

 
Hello. I am still new to Salesforce development and have a problem that seems over my head. I have to create an event where the contact is associated to the account, so I created my own VF page with custom controller. If the contact doesn't exist, the user can click the "New Contact" button that renders a pageBlock below to add a contact. The problem is after saving the contact, I need the contact selectlist to refresh with new contact as the selected contact. Seems easy, but I am stuck on this. Thank you for spending your valuable time looking at this.
<apex:page controller="NewEventController1" showHeader="true" sidebar="true" standardStylesheets="true">
<apex:form >
<apex:slds >
        
<div class="slds-scope"> 
<apex:pageBlock title="New Meeting">
<apex:pageMessages />
<apex:pageBlockSection columns="1" id="eventInformation">
    <apex:inputfield value="{!ev.subject}"/> 
    <apex:inputfield value="{!ev.startdatetime}" />     
    <apex:inputfield value="{!ev.description}"/> 
    <apex:inputfield label="{!accountLabel}" value="{!dummyContact.AccountId}" >
        <apex:actionSupport action="{!changeAccount}" event="onchange" rerender="eventInformation" />
    </apex:inputField>
    <apex:selectList label="{!contactLabel}" value="{!contactId}" size="1" rendered="{!showContactOptions}" id="contactselectlist">
        <apex:selectOptions value="{!contactOptions}" />
        <apex:actionSupport action="{!changeContact}" event="onchange" rerender="eventInformation" />
    </apex:selectList>
    <apex:pageBlockSectionItem rendered="{!!showContactOptions}"/>
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}" immediate="true"/>  
   <apex:commandbutton value="Cancel" action="{!cancel}"/>  
   <apex:commandbutton value="New Contact" action="{!newcontact}"/>      
<!--  <apex:commandButton value="New Contact" action="{!URLFOR($Action.Contact.NewContact)}" /> -->
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
<apex:pageBlock title="Contact Info" rendered="{!RenderContact}" id="contactinformation" >
      <apex:pageBlockButtons >
          <apex:commandButton action="{!insertContact}" value="Insert" reRender="eventinformation"/>
      </apex:pageBlockButtons>
      <apex:pageBlockSection showHeader="false" columns="1">
        <apex:inputField value="{!Newcontact.firstName}" />
        <apex:inputField value="{!Newcontact.lastName}" />
        <apex:inputField value="{!Newcontact.email}" />
      </apex:pageBlockSection>
    </apex:pageBlock>
    
</div>
</apex:slds>       
</apex:form>
</apex:page>



public with sharing class NewEventController1 {

public event ev { get; set; }

public Contact Newcontact {
        get {
        if (Newcontact == null)
        Newcontact = new Contact();
        return Newcontact;
        }
        set; }

public boolean RenderContact { get; set; }
    
public NewEventController1 (){
    RenderContact = false;
    ev = new event();
    ev.CurrencyIsoCode = UserInfo.getDefaultCurrency();
    ev.OwnerId = UserInfo.getUserId();
    ev.StartDateTime = Datetime.now().addMinutes(-Datetime.now().minute());
    ev.EndDateTime = Datetime.now().addMinutes(60-Datetime.now().minute());  
    ev.Subject = 'New Meeting';
    
    if ( ev.WhatId != null && ev.WhatId.getSObjectType() == Account.sObjectType )
        {
            dummyContact.AccountId = ev.WhatId;
        }
}

public Contact dummyContact
    {
        get
        {
            if ( dummyContact == null ) dummyContact = new Contact();
            return dummyContact;
        }
        private set;
    }

    public List<SelectOption> contactOptions
    {
        get
        {
            if ( contactOptions == null && dummyContact.AccountId != null )
            {
                contactOptions = new List<SelectOption>();
                contactOptions.add( new SelectOption( 'null', '--None--' ) );
                for ( Contact contact :
                    [   SELECT  Id, Name
                        FROM    Contact
                        WHERE   AccountId = :dummyContact.AccountId
                    ]
                    )
                {
                    contactOptions.add( new SelectOption( contact.Id, contact.Name ) );
                }
            }
            return contactOptions;
        }
        private set;
    }

    public Boolean showContactOptions
    {
        get { return contactOptions != null && contactOptions.size() > 1; }
    }

    public String contactId { get; set; }
    
	public String accountLabel
    {
        get { return Account.sObjectType.getDescribe().getLabel(); }
    }

    public String contactLabel
    {
        get { return Contact.sObjectType.getDescribe().getLabel(); }
    }
    
	public void changeAccount()
    {
        ev.WhatId = dummyContact.AccountId;
        ev.WhoId = null;
        contactOptions = null;
    }

    public void changeContact()
    {
                
        ev.WhoId =
        (   ( contactId != null && contactId != 'null' )
        ?   Id.valueOf( contactId )
       :   null
        ); 
    }    
    
public PageReference save() {
    
    return new ApexPages.StandardController(ev).save();
  }  
    
public PageReference newcontact() {
      RenderContact = true;
      return null;
  } 
    
public PageReference insertContact() {
      if (dummyContact.AccountId != null)
      	{ NewContact.AccountId = dummyContact.AccountId; }
      insert NewContact;
      ev.WhoId = NewContact.Id;
      return null;
  }      
    
public PageReference cancel() {
      return new ApexPages.StandardController(ev).cancel();
  }     
}



 
Hello Salesforce exports,
Newbie question here. I have a VF page using a custom controller with a commandbutton navigating to the standard New Contact page. After the user saves a contact there, I need to return to my VF page with the data refreshed. I'm hoping there is a simple way to do this, but I haven't come up with anything yet. Help is greatly appreciated.
<apex:commandButton value="New Contact" action="{!URLFOR($Action.Contact.NewContact)}"  />

 
Hello. I have an Apex class and Visual Force page to create an event, where the user first selects the Account and then the page will display only the Contacts associated with that Account. I need my List<SelectionOption> to show the "+ New Contact" option that appears when you create a regular event in Salesforce. Is there a way to do this?
 
public List<SelectOption> contactOptions
    {
        get
        {
            if ( contactOptions == null && dummyContact.AccountId != null )
            {
                contactOptions = new List<SelectOption>();
                contactOptions.add( new SelectOption( 'null', '--None--' ) );
                for ( Contact contact :
                    [   SELECT  Id, Name
                        FROM    Contact
                        WHERE   AccountId = :dummyContact.AccountId
                    ]
                    )
                {
                    contactOptions.add( new SelectOption( contact.Id, contact.Name ) );
                }
            }
            return contactOptions;
        }
        private set;
    }

 
Hello. I am creating a custom controller to insert an event. I understand it has to be a custom controller so it can be fired from a global action on Salesforce1. I need Visualforce to fire an event when either the Contact (whoid) or Account (whatid) is selected on the page so that I can dynamically create the SOSL to restrict the Contact or Account to those that are related to each other. Users should not be able to select a Contact unrelated to an Account. How can I do this? Thanks so much.

VisualForce:
<apex:page controller="NewEvent">
<apex:form >
<apex:pageBlock title="Event Details">

<apex:pageMessages />
<apex:pageBlockSection title="Event Information">
    <apex:inputfield value="{!ev.subject}"/>
    <apex:inputfield value="{!ev.description}"/>   
    <apex:inputfield value="{!ev.startdatetime}"/>
    <apex:inputfield value="{!ev.enddatetime}"/>
    <apex:inputfield value="{!ev.whoid}"/>
    <apex:inputfield value="{!ev.whatid}"/>  
</apex:pageBlockSection>
        
<apex:pageBlockbuttons >
   <apex:commandbutton value="Save" action="{!save}"/>    
</apex:pageBlockbuttons>    
    
</apex:pageBlock>
</apex:form>
</apex:page>

Apex:
public class NewEvent {

public event ev { get; set; }
    
public newevent (){
    ev = new event();
    ev.CurrencyIsoCode = UserInfo.getDefaultCurrency();
    ev.OwnerId = UserInfo.getUserId();
    ev.StartDateTime = Datetime.now().addMinutes(-Datetime.now().minute());
    ev.EndDateTime = Datetime.now().addMinutes(60-Datetime.now().minute());   
}
    
public PageReference save() {
      return new ApexPages.StandardController(ev).save();
  }    
}
Hello. I wrote an Apex trigger that works fine to update a custom field on the opportunity when an opportunitylineitem is updated. The problem is when I try to import 200 records I get the error: UpdateOpptyProductText: System.LimitException: Too many SOQL queries: 101. Many thanks for helping.
 
trigger UpdateOpptyProductText on OpportunityLineItem (after insert, after update) {
    for (OpportunityLineItem oli : Trigger.New) {
      
        Opportunity o = [select id from Opportunity where id =: oli.OpportunityId];
        o.Opportunity_Products__c = '';
        OpportunityLineItem[] lis = [Select id, name, product2id from opportunitylineitem where opportunityid=:o.Id];
        
        integer count = 0;
        for (OpportunityLineItem li : lis) {
            if (count > 0) {
                o.Opportunity_Products__c += '; ';
            }
            Product2 p = [select id,name from Product2 where id =: li.Product2Id];
            o.Opportunity_Products__c += p.name;
            count ++;
        } 
        update o;
    }
}

 
I am trying to update a custom object using REST api like this:

REST method:
POST
 
URI endpoint: 
/services/data/v41.0/sobjects/estimator__c
 
Request header:
Content-Type: application/json; charset=UTF-8
Accept: application/json
 
Request body:
{
  "id" : "a014100000OsY9iAAF",
  "active__c" : "false"

}
 
I get error

INVALID_FIELD
  • message: The Id field should not be specified in the sobject data.
  • errorCode: INVALID_FIELD
Can someone help me understand what format I need to use for an update? I am new to APIs. Many thanks
Hello. I have a custom object contractor__c child object under opportunity. If a contractor__c is created, I need to make sure one and only one contractor__c is marked as primary for the opportunity. I tried an Apex trigger like this but it's not working. If I set the first contractor as primary, it will also set the second contractor as primary. And if I turn the primary flag off for the first contractor, it does not turn on the primary flag for the second contractor. Any help is appreciated.
 
trigger VerifyOnlyOnePrimaryContractor on Contractor__c (before insert, before update) {
    
    for(Contractor__c c: trigger.new){
        string O = c.Opportunity__c;
        string thisContractor = c.ID;
        //if this contractor is marked primary, make all the others for the same opportunity not primary
        if(c.Primary__c){
            List<contractor__c> cList = [Select id from Contractor__c where Opportunity__c = :O and id <> :thisContractor];
            
            for(contractor__c con : cList){
                con.Primary__c = FALSE;
            }
            update cList;
        }
        
        else{
            //if no contractors are marked as primary, set one of them as primary
            string primary = 'no';
            List<contractor__c> cList1 = [Select id,primary__c from Contractor__c where Opportunity__c = :O];
            if(cList1.size() == 0){
                c.Primary__c = TRUE;
            }
            else
            {
                for(contractor__c con1 : cList1){
                    if(con1.Primary__c){
                        primary = 'yes';
                    }
                }
                if(primary == 'no'){
                    
                    c.Primary__c = TRUE;
                }
            }
        }
        
    }                                                                                                                                                                                                       
}

 
Hello.
The "View Source" button in Trailhead does not work in Chrome. It works in IE. Am I doing something wrong? 

User-added image

 
Hello.
My markup works ok on the desktop but when I test on mobile, the sitelookup field expands if I select an account with a long name. Then the screen becomes unusable (can't press the Save button or read the other fields. Is there an SLDS class to prevent a field from resizing to fit the selected name?
<lightning:layout >
        <lightning:layoutItem padding="around-small" size="{!v.screenSize}" class="slds-align_absolute-center">
            <lightning:card iconName="standard:opportunity" title="New Opportunity">
                <form class="slds-form--stacked">         
                    
                    <lightning:input aura:id="oppform" label="Opportunity Name"
                                     name="oppname"
                                     value="{!v.newOpp.Name}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <lightning:input type="number" aura:id="oppform" label="Revenue"
                                     name="revenue"
                                     value="{!v.newOpp.Amount}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <lightning:input type="date" aura:id="oppform" label="Estimated Close Date"
                                     name="closedate"
                                     value="{!v.newOpp.CloseDate}"
                                     required="true"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <c:strike_lookup aura:id="sitelookup"                                     
                                     value="{!v.siteID}"
                                     label="Site"
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select a site"
                                     iconName="standard:account"
                                     filter="{!v.filter}"
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small "
                                     required="true"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   Enter a site. You may enter more sites after saving. Do not enter a contractor or EPC.</small></i></div></p>
                    <br/>
                    
                    <c:strike_lookup aura:id="ownerlookup" 
                                     value="{!v.newOpp.AccountId}"
                                     label="Owner" 
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select an owner"
                                     iconName="standard:account"
                                     filter="type = 'owner'"
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small"
                                     required="true"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   Site owner. Do not enter a contractor or EPC.</small></i></div></p>
                    <br/>
                    
                    <c:strike_lookup aura:id="contractorlookup"                                     
                                     value="{!v.contractorID}"
                                     label="Contractor" 
                                     object="Account"
                                     searchField="Name"
                                     placeholder="Select a contractor"
                                     iconName="standard:account"
                                     filter="type = 'contractor'"                                     
                                     order="Name"
                                     limit="5"
                                     loadingMessage="Loading..."
                                     errorMessage="Invalid input"
                                     class="slds-p-horizontal_x-small"/>
                    
                    <p>    <div class="slds-p-horizontal_x-small" > 
                        <i><small>   (Optional) CG or EPC. If bidding to multiple contractors, you may enter more contractors after saving.</small></i></div></p>                    
                    
                    <p>     <div class="slds-text-color_error" >     <ui:outputText value="{!v.Err}" /></div></p>
                   
                    <lightning:button label="Save"
                                      class="slds-m-around_small"
                                      variant="brand"
                                      onclick="{!c.clickCreate}"/>
                </form>
            </lightning:card>
        </lightning:layoutItem>
    </lightning:layout>
 
doInit: function(component) {
        var userAgent = navigator.userAgent || navigator.vendor || window.opera;
        if(userAgent.match( /iPad/i ) || userAgent.match( /iPhone/i ) || userAgent.match( /iPod/i ) || userAgent.match( /Android/i )) {
            component.set("v.screenSize", 12);
        } else component.set("v.screenSize", 6);
    },

Thanks
Denise
Hello Salesforce experts,
I was going through my Salesforce Dev601 training manual from Developing Lightning Components. In the second chapter, there's this:
<aura:attribute name="student" type="Contact" access="public" 
default="{'sobjectType':'Contact','Name':'John Smith',PhotoUrl:'/services/images/photo/003B0000009VnYcIAK'}"/>
Was just wondering how that works? Name and PhotoUrl are not fields in the Contact object, so can I define this student attribute default with any name/value pairs I want even though I define it as a type of Contact? So confused...

Thanks for helping.
Hello.
I am creating a lightning component to override the New Opportunity button. Stagename is excluded, as I populate that field with an Apex trigger. What is the most efficient way to search for the account? I have 85,000 accounts, so should I use a combo box.... I need an idea on what to use.  Right now, the user has to enter the AccountID to save. Thanks in advance! 

NewOpp.apxc
public class NewOpp {
    
    @AuraEnabled
    public static void saveOpp(Opportunity opp) {
        system.debug('opp:' + opp);

        insert opp;
        //return opp.id;
    }
}

NewOpp.cmp
<aura:component controller="NewOpp" implements="flexipage:availableForAllPageTypes,lightning:actionOverride" access="global" >
    <aura:attribute name="opps" type="Opportunity[]"/>

    
    <aura:attribute name="newOpp" type="Opportunity"
                    default="{ 'sobjectType': 'Opportunity',
                             'Name': '',
                             'AccountId': '',
                             'CloseDate': '',
                             'Amount': 0 }"/>
    
    <lightning:card iconName="standard:opportunity" title="New Opportunity">
        <form class="slds-form--stacked">         
            <lightning:input aura:id="oppform" label="Owner"
                             name="ownername"
                             value="{!v.newOpp.AccountId}"
                             required="true"/>
            
            <lightning:input aura:id="oppform" label="Opportunity Name"
                             name="oppname"
                             value="{!v.newOpp.Name}"
                             required="true"/>
            
            <lightning:input type="number" aura:id="oppform" label="Revenue"
                             name="revenue"
                             value="{!v.newOpp.Amount}"
                             required="true"/>
            
            <lightning:input type="date" aura:id="oppform" label="Estimated Close Date"
                             name="closedate"
                             value="{!v.newOpp.CloseDate}"
                             required="true"/>
            <lightning:button label="Save"
                          class="slds-m-top--medium"
                          variant="brand"
                          onclick="{!c.clickCreate}"/>

        </form>
    </lightning:card>
</aura:component>

NewOppController.js
({
    clickCreate: function(component, event, helper) {
        var validOpp = component.find('oppform').reduce(function (validSoFar, inputCmp) {
            // Displays error messages for invalid fields
            inputCmp.showHelpMessageIfInvalid();
            return validSoFar && inputCmp.get('v.validity').valid;
        }, true);
        // If we pass error checking, do some real work
        if(validOpp){
            // Create the new expense
            var newOpp = component.get("v.newOpp");
            console.log("Create opp: " + JSON.stringify(newOpp));
            helper.createOpp(component, newOpp);
        }
    }
})

NewOppHelper.js
({
    createOpp: function(component, opp) {
    var action = component.get("c.saveOpp");
    action.setParams({
        "opp": opp
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
            var opps = component.get("v.opps");
            opps.push(response.getReturnValue());
            component.set("v.opps", opps);
          //  var urlOpp = $A.get("e.force:navigateToURL");
          //  urlOpp.setParams({
          //      "url": response.getReturnValue()
                
          //  });
          //  urlOpp.fire();
         
        }
    });
    $A.enqueueAction(action);
},

})

Thanks so much for your help!