I'm using a custom lightning component in an app and that app is being used in a VF page, I have created a component for look up thing, since we dont have any standard components/tags for that, And this custom component is working fine when used out side page, Cant figure out where i'm wrong, Any help is appreciated.
VF Page
<apex:page standardController="Traffic__c" sidebar="false" showHeader="false" standardStylesheets="false">
<apex:includeLightning />
<div id="lightning"/>
<div id="lightning2"/>
<script>
$Lightning.use("c:createNewTraffic", function() {
$Lightning.createComponent("c:CreateTraffic",
{},
"lightning2",
function(cmp) {
// do some stuff
});
});
$Lightning.use("c:createNewTraffic", function() {
$Lightning.createComponent("c:AccountLookup",
{},
"lightning",
function(cmp) {
// do some stuff
});
});
</script>
</apex:page>
App:
<aura:application access="GLOBAL" extends="ltng:outApp">
<aura:dependency resource="c:CreateTraffic" />
<aura:dependency resource="c:AccountLookup" />
</aura:application>
AccountLookup.cmp:
<!-- Event handlers -->
<aura:handler name="updateLookupIdEvent" event="c:UpdateLookupId" action="{!c.handleAccountIdUpdate}"/>
<aura:handler name="clearLookupIdEvent" event="c:ClearLookupId" action="{!c.handleAccountIdClear}"/>
<!-- Lookup component -->
<c:LookupSObject label="Account" pluralLabel="Accounts" sObjectAPIName="Account"
listIconSVGPath="/resource/SLDSv0122/assets/icons/standard-sprite/svg/symbols.svg#account"
listIconClass="slds-icon-standard-account"
/>
AccountLookupController.js :
({
/**
* Handler for receiving the updateLookupIdEvent event
*/
handleAccountIdUpdate : function(cmp, event, helper) {
// Get the Id from the Event
var accountId = event.getParam("sObjectId");
// Set the Id bound to the View
cmp.set('v.recordId', accountId);
},
/**
* Handler for receiving the clearLookupIdEvent event
*/
handleAccountIdClear : function(cmp, event, helper) {
// Clear the Id bound to the View
cmp.set('v.recordId', null);
}
})
LookUpSobject.cmp :
<aura:component controller="LookupSObjectController" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
<!-- Required Scripts/Styles -->
<!-- Salesforce Lightning Design System : https://www.lightningdesignsystem.com/ -->
<ltng:require styles="/resource/SLDSv0122/assets/styles/salesforce-lightning-design-system-ltng.css" />
<!-- Attributes -->
<aura:attribute name="sObjectAPIName" type="String" required="false"
description="The API name of the SObject to search" />
<aura:attribute name="label" type="String" required="false"
description="The label to assign to the lookup, eg: Account" />
<aura:attribute name="pluralLabel" type="String" required="false"
description="The plural label to assign to the lookup, eg: Accounts" />
<aura:attribute name="listIconSVGPath" type="String" default="/resource/SLDSv0122/assets/icons/custom-sprite/svg/symbols.svg#custom11"
description="The static resource path to the svg icon to use." />
<aura:attribute name="listIconClass" type="String" default="slds-icon-custom-11"
description="The SLDS class to use for the icon." />
<aura:attribute name="searchString" type="String"
description="The search string to find." />
<!-- Events -->
<aura:registerEvent name="updateLookupIdEvent" type="c:UpdateLookupId"/>
<aura:registerEvent name="clearLookupIdEvent" type="c:ClearLookupId"/>
<!-- Lookup Markup : See https://www.lightningdesignsystem.com/components/lookups -->
<div class="slds">
<div aura:id="lookup-div" class="slds-lookup" data-select="single" data-scope="single" data-typeahead="true">
<!-- This is the Input form markup -->
<div class="slds-form-element">
<label class="slds-form-element__label" for="lookup">{!v.label}</label>
<div class="slds-form-element__control slds-input-has-icon slds-input-has-icon--right">
<c:svg class="slds-input__icon" xlinkHref="/resource/SLDSv0122/assets/icons/utility-sprite/svg/symbols.svg#search" />
<!-- This markup is for when an item is currently selected -->
<div aura:id="lookup-pill" class="slds-pill-container slds-hide">
<span class="slds-pill slds-pill--bare">
<span class="slds-pill__label">
<c:svg class="{!'slds-icon ' + v.listIconClass + ' slds-icon--small'}" xlinkHref="{!v.listIconSVGPath}" />{!v.searchString}
</span>
<button class="slds-button slds-button--icon-bare" onclick="{!c.clear}">
<c:svg class="slds-button__icon" xlinkHref="/resource/SLDSv0122/assets/icons/utility-sprite/svg/symbols.svg#close" />
<span class="slds-assistive-text">Remove</span>
</button>
</span>
</div>
<!-- This markup is for when searching for a string -->
<ui:inputText aura:id="lookup" value="{!v.searchString}" class="slds-input" updateOn="keyup" keyup="{!c.search}" />
</div>
</div>
<!-- This is the lookup list markup. Initially it's hidden -->
<div aura:id="lookuplist" class="slds-lookup__menu slds-hide" role="listbox">
<div class="slds-lookup__item">
<button class="slds-button">
<c:svg class="slds-icon slds-icon-text-default slds-icon--small" xlinkHref="/resource/SLDSv0122/assets/icons/utility-sprite/svg/symbols.svg#search" />
"{!v.searchString}" in {!v.pluralLabel}
</button>
</div>
<ul aura:id="lookuplist-items" class="slds-lookup__list" role="presentation">
</ul>
</div>
</div>
</div>
</aura:component>
LookUpSobjectController.js :
({
/**
* Search an SObject for a match
*/
search : function(cmp, event, helper) {
helper.doSearch(cmp);
},
/**
* Select an SObject from a list
*/
select: function(cmp, event, helper) {
helper.handleSelection(cmp, event);
},
/**
* Clear the currently selected SObject
*/
clear: function(cmp, event, helper) {
helper.clearSelection(cmp);
}
})
LookUpSobjectHelper.js :
({
/**
* Perform the SObject search via an Apex Controller
*/
doSearch : function(cmp) {
// Get the search string, input element and the selection container
var searchString = cmp.get("v.searchString");
var inputElement = cmp.find('lookup');
var lookupList = cmp.find("lookuplist");
var lookupListItems = cmp.find("lookuplist-items");
// Clear any errors and destroy the old lookup items container
inputElement.set('v.errors', null);
lookupListItems.set('v.body', new Array());
// We need at least 2 characters for an effective search
if (typeof searchString === 'undefined' || searchString.length < 2)
{
// Hide the lookuplist
$A.util.addClass(lookupList, 'slds-hide');
return;
}
// Show the lookuplist
$A.util.removeClass(lookupList, 'slds-hide');
// Get the API Name
var sObjectAPIName = cmp.get('v.sObjectAPIName');
// Create an Apex action
var action = cmp.get("c.lookup");
// Mark the action as abortable, this is to prevent multiple events from the keyup executing
action.setAbortable();
// Set the parameters
action.setParams({ "searchString" : searchString, "sObjectAPIName" : sObjectAPIName});
// Define the callback
action.setCallback(this, function(response) {
var state = response.getState();
// Callback succeeded
if (cmp.isValid() && state === "SUCCESS")
{
// Get the search matches
var matches = response.getReturnValue();
console.log('--matches---');
console.log(matches);
// If we have no matches, return
if (matches.length == 0)
{
return;
}
// Render the results
this.renderLookupComponents(cmp, lookupListItems, matches);
}
else if (state === "ERROR") // Handle any error by reporting it
{
var errors = response.getError();
if (errors)
{
if (errors[0] && errors[0].message)
{
this.displayToast('Error', errors[0].message);
}
}
else
{
this.displayToast('Error', 'Unknown error.');
}
}
});
// Enqueue the action
$A.enqueueAction(action);
},
/**
* Render the Lookup List Components
*/
renderLookupComponents : function(cmp, lookupListItems, matches)
{
// list Icon SVG Path and Class
var listIconSVGPath = cmp.get('v.listIconSVGPath');
var listIconClass = cmp.get('v.listIconClass');
// Array of components to create
var newComponents = new Array();
// Add a set of components for each match found
for (var i=0; i<matches.length; i++)
{
// li element
newComponents.push(["aura:html", {
"tag" : "li",
"HTMLAttributes" : {
"class" : "slds-lookup__item"
}
}]);
// a element
newComponents.push(["aura:html", {
"tag" : "a",
"HTMLAttributes" : {
"id" : cmp.getGlobalId() + '_id_' + matches[i].SObjectId,
"role" : "option",
"onclick" : cmp.getReference("c.select")
}
}]);
// svg component
newComponents.push(["c:svg", {
"class" : "slds-icon " + listIconClass + " slds-icon--small",
"xlinkHref" : listIconSVGPath
}]);
// output text component
// For some reason adding an aura:id to this component failed to record the id for subsequent cmp.find requests
newComponents.push(["ui:outputText", {
"value" : matches[i].SObjectLabel
}]);
}
// Create the components
$A.createComponents(newComponents, function(components, status) {
// Creation succeeded
if (status === "SUCCESS")
{
// Get the List Component Body
var lookupListItemsBody = lookupListItems.get('v.body');
// Iterate the created components in groups of 4, correctly parent them and add them to the list body
for (var i=0; i<components.length; i+=4)
{
// Identify the releated components
var li = components[i];
var a = components[i+1];
var svg = components[i+2];
var outputText = components[i+3];
// Add the <a> to the <li>
var liBody = li.get('v.body');
liBody.push(a);
li.set('v.body', liBody);
// Add the <svg> and <outputText> to the <a>
var aBody = a.get('v.body');
aBody.push(svg);
aBody.push(outputText);
a.set('v.body', aBody);
// Add the <li> to the container
lookupListItemsBody.push(li);
}
// Update the list body
lookupListItems.set('v.body', lookupListItemsBody);
}
else // Report any error
{
this.displayToast('Error', 'Failed to create list components.');
}
});
},
/**
* Handle the Selection of an Item
*/
handleSelection : function(cmp, event) {
// Resolve the Object Id from the events Element Id (this will be the <a> tag)
var objectId = this.resolveId(event.currentTarget.id);
// The Object label is the 2nd child (index 1)
var objectLabel = event.currentTarget.children[1].innerText;
// Log the Object Id and Label to the console
console.log('objectId=' + objectId);
console.log('objectLabel=' + objectLabel);
// Create the UpdateLookupId event
var updateEvent = cmp.getEvent("updateLookupIdEvent");
// Populate the event with the selected Object Id
updateEvent.setParams({
"sObjectId" : objectId
});
// Fire the event
updateEvent.fire();
// Update the Searchstring with the Label
cmp.set("v.searchString", objectLabel);
// Hide the Lookup List
var lookupList = cmp.find("lookuplist");
$A.util.addClass(lookupList, 'slds-hide');
// Hide the Input Element
var inputElement = cmp.find('lookup');
$A.util.addClass(inputElement, 'slds-hide');
// Show the Lookup pill
var lookupPill = cmp.find("lookup-pill");
$A.util.removeClass(lookupPill, 'slds-hide');
// Lookup Div has selection
var inputElement = cmp.find('lookup-div');
$A.util.addClass(inputElement, 'slds-has-selection');
},
/**
* Clear the Selection
*/
clearSelection : function(cmp) {
// Create the ClearLookupId event
var clearEvent = cmp.getEvent("clearLookupIdEvent");
// Fire the event
clearEvent.fire();
// Clear the Searchstring
cmp.set("v.searchString", '');
// Hide the Lookup pill
var lookupPill = cmp.find("lookup-pill");
$A.util.addClass(lookupPill, 'slds-hide');
// Show the Input Element
var inputElement = cmp.find('lookup');
$A.util.removeClass(inputElement, 'slds-hide');
// Lookup Div has no selection
var inputElement = cmp.find('lookup-div');
$A.util.removeClass(inputElement, 'slds-has-selection');
},
/**
* Resolve the Object Id from the Element Id by splitting the id at the _
*/
resolveId : function(elmId)
{
var i = elmId.lastIndexOf('_');
return elmId.substr(i+1);
},
/**
* Display a message
*/
displayToast : function (title, message)
{
var toast = $A.get("e.force:showToast");
// For lightning1 show the toast
if (toast)
{
//fire the toast event in Salesforce1
toast.setParams({
"title": title,
"message": message
});
toast.fire();
}
else // otherwise throw an alert
{
alert(title + ': ' + message);
}
}
})
When used inside the app: lookup cmp, Working as expected
When used in a page: lookup cmp, Not working