2

I'm accessing a vf page via "action" on lead object, which contains a component.

Action -> Vf Page --> mylightningcomponent --->LeadSource.

the problem is when i click on button/action on record detail page or from Lightning UI on the record, I see " save " which is grayed out. what is causing this behavior ?

And force:inputField supposed to show the picklist values. It doesnt render at all.

my vf page`

 <apex:page standardStylesheets="false" controller="leadController" extends="ltng:outApp">
 <apex:includeLightning />
 <apex:includeScript value="/lightning/lightning.out.js" />
<apex:stylesheet value="{!URLFOR($Resource.SLDS1, 'assets/styles/salesforce-lightning-design-system.css')}" /> 
<div class="slds" style="margin-top:10px;margin-left:10px;"> 
</div>
<div id="lightning" />
<script>
 var leadid = "{!$CurrentPage.parameters.id}";
    console.log(leadid);
    $Lightning.use("c:leadApp", function() {
      $Lightning.createComponent("c:Lead_Comp",
            {"leadid": leadid},
              "lightning",
              function(cmp) {
                  //alert("{!$CurrentPage.parameters.id}");
                // do some stuff
           });
    });
</script>
</apex:page>`

EDIT: Updated my leadcontroller as advised by @crmprogdev My server-controller

public leadController(){

}
@AuraEnabled
public static Lead saveThisLead(id leadId){
    lead myLead = new lead();
    myLead = [select id, name from Lead where id =: leadid];
    upsert myLead;
    return myLead;
}   

}

my Component

<aura:component controller="leadController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
 <ltng:require styles="/Resource/SLDS1/assets/styles/salesforce-lightning-design-system-ltng.css" />
    <aura:handler name="init" value="{!this}" action="{!c.init}"/>
    <aura:attribute name="lead"  type="Lead" default="{ sobjectType: 'Lead'}"/>
    <aura:attribute name="leadid"  type="String" />
    <aura:attribute name="Name" type="String" />
    <force:inputField value="{!v.lead.Street}" />
    <force:inputField value="{!v.lead.LeadSource}" />
</aura:component>

EDIT: adding my app

My App

<aura:application access="GLOBAL" extends="ltng:outApp">

    <aura:dependency resource="c:Lead_Comp"/>
    <c:Lead_Comp/>

</aura:application>

EDIT

my component controller

({
    init : function(component, event, helper) {
        var action = component.get("c.saveThisLead");
        console.log("init");
        var ldid = component.get("v.leadid");
        console.log(ldid);
        action.setParams({
           "leadid":ldid
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if(component.isValid() && state ==="SUCCESS"){
                component.set("v.lead", response.getReturnValue());
            } else if (state === "ERROR"){
                var errors = action.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        Component.set("v.message", errors[0].message);
                        console.log(errors[0].message);
                    }
                }
             }
            console.log(response.getReturnValue());
        });
        $A.enqueueAction(action);
    },    
})

2 Answers 2

2

Seems like you're most of the way there already.

I'd suggest switching from

<force:inputField value="{!v.lead.Street}" />

to

<ui:inputText value="{!v.lead.Street}" />

as the force components and events do not appear to be available when using Lightning Out.

The other suggestion I have is to write your own 'Save' functionality in the Lightning Component Controller.

Your Apex Controller could be as simple as:

@AuraEnabled
public static Lead saveLead(Lead myLead){
    try {
        upsert myLead;
    } catch (Exception e) {
        throw new AuraHandledException('Unable to save lead: ' + e.getMessage());
    }

    return myLead;
}

and your client-side controller could be as simple as:

saveLead: function (component, event, helper){
    var action = component.get("c.saveLead");
    var myLead = component.get("v.lead");
    action.setParams({ "myLead": myLead });

    action.setCallback(this, function(response) {
        var state = response.getState();
        // display a message to your user, prompting them to close
        // the action modal
        console.log(state);
    });

    $A.enqueueAction(action);
}

with a simple button

<ui:button label="Save" press="{!c.saveLead}"/>

Additionally, here's a blog that might help.

5
  • Thanks for the response @JakeRichter but I'm trying to utilize the standard buttons of the page. I want to utilize the standard buttons of the Modal pop up, "Cancel" and "Save" and your solution is creating an another button. Can you share your thoughts on how can we address that issue ? Aug 16, 2016 at 20:28
  • @naruto-sfdc As far as I know, that is not supported. This would be your best bet until Winter '17 when you'll be able to skip all this nonsense and just use a Lightning Component directly. Check out this preview to the release notes. Aug 17, 2016 at 13:35
  • thank you for the response. Now i can look at other options :) and since you answered what exactly i was looking for i'm going to mark your answer as correct one or answer. Aug 17, 2016 at 21:20
  • @naruto-sfdc, there is a similar question to yours that I answered here. In that scenario, the quick action save button is used, but the Lightning Component is not really doing any of the logic; it's all done in the Visualforce Page. Aug 18, 2016 at 13:37
  • I can not comment on your original post that you mentioned in above comment, but how do you bind the updated values from component to visualforce page? I modified the code you provided there and i'm getting null values for the fields. Aug 19, 2016 at 18:32
1

It appears to me that you may need to add the reference to extends=ltng:outApp in your Component App definition. See Use Lightning Components in Visualforce Pages.

There are three steps to add Lightning components to a Visualforce page.

  1. Add the component to your Visualforce page.
  2. Reference a Lightning app that declares your component dependencies with $Lightning.use().
  3. Write a function that creates the component on the page with $Lightning.createComponent().

You appear to have done all of the above.

Check your application definition to make certain it looks something like below:

<aura:application access="GLOBAL" extends="ltng:outApp"> 
    <aura:dependency resource="ui:button"/>
</aura:application> 

Edit

It doesn't appear to me that your LeadController class has any kind of a getter to grab the lead recordId parameter from the page when it's loaded that your component is looking for. It also doesn't seem to have a means of setting it to the page. Instead, you're relying on your component's javascript to try to get that parameter. I'm not completely certain it can do that since it believe it operates in a different context (it's served from the Lightning Server, not the Visualforce Page Server which can have a different User.sessionId among other things).

Also, since you've not declared your page as using the standard Lead controller plus declared your LeadController as an extension, you may need to instantiate a new instance of the standard controller in your LeadController custom class. It would seem you'd need that in order to have access to the fields in the lead record; something you might want or need your controller to 'get' or query for each record since you're doing a return.

6
  • I added the reference, thank you for pointing that out. but it still didn't work. still both issues persists. Aug 13, 2016 at 20:32
  • I notice that in your leadController, you use the variable name lead in conjunction with the object lead. It's not a wise practice to use object literals as variable names. I won't say that's the cause of your issue, but it's something I'd avoid and most definitely would change in my code. It appears that you may be doing some of the same in your component.
    – crmprogdev
    Aug 13, 2016 at 23:49
  • sure i will remember that next time when i use that! Aug 14, 2016 at 16:20
  • i updated the controller and post as well. But still im no where. I will keep updating this post as i get the more information. right now i m stuck at passing leadId to serverside controller. i get a undefined value in the log and that is causing the issue. var ldid = component.get("v.leadid"); console.log(ldid); Aug 15, 2016 at 18:56
  • Did you at all look at the edits to my answer above? Also, how's the component going to reliably get the v.leadId if you don't have a record or page load event handler for when the page sets v.leadId initially? Trying to pass it using the console.log function feels like a "hack" to me. I'd expect there to be a proper event handler for this.
    – crmprogdev
    Aug 15, 2016 at 20:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .