• Denise Crosby
  • NEWBIE
  • 130 Points
  • Member since 2017
  • Salesforce Developer
  • MORI Associates

  • Chatter
    Feed
  • 0
    Best Answers
  • 1
    Likes Received
  • 0
    Likes Given
  • 18
    Questions
  • 66
    Replies
Hello friends,
I inherited a visualforce page with over 4000 lines of code in it. It is hitting the 'Maximum view state size limit (135KB) exceeded' error message. I know that queries in the custom controller need to be obtimized, etc, but there are 56 select statements and I'm not familiar with the data structure at all. Is there a fairly simple, fast way to break the page into components similar to how we break pages into components in Lightning? And should I expect that will help the performance? Tech lead has suggested that I split it into 2 visualforce pages, to quickly get past this problem. The first page would have a single apex:selectlist that the user must select from. The second page would have everything else with data dependent upon the selection from the apex:selectlist on the first page. I'm not convinced this will solve the problem though. We plan to move to Lightning soon, so we don't want to completely rebuild in visualforce. Any advice here is greatly appreciated.

Sample code is posted here. There are a total of 112 output panels on this page and it looks like some of them are rendered or not based on boolean values. Ugh.
<!--Salesforce Licenses-->
             <div class="row">
                <div class="col-sm-12 m40">  
                    <a name="bac"></a>
                    <apex:outputPanel id="SalesforceLicensesRepeat">
                    <table cellpadding="0" cellspacing="0" class="bordered" style="width:1280px;border:1px solid #222;">
                    <tr>
                        <td colspan="9" class="darkgrayback">
                            <div class="tabletop noborder">
                                Salesforce Licenses
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td class="lightgreenback borderbottom1 thead"></td>
                        <td class="lightgreenback borderbottom1 thead">Value</td>
                        <td class="lightgreenback borderbottom1 thead">Description</td>
                        <td class="lightgreenback borderbottom1 thead">Notes</td>
                        <td class="lightgreenback borderbottom1 thead">Attachment</td>
                        <td class="lightgreenback borderbottom1 thead">Confirmation</td>
                        <td class="lightgreenback borderbottom1 thead">Date</td>
                        <td class="lightgreenback borderbottom1 thead">Fund Code</td>
                        <td class="lightgreenback borderbottom1 thead"></td>
                    </tr>  
                    <apex:repeat value="{!SalesforceLicenses}" var="ba">   
                    <tr>
                        <td class="lightgreenback" style="text-align:center;"><apex:commandLink action="{!EditBudgetItem}" oncomplete="showModal('BItemModal')" rerender="binewpanel">
                                <apex:param name="editid" value="{!ba.Id}" assignTo="{!editid}"/>Edit</apex:commandLink>
                        </td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Value__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Description__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Notes__c}" /></td>
                        <td class="lightgreenback" style="text-align:center;">
                            <apex:repeat value="{!ba.Attachments}" var="att">
                                <a href="/servlet/servlet.FileDownload?file={!att.Id}" target="_blank" style="color:#000;text-decoration:underline;">View/Download Attachment</a><br />
                            </apex:repeat>
                            <apex:outputPanel rendered="{!ba.Attachments.size == 0}">
                                    <a href="#AttachModal" data-toggle="modal" data-target="#AttachModal" onclick="UpRecordId('{!ba.Id}')">+ Add</a>
                            </apex:outputPanel>                            
                        </td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Confirmation__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Date__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Fund_Code__c}" /></td>
                        <td class="lightgreenback" style="text-align:center;">
                            <apex:commandLink action="{!DeleteBudgetItem}" onclick="if(!confirm('Are you sure you want to delete this item?\n\nThis action cannot be undone.')){return false};"  rerender="CMOPanel">
                                <apex:param name="delid" value="{!ba.Id}" assignTo="{!delid}"/>Delete</apex:commandLink>
                        </td>
                    </tr>  
                    </apex:repeat> 
                        
                    <tr>
                        <td class="lightgreenback totborder">Total</td>
                        <td class="lightgreenback totborder">
                            <apex:outputText value="${0, number,###,###,###,###}"> 
                                <apex:param value="{!TotalSalesforceLicenses}"/> 
                            </apex:outputText>
                        </td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                    </tr>  

                        
                    <tr>
                        <td colspan="9" class="noback">                         
                            <div style="text-align:right;">
                                <apex:commandLink action="{!NewBudgetItem}" oncomplete="showModal('BItemModal')" rerender="binewpanel" styleClass="btn btn-primary bimodal">
                                <apex:param name="editid" value="Salesforce Licenses" assignTo="{!editid}"/>+ Add</apex:commandLink>
                            </div>                            
                        </td>
                    </tr>
                    
                    
                    </table>
                    </apex:outputPanel>
                </div>
            </div>

 
Hello. This is a really newbie question but I haven't done coding in a while and got stuck. The Visualforce Basics trailhead says to Open your browser’s JavaScript console and enter the following code for format your Visualforce page with Lightning.

$A.get("e.force:navigateToURL").setParams(
    {"url": "/apex/pageName"}).fire();

I know how to get to the Chrome DevTools, but how do you run Javascript inside it?
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();
  }    
}
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 friends,
I inherited a visualforce page with over 4000 lines of code in it. It is hitting the 'Maximum view state size limit (135KB) exceeded' error message. I know that queries in the custom controller need to be obtimized, etc, but there are 56 select statements and I'm not familiar with the data structure at all. Is there a fairly simple, fast way to break the page into components similar to how we break pages into components in Lightning? And should I expect that will help the performance? Tech lead has suggested that I split it into 2 visualforce pages, to quickly get past this problem. The first page would have a single apex:selectlist that the user must select from. The second page would have everything else with data dependent upon the selection from the apex:selectlist on the first page. I'm not convinced this will solve the problem though. We plan to move to Lightning soon, so we don't want to completely rebuild in visualforce. Any advice here is greatly appreciated.

Sample code is posted here. There are a total of 112 output panels on this page and it looks like some of them are rendered or not based on boolean values. Ugh.
<!--Salesforce Licenses-->
             <div class="row">
                <div class="col-sm-12 m40">  
                    <a name="bac"></a>
                    <apex:outputPanel id="SalesforceLicensesRepeat">
                    <table cellpadding="0" cellspacing="0" class="bordered" style="width:1280px;border:1px solid #222;">
                    <tr>
                        <td colspan="9" class="darkgrayback">
                            <div class="tabletop noborder">
                                Salesforce Licenses
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td class="lightgreenback borderbottom1 thead"></td>
                        <td class="lightgreenback borderbottom1 thead">Value</td>
                        <td class="lightgreenback borderbottom1 thead">Description</td>
                        <td class="lightgreenback borderbottom1 thead">Notes</td>
                        <td class="lightgreenback borderbottom1 thead">Attachment</td>
                        <td class="lightgreenback borderbottom1 thead">Confirmation</td>
                        <td class="lightgreenback borderbottom1 thead">Date</td>
                        <td class="lightgreenback borderbottom1 thead">Fund Code</td>
                        <td class="lightgreenback borderbottom1 thead"></td>
                    </tr>  
                    <apex:repeat value="{!SalesforceLicenses}" var="ba">   
                    <tr>
                        <td class="lightgreenback" style="text-align:center;"><apex:commandLink action="{!EditBudgetItem}" oncomplete="showModal('BItemModal')" rerender="binewpanel">
                                <apex:param name="editid" value="{!ba.Id}" assignTo="{!editid}"/>Edit</apex:commandLink>
                        </td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Value__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Description__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Notes__c}" /></td>
                        <td class="lightgreenback" style="text-align:center;">
                            <apex:repeat value="{!ba.Attachments}" var="att">
                                <a href="/servlet/servlet.FileDownload?file={!att.Id}" target="_blank" style="color:#000;text-decoration:underline;">View/Download Attachment</a><br />
                            </apex:repeat>
                            <apex:outputPanel rendered="{!ba.Attachments.size == 0}">
                                    <a href="#AttachModal" data-toggle="modal" data-target="#AttachModal" onclick="UpRecordId('{!ba.Id}')">+ Add</a>
                            </apex:outputPanel>                            
                        </td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Confirmation__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Date__c}" /></td>
                        <td class="lightgreenback"><apex:outputField value="{!ba.Fund_Code__c}" /></td>
                        <td class="lightgreenback" style="text-align:center;">
                            <apex:commandLink action="{!DeleteBudgetItem}" onclick="if(!confirm('Are you sure you want to delete this item?\n\nThis action cannot be undone.')){return false};"  rerender="CMOPanel">
                                <apex:param name="delid" value="{!ba.Id}" assignTo="{!delid}"/>Delete</apex:commandLink>
                        </td>
                    </tr>  
                    </apex:repeat> 
                        
                    <tr>
                        <td class="lightgreenback totborder">Total</td>
                        <td class="lightgreenback totborder">
                            <apex:outputText value="${0, number,###,###,###,###}"> 
                                <apex:param value="{!TotalSalesforceLicenses}"/> 
                            </apex:outputText>
                        </td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                        <td class="lightgreenback totborder"></td>
                    </tr>  

                        
                    <tr>
                        <td colspan="9" class="noback">                         
                            <div style="text-align:right;">
                                <apex:commandLink action="{!NewBudgetItem}" oncomplete="showModal('BItemModal')" rerender="binewpanel" styleClass="btn btn-primary bimodal">
                                <apex:param name="editid" value="Salesforce Licenses" assignTo="{!editid}"/>+ Add</apex:commandLink>
                            </div>                            
                        </td>
                    </tr>
                    
                    
                    </table>
                    </apex:outputPanel>
                </div>
            </div>

 
Hello. This is a really newbie question but I haven't done coding in a while and got stuck. The Visualforce Basics trailhead says to Open your browser’s JavaScript console and enter the following code for format your Visualforce page with Lightning.

$A.get("e.force:navigateToURL").setParams(
    {"url": "/apex/pageName"}).fire();

I know how to get to the Chrome DevTools, but how do you run Javascript inside it?
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!
 
I am new to Visualforce and I am doing the Trailhead: Visualforce Basics Module - Use Standard Controllers.  The instructions state:
To preview your page in the context of Lightning Experience, open your browser’s developer console and enter:
$A.get("e.force:navigateToURL").setParams(
    {"url": "/apex/pageName"}).fire();
I am not sure where to enter this.  When I enter it in the Visualforce page the text just show up on the Visualforce page preview.  I must be missing something.  Any help will be greatly appreciated.