Visualforce Page List output - salesforce

How do you print out a custom Apex class list, that is not related to an Sobject? I keep getting error of
Error: Unknown property 'apiMyIntegrationCom.customerScorecardDiscountDetail.discountCategory'
Most code cut out for simplicity. I know the data is there, cause if i just use {!DiscountDetails} in visualforcepage, the data comes out for the whole class,var names and everything. Just looking to get particular vars.
public class MyController{
private apiMyIntegrationCom.customerScorecardResponse custScoreCard;
......
public apiMyIntegrationCom.customerScorecardDiscountDetail[] getDiscountDetails(){
return this.custScoreCard.discountDetails;
}
}
VisualForce Page:
<apex:page standardController="Account" extensions="MyController">
<table id="discountTable">
<apex:repeat id="dd" value="{!DiscountDetails}" var="dds">
<tr>
<td>{!dds.discountCategory}</td>
</tr>
</apex:repeat>
</table>

I think you need to add getDiscountCategory() to your apiMyIntegrationCom.customerScorecardDiscountDetail class (and any other fields you wish to expose on VF)
VF needs either explicit getProperty(), setProperty() methods or this notation: public String property {get; private set;}. Some more info can be found in my other answer: https://salesforce.stackexchange.com/a/9171/799
It looks like your class is autogenerated from WSDL file? Yep, that means you need to modify this code by sprinkling getters everywhere and you'll have to repeat this process every time you regenerate the class...

Related

Unknown Property Error using Custom Controller in Visualforce

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}.

Using Apex Repeat to Populate a Visualforce Table

It appears that my List is blank, not being passed through with the controller extension or otherwise some problem is causing my table not to populate the anticipated data. This visualforce page is being loaded from a custom button on a Work Order.
I've tried populating the data by using:
:ApexPages.CurrentPage().getParameters().get('id')
As well as just hardcoding what I believe is the 'id' as shown in the code example.
The VF Page is as follows:
<apex:page Standardcontroller="WorkOrder" extensions="cWOInvoice1" renderAs="pdf">
<apex:form >
...
<table style="...">
<tbody style="...">
<tr style="display:table-row;">
<th style="...">Scope of Work</th>
<th style="...">Trade</th>
<th style="...">Price</th>
</tr>
<apex:repeat value="{!woli}" var="woli">
<tr>
<td style = "...">{!woli.Repair_Product__r.Name}</td>
<td style = "...">{!woli.Repair_Product__r.Trade__c}</td>
<td style = "...">${!woli.Item_Price_Roll_Up_Sub__c}</td>
</tr>
</apex:repeat>
</tbody>
</table>
...
</body>
</apex:form>
</apex:page>
The controller looks like this (Again hardcoded workOrderID for bugtesting):
public class cWOInvoice1 {
public WorkOrderLineItem woli {get;set;}
public cWOInvoice1(ApexPages.StandardController controller){
List<WorkOrderLineItem>woli=[SELECT Id, Area__c, Tenant_Responsible__c, WorkOrderId, Repair_Product__r.Name, Repair_Product__r.Bill_Rate_Retail__c, Repair_Product__r.Bill_Rate__c, Repair_Product__r.Trade__c FROM WorkOrderLineItem WHERE WorkOrderId='0WO55000000Cw4LGAS'];
}
}
I expected the custom controller to pass through a list of work order line items that apex repeat would then display in the table. Instead, I get an empty table.
You have the variable woli declared with two different types in different scopes.
At the controller level, woli is a single WorkOrderLineItem member variable:
public WorkOrderLineItem woli {get;set;}
Because it's never initialized, its value is null.
Inside your constructor, you re-declare woli as a List<WorkOrderLineItem> and initialize it:
public cWOInvoice1(ApexPages.StandardController controller){
List<WorkOrderLineItem>woli=[SELECT Id, Area__c, Tenant_Responsible__c, WorkOrderId, Repair_Product__r.Name, Repair_Product__r.Bill_Rate_Retail__c, Repair_Product__r.Bill_Rate__c, Repair_Product__r.Trade__c FROM WorkOrderLineItem WHERE WorkOrderId='0WO55000000Cw4LGAS'];
}
This value goes out of scope at the end of the constructor and is never made available to your page.
You need to remove the local declaration and correct the type of the member variable.
Whether or not your <apex:repeat> currently compiles (I'm not sure if that's legal or not off the top of my head), you should change your iteration variable to have a different name than the bound property:
<apex:repeat value="{!woli}" var="woli">
You may wish to make the controller property something like woliList to clarify.

