I'm currently trying to customize an object on Salesforce and need to create a action button that will lead to a new account edit page.
I would like to prefill the new account page by passing inputs through the URLFOR function (see below); in my example, the parameter value is not interpreted.
<apex:page>
<apex:outputLink value="{! URLFOR( $Action.Account.New, null, [acc2='{! Object__c.Name}'] ) }">New Account</apex:outputLink>
</apex:page>
Does anyone have an idea on how to pass variables inputs through URLFOR in apex ?
Thanks for your help.
Crak
Yes, you are using the URLFOR function correctly.
Using
<apex:outputLink value="{! URLFOR( $Action.Account.New, null, [acc2='Acme'] ) }">New Account</apex:outputLink>
I was able to have a account screen load with Acme as the account name.
I believe the problem is that your call to get the name is returning null or blank so it appears that it is not applying anything to the Name field.
In your controller you should have a property that gives you access to the working record. Get the name like the following example.
Controller
Object__c MyCustomObject {get;set;}
Page
<apex:outputLink value="{! URLFOR( $Action.Account.New, null, [acc2=MyCustomObject.Name] ) }">New Account</apex:outputLink>
If that doesnt work as is, try changing to [acc2='MyCustomObject.Name'] etc
To get more generic solution you can use:
$Action.Account[]
when actionName is string variable(from apexclass or custom setting) can be:
View: Shows the detail page of an object
Edit: Shows the object in Edit mode
Delete: URL for deleting an object
New: URL to create a new record of an object
Tab: URL to the home page of an object
We can do it even more generic by change the object name to a variable too
$Action[objectName][actionName]
for example:
VFP:
<apex:page standardController="Account" extensions="urlForParamCTRL"
action="{!urlFor($Action[objectName][actionName],account.Id, null, true)}">
</apex:page>
Apex class:
public class urlForParamCTRL {
Public String objectName {get;set;}
Public String actionName {get;set;}
public urlForParamCTRL(ApexPages.StandardController controller)
{
this.objectName = 'Account';
this.actionName = 'New';
}
}
reference: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_dynamic_vf_globals_action.htm
Related
I have an error with a new Visualforce page I'm creating that takes list from a custom controller I made. It is for a standard objects and the class file compiled just fine. But when I start building the Visualforce page it gives me an error that I can't figure out.
This is the Visual Force Page
<apex:page controller="SearchAccountListController">
<apex:repeat value="{! acctList}" var="acct">
<apex:outputLink value="/{!acct.Name}">
<apex:outputText value="{!acct.Phone}"/><br/>
</apex:outputLink>
</apex:repeat>
</apex:page>
And the Controller:
public class SearchAccountListController {
public List<Account> getNewAccounts() {
List<Account> acctList = [SELECT Name,Phone FROM Account];
return acctList;
}
}
The class compiles fine, I'm using the Developer Console, so that seems to be okay. But then when I go to save my Visualforce page it gives the following error:
Save error: Unknown property 'Unknown property 'SearchAccountListController.acctList'
You don't have a class-level property acctList, you only have a local variable with that name. That name is lost when you leave the function.
From visualforce's point of view you have a getter function and what it returns can be accessed with {!newAccounts}.
Need your inputs in a scenario I am currently stuck in. Here are the details. Appreciate your time and all your inputs.
currently I am able to see the values retrieved in controller but they are not being displayed on visualforce page.
Requirement: I need to email bulk of selected contacts. When there is no email to selected contacts, we are required to populate the name of contacts on UI who do not have the email. I am able to accomplish first part of requirement but stuck on displaying contact names on visual force page .
List button : BulkEmailTest which calls firstVF visual force page.
firstVF code:
<apex:page standardController="Contact" extensions="FirstController" recordSetVar="listRecs"
action="{!send}">
Emails are being sent!
<script> window.history.back();
</script>
</apex:page>
FirstController code: for simplified code, I have edited snippet for contacts with email as our priority is only related to contacts with no email.
public with sharing class FirstController
{
public List<Contact> noEmail {get;set;}
public Contact contact;
public List<Contact> allcontact {get; set;}
Id test;
public Contact getAllContact() {
return contact;
}
ApexPages.StandardSetController setCon;
ApexPages.StandardController setCon1;
public static Boolean err{get;set;}
public FirstController(ApexPages.StandardController controller)
{
setCon1 = controller;
}
public FirstController(ApexPages.StandardSetController controller)
{
setCon = controller;
}
public PageReference cancel()
{
return null;
}
public FirstController()
{
}
public PageReference send()
{
noEmail = new List<Contact>();
set<id> ids = new set<id>();
for(Integer i=0;i<setCon.getSelected().size();i++){
ids.add(setCon.getSelected()[i].id);
}
if(ids.size() == 0){
err = true;
return null;
}
List<Contact> allcontact = [select Email, Name, firstName , LastName from Contact where Id IN :ids];
for(Contact current : allcontact)
{
system.debug(current);
if (current.Email!= null)
{
PageReference pdf = Page.pdfTest;
pdf.getParameters().put('id',(String)current.id);
system.debug('id is :'+current.id);
pdf.setRedirect(true);
return pdf;
}
else //No email
{
system.debug('in else current'+current );
noEmail.add(current);
// noEmail.add(current);
system.debug('in else noemail'+noEmail );
}//e
}
if(noEmail.size()>0 ) {
PageReference pdf1 = Page.NoEmailVF;
pdf1.getParameters().put('Name', String.valueOf(noEmail));
system.debug('pring noEmail' +noEmail);
pdf1.setRedirect(false);
return pdf1;
}
return null;
}
}
NoEmailVF visual force page code
<apex:page controller="FirstController">
<b> Emails are not sent to below contacts :
<table border="1">
<tr>
<th>Name</th>
</tr>
<apex:repeat var="cx" value="{!allcontact}" rendered="true">
<tr>
<td>{!cx.name}</td>
</tr>
</apex:repeat>
</table>
<p> Please note that emails are not sent to selected Donors only when
they did not make any donation for that year or if they do not have email address listed. </p>
<p>If you still wish to retrieve donations made in this year, then you may use "Hard Copy" button listed on the Donor record to have the data printed. </p>
</b>
<apex:form >
<apex:commandButton action="{!cancel}" value="Back" immediate="true"/>.
</apex:form>
</apex:page>
It's bit messy. I think I know why it doesn't work but I'm also going to give you few tips how to clean it up.
I don't think you need 2 separate pages. You could do it on 1 page. I'm not even sure what were you trying to accomplish. Should the user be moved to previous page (some listview button I guess? Wherever history.back() takes them). Or to Page.NoEmailVF. (and there's even Page.pdfTest thrown into the mix ;))
If you're sure you need multiple pages - here's how you can transfer "state" of the controller across pages. It should work automatically as long as they share same controller (or extension), no need to pass anything via url: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_quick_start_wizard.htm
Your constructors don't do much. They save the references to standard(set)controller but they don't run any queries. Contacts aren't queried until the send() method.
You're hoping to pass the noEmail parameter with String.valueOf(List<Contact>). It's... uh.. it probably does something but after redirect you don't read anything. The NoEmailVF page has just <apex:page controller=... (not an extension) so the FirstController() (the one without any parameters) is called. And it has empty body! It completely ignores what was passed via url. It probably could read what you passed using ApexPages.currentPage().getParameters().get('Name') but then honestly no idea what you can do to create real list of contacts out of such string. Messy. You probably could do some JSON.serialize and then deserialize but I don't like the whole idea.
And last but not least - calling page action is evil, unexpected for the user and against salesforce security best practices. Pls check my old answer https://salesforce.stackexchange.com/a/28853/799
So...
What a random internet stranger thinks you need:
1 VF page. With only 1 constructor, the one that takes StandardSetController.
In the constructor inspect the ssc.getSelected() and query SELECT Id, Name FROM Contact WHERE Id IN :ssc.getSelected() AND Email = null. Save the results of the query into public contactsWithoutEmail {get; private set;}
Do NOT have the action={!send} unless you absolutely need it automated. it should be conscious user's decision to click some final "Do it!" button.
In the send() method query only these SELECT Id, Name FROM Contact WHERE Id IN :ssc.getSelected() AND Email != null and process them.
In visualforce - use <apex:pageBlockTable>, <apex:dataTable> or similar to display contactsWithoutEmail. No need to hand-craft the html.
And I recommend making send a normal apex:commandButton, not action
I am following this link to Create Save and New Functionality on page
How to implement "Save & New" functionality in a VisualForce Page
According to that i have did following
1.Create a apex class Opportunity and implement extension method
public with sharing class Opportunity
{
ApexPages.standardController m_sc = null;
public Opportunity(ApexPages.standardController sc)
{
m_sc = sc;
}
public Pagereference doSaveAndNew()
{
SObject so = m_sc.getRecord();
upsert so;
string s = '/' + ('' + so.get('Id')).subString(0, 3) + '/e?';
ApexPages.addMessage(new ApexPages.message(ApexPages.Severity.Info, s));
return new Pagereference(s);
}
}
this compiles fine
2.create a new page , extend the controller ,create button and call method
<apex:page sidebar="false" standardController="Opportunity" extensions="Opportunity" >
<apex:form >
<apex:pageMessages />
{!Opportunity.Name}
<apex:commandButton action="{!doSaveAndNew}" value="Save & New"/>
</apex:form>
</apex:page>
this gives me error "Unknown method 'OpportunityStandardController.doSaveAndNew()'"
I dont know what step I am missing in this process
Any suggestions
The APEX Class extension should not be the same with object name
APEX Class Name
OpportunityController
APEX Page
OpportunityPage
The code should be
<apex:page sidebar="false" standardController="Opportunity" extensions="OpportunityController" >
I think maybe the class name equal the object standard name will error
As Joseph pointed out, the page is trying to access the method in the standard controller 'OpportunityStandardController.doSaveAndNew()' and cannot find it since both the extension and the standard controller are called the same thing and it's just looking in the wrong class.
You probably just need to rename your controller extension to something else. I typically throw "Extension" on the end of the class name so I know what it is for. As an example, maybe something like "OpportunitySaveExtension". Then update your visualforce page to reference the renamed class in the "Extensions" attribute.
extensions="OpportunitySaveExtension"
Hi there I created a visual force page to with a standard lead controller as the controller and extend it. I want to do this so i can still utilize the apex:detail control and not reinvent the wheel in dealing with the standard lead info, related list etc.
I added an apex:commandbutton and make it call save. When I click on this button I can clearly see that my function is being called. However, all changes that is done to the lead info via inline editing is not captured.
For example, If I edited LastName using the inline editing and i click on the apex:commandbutton the new LastName value is not being saved. It's almost like the save function that is being called by apex:commandbutton is not aware of the data changes.
the following is code to my visual force page.
<apex:page standardController="Lead" extensions="LeadTestExtensionController">
<apex:form >
<apex:commandButton action="{!save}" value="Save" id="btnSave"/>
<apex:detail subject="{!Lead.Id}" relatedList="true" showchatter="true" inlineEdit="true" />
</apex:form>
</apex:page>
the following is code to my controller
public with sharing class LeadTestExtensionController {
private Apexpages.StandardController controller;
private PageReference page;
private string id;
private final Lead myLead;
public String positions {get; set;}
public LeadTestExtensionController(ApexPages.StandardController stdController) {
this.controller = stdController;
this.myLead = (Lead)stdController.getrecord();
this.page = ApexPages.currentPage();
this.id = page.getParameters().get('id');
List<Lead> myLeads = [select Opportunity_Stage__c from lead where id = :id];
if(myLeads.size() > 0)
{
positions = myLeads[0].Opportunity_Stage__c;
}
}
public PageReference save() {
this.controller.save();
PageReference newPage = New PageReference('/apex/RCS');
newPage.getParameters().put('id',ApexPages.currentPage().getParameters().get('id'));
newPage.setRedirect(true);
return newPage;
}
}
Once I click on the apex:command button, the page is being redirected to apex/RCS so i know its being called. However, if i return to the same lead, the last name doesn't change. I was under the impression that the following line would've called the standard controller's save function that should've taken care of the updating of the Last Name.
this.controller.save();
What am I doing wrong and how can I accomplish this. The above code is heavily simplified version of my actual code. What I am trying to do in my actual code is to check the value of certain field and if it meets certain criteria I want it to do something. However, I can't seems to see the new value entered.
Thank you.
Calling save() on the standard controller does not commit inline edits in a detail section. I've just reproduced the problem using only the standard controller, so the way you are overriding it is not the issue.
I think the reason for this is that apex:detail gets a record out of the database in its own right, rather than using a reference to the one in the standard controller.
Inline edit should provide you with its own save button, and I think your best bet is to try and incorporate that into your design.
I have a list of Assets
Name: column 2: etc
A1 C1 b1
A2 c2 b2
When I click on A1, I call action="{! assetClicked}" within to do some logic, but I cannot redirect it to another Visual Force Page
If I use I can link to another VF page, but cannot do action="{! assetClicked}"
Is there a way to combine them together or some other way around?
Page Code:
<apex:form >
<apex:commandLink action="{! assetClicked}" value="{!wn.name}" id="theCommandLink">
<apex:param value="{!wn.name}" name="id" assignTo="{!selectedAsset}" ></apex:param>
<apex:outputLink value="/{!wn.id}" id="eventlink">{!wn.name}</apex:outputLink>
</apex:commandLink>
</apex:form>
You would need to use the PageReference class.
Here's a modified example from the documentation:
// selected asset property
public string selectedAsset {get;set;}
public PageReference assetClicked()
{
// Your code here
PageReference redirect = new PageReference('/apex/PageName');
// pass the selected asset ID to the new page
redirect.getParameters().put('id',selectedAsset);
redirect.setRedirect(true);
return redirect;
}
Alternatively, you could use Page.PageName; instead of new PageReference('/apex/PageName'); as described here.
You didn't indicate how to retrieve the parameter in the desintation Visualforce page controller. I found this in a different forum:
// Assuming the parameter is 'id' after redirecting to page2 you can retrieve the paramter thus
public customcontrollerpage2() {
String ID = ApexPages.currentPage().getParameters().get('id');
}
In button method add something like this at the end of the method:
PageReference pr = new PageReference('/apex/YOUR_PAGE_NAME');
return pr;