I am trying to pull the URL for whatever record the user is on when they launch my screenflow.
For example if they are on an account I would need the account URL:
"https://mydomain--partial.lightning.force.com/lightning/r/Account/00000000000000/view"
If they are on a report, I would need the report URL:
"https://mydomain--partial.lightning.force.com/lightning/r/Report/00000000000000000/view?queryScope=userFolders"
My screenflow launches from a utility action.
I'm using the following formula in the screenflow now
(LEFT({!$Api.Partner_Server_URL_260}, FIND( '.com', {!$Api.Partner_Server_URL_260} )) + RIGHT({!$Api.Partner_Server_URL_260}, FIND( '.com', {!$Api.Partner_Server_URL_260} )))
The problem is that this returns:
"https://mydomain--partial.my.salesforce.com/services/Soap/u/26.0/00000000000"
I solved my own question and wanted to share just in case anyone came across this in the future.
What I had to do was:
Call the flow in an aura cmp
Get the window location in the cmp and pass it to an input variable in the flow
CMP:
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction,lightning:isUrlAddressable" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<lightning:flow aura:id="FLOW NAME"/>
</aura:component>
Controller:
({
init : function (cmp) {
var flow = cmp.find("FLOWNAME");
var inputVariables = [
{
name : 'vCurentlURL',
type : 'String',
value : window.location.href,
}
];
flow.startFlow("FLOWNAME", inputVariables );
}
})
Related
Custom Lightning App named "Stack" giving "You dont have access to this record Contact "
Trying to follow steps in How To Implement Full Search in Case Type using Salesforce?
Here is Org wide defaults of the custom object ERT Case Type data
Here is Apex code of stack.aspx
public class Stack {
#AuraEnabled(cacheable=true)
public static List<LookupSearchResult> search(String searchTerm, List<String> selectedIds){
if(String.isBlank(searchTerm) || searchTerm.length() < 2){
return null;
}
String t = '%' + searchTerm + '%'; // decide how you want to search, "starts with", "includes" or what
List<ERT_Case_Type_Data__c> records = [SELECT Id, Name, Level_1__c, Level_2__c, Level_3__c
FROM ERT_Case_Type_Data__c
WHERE Level_1__c LIKE :t OR Level_2__c LIKE :t OR Level_3__c LIKE :t
ORDER BY Level_1__c, Level_2__c, Level_3__c
LIMIT 20];
/* You could also experiment with SOSL?
records = [FIND :('*' + searchTerm + '*') IN ALL FIELDS
RETURNING Case_Type_Data__c(Id, Name, Level_1__c, Level_2__c, Level_3__c)][0];
*/
List<LookupSearchResult> results = new List<LookupSearchResult>();
for(ERT_Case_Type_Data__c ctd : records){
results.add(new LookupSearchResult(ctd.Id, 'ERT_Case_Type_Data__c', 'standard:case_wrap_up', ctd.Name,
String.join(new List<String>{ctd.Level_1__c , ctd.Level_2__c, ctd.Level_3__c}, '; ')
));
}
return results;
}
}
Here is Aura component(html part)
<aura:component implements="force:hasRecordId,force:appHostable,flexipage:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="Stack">
<aura:attribute access="global" type="List" name="selection" default="[]"/>
<aura:attribute access="global" type="List" name="errors" default="[]"/>
<lightning:card title="New Case Type">
<lightning:recordEditForm aura:id="myForm" objectApiName="ERT_Case_Type__c" onsubmit="{!c.onSubmit}" onsuccess="{!c.onSuccess}">
<lightning:messages />
<c:Lookup selection="{!v.selection}" onSearch="{!c.lookupSearch}" onSelection="{!c.useSelected}" errors="{!v.errors}" label="Search" placeholder="Search Case Types Data"/>
<lightning:inputField aura:id="Level_1__c" fieldName="Level_1__c" />
<lightning:inputField aura:id="Level_2__c" fieldName="Level_2__c" />
<lightning:inputField aura:id="Level_3__c" fieldName="Level_3__c" />
<lightning:button class="slds-m-top_small" variant="brand" type="submit" name="save" label="Save" />
</lightning:recordEditForm>
</lightning:card>
</aura:component>
Here is Aura component - JS controller part
({
lookupSearch : function(component, event, helper) {
// Get the lookup component that fired the search event
const lookupComponent = event.getSource();
const serverSearchAction = component.get('c.search');
lookupComponent.search(serverSearchAction);
},
useSelected: function(component, event, helper) {
const selection = component.get('v.selection');
const errors = component.get('v.errors');
if (selection.length) {
if(errors.length){ // Clear errors, if any
component.set('v.errors', []);
}
let levels = selection[0].subtitle.split('; ');
component.find('Level_1__c').set('v.value', levels[0]);
component.find('Level_2__c').set('v.value', levels[1]);
component.find('Level_3__c').set('v.value', levels[2]);
}
},
onSubmit: function(component, event, helper) {
debugger;
event.preventDefault(); // stop the form from submitting
var fields = event.getParam('fields');
fields.Case__c = component.get('v.recordId'); // link to "this" Case
component.find('myForm').submit(fields);
},
onSuccess: function(component, event, helper){
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
"title": "Success!",
"message": "Case Type saved OK, refreshing",
"type": "success"
});
toastEvent.fire();
$A.get('e.force:refreshView').fire(); // reload page
}
})
Please help me in removing this access error
Regards,
Carolyn
I doubt it's sharing related (so not the org-wide settings). If it was sharing it'd simply always return 0 results but no big red errors.
If you remove the line with <c:Lookup selection="{!v.selection}" onSearch="{!c.lookupSearch}" onSelection="{!c.useSelected}" errors="{!v.errors}" label="Search" placeholder="Search Case Types Data"/> does the error go away? If it stays - it's problem with permissions around the custom code or Case_Type_Data__c). If it goes away - it's something with creating ERT_Case_Type__c)
Check the Profile (or Permission Sets if you use them) rights to:
Read the source object (Case_Type_Data__c) and all referenced fields (Level_1__c...)
Create the target object (ERT_Case_Type__c) and read/edit all referenced fields (Level1__c... but also Case__c)
Read on the Case object and Case.CaseNumber, Case.Subject fields
Permission to execute the Apex class (renamed to Stack, right?). And maybe add permission to run LookupSearchResult too.
I suspect you have enabled some critical updates (Setup -> Critical updates or Setup -> Release Updates) like "Restrict Access to #AuraEnabled Apex Methods for Authenticated Users Based on User Profile" or "Require Permission to View Record Names in Lookup Fields"
I have a similar code as below.
createRecord : function (component) {
var createRecordEvent = $A.get("e.force:createRecord");
createRecordEvent.setParams({
"entityApiName": "Case",
"panelOnDestroyCallback": function(event) {
$A.get("e.force:navigateToSObject").setParams({
recordId: component.get("v.recordId"),
slideDevName: "detail"
}).fire();
}
});
createRecordEvent.fire();
}
It does not redirect to the record id i have provided and this code is not even calling the function inside "panelOnDestroyCallback".
I have also tried "navigationLocation": "LOOKUP" and I do know RELATED_LIST opens the same page i have called the createrecordevent.
I have also tried url redirect too inside that "panelOnDestroyCallback".
panelOnDestroyCallback is not even getting called in the code.
My intention is to send the page to account record detail page after it saved the case record which was opened from createrecordevent??
e.force:createRecord will automatically redirect you to the new record after creation. No need to define a custom callback for that.
<aura:component implements="flexipage:availableForAllPageTypes">
<lightning:button label="Create Case" variant="brand" onclick="{!c.createRecord}"/>
</aura:component>
({
createRecord : function (component, event, helper) {
var createRecordEvent = $A.get("e.force:createRecord");
createRecordEvent.setParams({
"entityApiName": "Case"
});
createRecordEvent.fire();
}
})
I'm creating a form using Vue JS (more specifically the Vuetify library) and when clicking the 'Add' button I am trying to make it so that the user input is added to the database.
The database has 3 columns: id, type_id, value. I want to link the user input to the value column.
Note that allDesserts is an array that stores all of the items in the database. This is what I want to add to.
How can I achieve this?
Component in my form:
<v-combobox
:items="allDesserts.map(a => a.value)"
label="Project Type"
:search-input.sync="search"
>
<template v-slot:no-data>
<v-text-field
label="Add new dessert"
v-model="search"
>
</v-text-field>
<v-btn
#click="enterKey"
>Add</v-btn>
</template>
</v-combobox>
Axios request/method:
enterKey () {
axios.post('/api/desserts', {
value: 'key'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
}
My controller:
public function storeDessert(Request $request)
{
$dropdownType = new DropdownType();
$dropdownType->attribute_id = $request->input(rand(1, 10000));
$dropdownType->value = $request->input('value');
$dropdownType->save();
}
I am getting the following error:
"Illegal string offset 'id'"
I think your error is on this line.
$dropdownType->attribute_id = $request->input(rand(1, 10000));
Let say rand(1, 10000) will give you a value of 100, now you used this 100, as a key to access value in your requests which is not available.
Try to look your payload. You are just passing a data which has a key value only, this one.
{value: 'key'}
and now this line will work cause it is available in your payload.
$dropdownType->value = $request->input('value');
But not this one.
$dropdownType->attribute_id = $request->input(rand(1, 10000));
I am using some Graph view to view some statistic in my project.
e.g. Morish Grapgh, Pie chart graph.
I have an option like date range, so that I can specify the range of date and can fetch the data within that range and show the output graph in the front end.
The issue I am facing is at the First time I am able to see the out put while I am changing the Date range.
from the second time I am able to get the Data from the backend but after setting the new set of values to the graph Data, but the graph view is not changing because the graph is not able to refresh.
Here sample code. Please ask if any additional info needed.
<sa-morris-graph *ngIf="graphData!=null" [data]="graphData"
type="area"
[options]="{
xkey: 'x',
ykeys: ['y', 'z'],
labels: ['USER', 'New USER']
}"></sa-morris-graph>
from the Component type script file I am setting graphData
export class GAUserComponent implements OnInit{
fromDate : any ;
toDate : any ;
graphData : any = null;
dateSelected(){
this.gaService.getGaData(this.req,"/users")
.subscribe(
data => {
this.dataResponse = data;
let grData = [];
for (let data of this.dataResponse.usersByDate) {
var sample={"x": data.valueX ,"y": data.valueY , "z" : data.valueZ };
grData.push(sample);
}
this.graphData = grData;
},
err => {
console.log("Error occered : "+ err);
}
);
}
Please suggest me to solve the problem.
I guess In angular 1 there is a watch() to achieve this but in angular 2 this function is not there.
correct me If I am wrong and help me solve this
Thanks
I'm trying to pass data to a different route. I use form action and Url.Action but that didn't work. It doesn't even route to another view. It works when I use the anchor tag href with Url.Action, but how do I pass data from one Controller method to the same Controller but a different method.
I have a DNN MVC module example on Github for your reference. https://github.com/DotNetNuclear/DnnRestaurantMenu/blob/master/RestaurantMenu.MVC. You can easily install it by finding the install package under the Releases link.
If you look at the default/index view, there is a link to open the Edit view. If passed an item ID, it will load the data into the edit form, otherwise, with no item ID, it considers it a new (add) item.
So in my View.cshtml, I use DNN's Url.Action helper which forms the button's href. (https://github.com/DotNetNuclear/DnnRestaurantMenu/blob/master/RestaurantMenu.MVC/Views/Menu/Index.cshtml)
<a class="btn btn-default" href="#Url.Action("Edit", "Menu", new {ctl = "Edit", itemId = item.MenuItemId})">#Dnn.LocalizeString("EditItem")</a>
The first parameter is the module control key/action. The second is the controller name. In the 3rd parameter of Url.Action we pass the control type and then any number of additional querystring parameters. In this case, the item Id that is in the view's model.
In my MenuController's Edit() action, I can then take that item ID parameter to lookup the item model from the database and then return the Edit view.
public ActionResult Edit(int itemId = -1)
{
...
if (itemId > 0)
{
item = _menuController.GetItem(itemId, CurrentModuleId);
}
...
}
The only way I have every been able to do this with no headache is to create a routerconfig.cs:
using DotNetNuke.Web.Mvc.Routing;
using RouteParameter = System.Web.Http.RouteParameter;
namespace CodeWompler.CW.GridTest
{
public class RouteConfig : IMvcRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapRoute(
moduleFolderName:"CW.GridTest",
routeName: "CW.GridTest",
url: "{controller}/{action}/{id}/{userid}/{itemid}",
defaults: new {
id=RouteParameter.Optional,
userid=RouteParameter.Optional,
itemid=RouteParameter.Optional
},
namespaces: new[] {"CodeWompler.CW.GridTest.Controllers"});
}
}
}
Then, in my index.cshtml, for instance, I can do this:
$.ajax({
url: `/DesktopModules/MVC/CW.GridTest/IMMUser/EditUserById/userid/${myUserId}`,
method: "Post",
headers: {
"ModuleId": moduleId,
"TabId": tabId,
"RequestVerificationToken": rvtoken,
"userId": id //if we were to specify Edit as our url, then we would need this since Edit() takes no parameters and instead, looks in the header for it's data.
}
or
/DesktopModules/MVC/CW.GridTest/IMMUser/EditUserById/${myUserId}
or
/DesktopModules/MVC/CW.GridTest/IMMUser/AssignItemToUser/userid/${myUserId}/itemid/${myItemId}