APEX Class To List Multiple Queries To Be Used In VisualForce Page

*New to SF development *
I'm working toward this end goal; Create a custom button on the Opportunity. When that button is pushed, a VisualForce page will display records from 2 custom objects that have a relationship to that Opportunity(ID). Both custom objects relate to the Opportunity via a custom lookup field.
As a rookie, I'm not sure if I'm starting in the right spot. Here is how I'm trying to in my head. The code below is for items #1 & #2 below.
Create a class methods that query the separate data. Each method would be a separate query/list
Include coding to pull in a variable of the current Opportunity ID
Create VisualForce page that displays queried data
Create button that triggers the APEX Code
public with sharing class TestDisplayQueryList{
public Opportunity currRec {get; set;}
public static List<Opportunity> oppRecords {get; set;}
public static List<Billing__c> billRecords {get; set;}
public static List<Service__c> servRecords {get; set;}
public TestDisplayQueryList(){
currRec = [SELECT ID FROM Opportunity WHERE :ApexPages.currentPage().getParameters().get('id')];
oppRecords = [SELECT Name, StageName ID FROM Opportunity WHERE ID= :currRec];
billRecords = [SELECT Name, Invoice ID FROM Billing WHERE Opportunity_Name_c= :currRec];
servRecords = [SELECT Name, Department ID FROM Service WHERE Opportunity_Name_c= :currRec];
}
}
3.) there are a bunch of ways to do this, The simplest is just a pageblock table
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_quick_start_iteration_components.htm
put your value as your list from your controller, you will need a seperate pageblock table for each list.
4.)
Create a custom button or link, you can do this using salesforce custom button, Just make it a url and pass it the ?id at the end of the url. This will automatically cause the code to run because the code can be ran upon page initialization. you will place this button on the opportunity page.
If you want to show the infromation in a popup window( which will be look and act better for the system) you can also do a custom button, just do a javascript button. there are a ton of tutorials online for making a button for a popup window in javascript. the javascript can extend to the controller and pass the opportunity id as well.
If you get stuck, please let me know and best of luck!
To be honest you could do this much easier than you think.
VisualForce has an abundance of standard components that can be used for tasks like this.
Below is an example VisualForce page for you:
<apex:page standardController="Opportunity" extensions="OpportunityExt">
<!-- Either include all related lists by setting the relatedList attribute to true -->
<apex:detail subject="{!opportunity.Id}" relatedList="false"/>
<!-- Or by Including the related lists seperately -->
<apex:relatedList list="OpportunityLineItems" />
<apex:relatedList list="OpportunityCompetitors" />
<!-- To use a button to display a panel, create the panel to reRender after our button action is complete -->
<apex:outputPanel id="thePanel">
<!-- Then create the buttons -->
<apex:commandButton action="{!showThePanel}" value="Show Panel" reRender="thePanel" rendered="{!NOT(showPanel)}"/>
<apex:commandButton action="{!hideThePanel}" value="Hide Panel" reRender="thePanel" rendered="{!showPanel}"/>
<!-- And inside that panel create a block that will only render when the flag is set -->
<!-- Note the use of outputPanel and outputText differently -->
<!-- OutputText leaves no container behind, outputPanel does so we need it for the "identifying panel" -->
<apex:outputText rendered="{!showPanel}">
<!-- You can then include the related lists you wanted -->
<apex:relatedList list="OpenActivities" />
</apex:outputText>
</apex:ouputPanel>
</apex:page>
And this would be the extension for that page:
public with sharing class OpportunityExt {
private Opportunity theOpportunity;
public Boolean showPanel {get; private set;}
public OpportunityExt(ApexPages.StandardController controller) {
// Get the Opportunity from the standard controller
theOpportunity = (Opportunity) controller.getRecord();
// By default don't display the panel - or do, it's your task
showPanel = false;
}
public void showThePanel() {
showPanel = true;
}
public void hideThePanel() {
showPanel = false;
}
}
For your reference here are the documentation links:
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_page.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_detail.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_relatedList.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_commandButton.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_outputPanel.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_outputText.htm
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_controller_extension.htm

implementing save and new button not working

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"

How do I properly override salesforce standard object controller save method to intercept it in a visual force page?

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.

Resources