I'm working on visualforce and apex and I got a situation where I want to combine 3 different tables in which handyman's name is common. Also, the specialities custom field on handyman custom object is a multipicklist so I couldn't query this directly from any of openorders or closeorders aggregated query because we cannot group by specialities i.e. a multipicklist. I would be very glad if someone help me out with this.
Note: orders custom object has lookup field on handyman.
Visualforce Page Code
<apex:page standardController="Orders__c" extensions=“HandymanInfo">
<apex:form>
<apex:pageBlock>
<apex:pageBlockSection columns="6" title=“ Handyman Tables">
<apex:pageBlockTable value=“{!lsthandyman}” var=“h”>
<apex:column value=“{!h.Name}">
<apex:facet name="header”>Handyman Name</apex:facet>
</apex:column>
<apex:column value=“{!h.Specialities__c}" >
<apex:facet name="header">Specialities</apex:facet>
</apex:column>
</apex:pageBlockTable>
<apex:pageblocktable value=“{!openorders}" var="oo">
<apex:column value="{!oo[’n']}"><apex:facet name="header”>Handyman Name</apex:facet></apex:column>
<apex:column value="{!oo[’sumopen']}"><apex:facet name="header”>Total Orders Opened</apex:facet></apex:column>
</apex:pageblocktable>
<apex:pageBlockTable value=“{!closeorders}" var="co">
<apex:column value="{!co[’n']}"><apex:facet name="header”>Handyman Name</apex:facet></apex:column>
<apex:column value="{!co[’sumclosed']}"><apex:facet name="header">Total Orders Closed</apex:facet></apex:column>
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller Class Code:
public class HandymanInfo {
public List<Handyman__c> lsthandyman {get;set;}
Public List<AggregateResult> openorders {get; set;}
Public List<AggregateResult> close orders {get; set;}
public HandymanInfo(ApexPages.StandardController controller) {
lsthandyman = [SELECT Name,Specialities__c FROM Handyman__c ORDER BY Name ASC];
openorders = [SELECT Handyman__r.Name n, COUNT(Name) sumopen FROM Orders__c
WHERE ((Status__c='New') OR (Status__c ='Assigned’) OR (Status__c='Accepted') OR
(Status__c ='In Progress'))
GROUP BY Handyman__r.Name
ORDER BY Handyman__r.Name ASC];
closeorders = [SELECT Handyman__r.Name n, COUNT(Name) sumclosed FROM Orders__c
WHERE ((Status__c='Completed') OR (Status__c='In Review’) OR (Status__c ='Paid'))
GROUP BY Handyman__r.Name
ORDER BY Handyman__r.Name ASC];
}
}
Are orders -> handyman connected in lookup relationship or master detail? can order be without handyman? if the handyman would ever be deleted - would you expect to cascade delete the orders or would you want to keep the "orphans"?
If you have it as master-detail then you could make 2 rollup fields from order to handyman. And then your controller becomes very simple, SELECT Name, Specialities__c, OrdersCountOpen__c, OrdersCountClosed__c FROM Handyman__c ORDER BY Name, job done.
If it has to stay as lookup... You could make 2 Map<Id, Integer> where key would be the handyman's id and value would be the count. Or even cheat a bit with a subquery to get open orders and then just run another query for closed.
// make this your class variable
public Map<Id, Integer> closedOrders {get; private set;}
// and then
lsthandyman = [SELECT Name, Specialities__c,
(SELECT Id FROM Orders__r WHERE Status__c IN ('New', 'Assigned', 'Accepted', 'In Progress'))
FROM Handyman__c
ORDER BY Name ASC];
closedOrders = new Map<Id, Integer>();
// there's no guarantee all handymen have any closed orders and we don't want to display error if map key isn't found. So let's make sure we have something in there even if it's all zeroes
for(Handyman__c h : lsthandyman){
closedOrders.put(h.Id, 0);
}
// and now let's get some actual closed order numbers
for(AggregateResult ar : [SELECT Handyman__c h, COUNT(Id) cnt
FROM Orders__c
WHERE Status__c IN ('Completed','In Review’,'Paid')
GROUP BY Handyman__c]){
closedOrders.put((Id) ar.get('h'), Integer.valueOf(ar.get('cnt')));
}
And then your Visualforce will be something like
<apex:pageBlockTable value=“{!lsthandyman}” var=“h”>
<apex:column header="Handyman Name" value=“{!h.Name}"/>
<apex:column header="Specialities" value=“{!h.Specialities__c}"/>
<apex:column header="# Open" value="{!h.Orders__r.size}" />
<apex:column header="# Closed" value="{!closedOrders[h.Id]}" />
</apex:pageBlockTable>
Related
I have a senario where i will be dispalying input text fieldon vf page ,when i enter some value and click on search button the realted accounts should be displayed depending on that keyword.
I have tried the following code ,but i am unable to resolve the error Unknown property 'VisualforceArrayList.Name'
The below is my code:
class:
public class AccountswithKeywordfrompage {
public string keyword{get;set;}
public List<List<Account>> accountlist{get;set;}
public void Accounts(){
keyword = System.currentPageReference().getParameters().get('search');
accountlist=[FIND '+keyword' IN ALL FIELDS
RETURNING Account(Name)];
}
}
vf page:
<apex:page controller="AccountswithKeywordfrompage" standardStylesheets="false">
<apex:form>
<apex:inputText label="SearchAccounts" id="search">
<apex:commandButton value="search" action="{!Accounts}"/>
</apex:inputText>
<apex:pageblock>
<apex:pageblockTable value="{!accountlist}" var="accountobj">
<apex:outputlink value="{!accountobj.Name}"/>
</apex:pageblockTable>
</apex:pageblock>
</apex:form>
</apex:page>
Can anyone help me to solve the issue ?
accountlist is a List<List<Account>>, which is the wrong type; a SOSL search returns a List<List<sObject>>. It just so happens that your SOSL search only returns Account results.
When you iterate over a List<List<sObject>>:
<apex:pageblockTable value="{!accountlist}" var="accountobj">
the type of the iteration variable is List<Account>, which has no Name property.
The cleanest solution is to declare your variable as a List<Account> and extract the first element of the returned List<List<sObject>> from SOSL.
I am new to coding and am using Salesforce.
I need help understanding how to create a test class for a controller extension.
I am clutching at straws when building the Test Class and now have 66% code coverage. Your help to adjust the below code will be much appreciated and help greatly in my understanding.
The Visualforce page is very simple:
<apex:page standardController="Case"
extensions="Case_ListOppSplits_Controller" lightningStylesheets="true">
<apex:pageBlock >
<apex:pageBlockTable value="{!Opportunity_Splits}" var="oppSplit">
<apex:column value="{!oppSplit.Name}"/>
<apex:column value="{!oppSplit.Split_Loan_Amount__c}"/>
<apex:column value="{!oppSplit.Loan_Usage__c}"/>
<apex:column value="{!oppSplit.Loan_Purpose__c}"/>
<apex:column value="{!oppSplit.Rate_Type__c}"/>
<apex:column value="{!oppSplit.Repayment_Type__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:page>`
The controller extension is:
public class Case_ListOppSplits_Controller {
public Case myCase;
public Case_ListOppSplits_Controller(ApexPages.StandardController stdController){
this.myCase = (Case)stdController.getRecord();
}
public list<Opportunity_Split__c> getOpportunity_Splits(){
Case currentCase = [SELECT Id, Subject, Opportunity__c FROM Case WHERE Id =: ApexPages.currentPage().getParameters().get('id')];
List<Opportunity_Split__c> OppSplits = [SELECT Id, Name, Opportunity__c, Loan_Purpose__c, Loan_Type__c, Loan_Usage__c, Rate_Type__c, Repayment_Type__c, Split_Loan_Amount__c FROM Opportunity_Split__c WHERE Opportunity__c =: currentCase.Opportunity__c];
return OppSplits;
}
}
Test Class:
#isTest
public class Case_ListOppSplits_Controller_Test {
static testMethod void testMethod1()
{
Case testCase = new Case();
testCase.Subject='Test Case';
testCase.Opportunity__c='0067F00000N8vSVQAZ';
testCase.RecordTypeId='0126D000000qSBcQAM'; //UA
testCase.Status='Assigned';
insert testCase;
Test.StartTest();
PageReference pageRef = new PageReference('https://omniwealth--dwr.my.salesforce.com/apex/Case_OpportunitySplits?id='+testCase.Id);
ApexPages.StandardController sc = new ApexPages.StandardController(testCase);
Case_ListOppSplits_Controller extn = new Case_ListOppSplits_Controller(sc);
List<Opportunity_Split__c> listOppSplits = extn.getOpportunity_Splits();
Test.StopTest();
}
}
It looks like you are trying to utilize existing data (which you shouldn't do) without adding #seeAlldata=true. What you should do is create the opportunities and splits in your test code before you call your controller methods.
On a side note, you have the myCase record in your controller, so your query in getOpportunitySplits can utilize it instead of the page parameter. (Where Id =: myCase.Id).
Once you create the opportunity and splits or set seealldata, you should increase the coverage. If you decided to use seeAllData, know that your test will fail when attempting to deploy to production since the opportunity id values probably won't match.
The objective is to have numberOfSections variable in the controller and then dynamically generate these sections on the vf page with the same format. How can this be achieved?
You can use apex:dynamicComponent to accomplish this:
Creating and Displaying Dynamic Components
What have you tried so far, what doesn't work? Your question is very poor and unlikely to attract more answers.
Easiest is to have a list of items (not just a counter, a list) and iterate it with <apex:repeat>.
public class Stack61357421 {
public List<String> sectionTitles {get; private set;}
public Stack61357421(){
sectionTitles = new List<String>{'lorem', 'ipsum', 'dolor', 'sit', 'amet'};
}
}
<apex:page controller="Stack61357421" tabStyle="Account">
<apex:pageBlock title="Hi stack">
<apex:repeat value="{!sectionTitles}" var="title">
<apex:pageBlockSection title="{!title}">
content goes here
</apex:pageBlockSection>
</apex:repeat>
</apex:pageBlock>
</apex:page>
I have two custom objects, X and Y.
The object Y is related to X by lookup YretatedX__c.
I am trying to show all Y related to X y standart page of X whith a visualforce.
Visualforce:
<apex:page standardController="X__c" extensions="related_list">
<apex:detail relatedList="true">
<apex:relatedList list="Y__c" subject="{!AllRelated}"/>
</apex:detail>
</apex:page>
Apex Class:
public class related_list {
private X__c x;
private Id idX;
public List<Y__c> AllRelated = new Y__c[]{};
public related_list(ApexPages.StandardController controller) {
this.x=(X__c)controller.getRecord();
idX = this.x.Id;
}
public List<Y__c> getAllRelated() {
AllRelated = [SELECT id FROM Y__c WHERE YretatedX__c =: this.idX];
return AllRelated;
}
}
In X page, the visualforce only shows:
Invalid parameter value "[a120E0000001234567, a120E0000007654321]" for parameter "id"
This Ids are valid for Y objects retated to this X object
I tried a lot, but I can find a solution.
I think you're not understanding the attributes of the apex:relatedList component in Visualforce.
Refer to this:
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_relatedList.htm
Note that you don't actually need to query for the records to display them with the component.
All you need is this:
<apex:relatedList list="Contacts"/>
You need to specify the Relationship Name for the list attribute
You don't need to specify the subject (the subject is the record who is the Parent of the list you are trying to show) as this would automatically be populated by the Standard Controller
Hope that helps.
I found a solution using <apex:pageBlockTable instead of <apex:relatedList
<apex:page standardController="X__c" extensions="related_list">
<apex:pageblock id="CustomList" title="Y" >
<apex:pageBlockTable value="{!AllRelated}" var="y" rendered="true">
<apex:column value="{!y.id}"/>
</apex:pageBlockTable>
</apex:pageblock>
</apex:page>
I am new to salesforce developement. I am unable to create a table of a custom object records in a community-user accessed visual force page. I can access individual record by using wrapper class. However I cannot display a table and if I use list of wrapper objects in the apex:repeat value, I get this error (as they are not SObjects):
" can only be used with SObjects, or objects that are Visualforce field component resolvable."
I also need to support inline-editing once this is resolved. Are custom object access limited for customer-community users? Issue is there only if O access thru community portal. Any way of achieving inline-editing table of custom objects?
VF page
<apex:page controller="FHController" >
<apex:form >
<apex:repeat value="{!fhList}" var="rec">
Series: <apex:outputField value="{!rec.Series__c}" />
</apex:repeat>
</apex:form>
</apex:page>
Controller
public class FHController {
public List<Funding_History__c> fhList {get; set;}
public FHController() {
String id = ApexPages.currentPage().getParameters().get('id');
fhList = [SELECT id, Series__c, Date__c, Amount__c, Valuation__c, Investors__c FROM Funding_History__c WHERE Account__c = :id];
}
public PageReference save() {
System.debug('COUNT: ' + fhList.size());
update fhList;
return null;
}
}
Thanks!
You don't need any wrapper-classes for displaying SObject on VF-page. You need just select set of Funding_History__c objects and don't wrap it. Then you be able to get these objects on VF-page in {!fhList} variable.
For inline editing you can use apex:inlineEditSupport. Here is quote from SF documentation:
This component provides inline editing support to
and various container components. In order to support inline editing,
this component must also be within an tag.
The component can only be a descendant of the following tags: "apex:dataList", "apex:dataTable", "apex:form", "apex:outputField", "apex:pageBlock", "apex:pageBlockSection", "apex:pageBlockTable", "apex:repeat".
See also: the inlineEdit attribute of "apex:detail"
And here is short example how it looks for Contact object (your case is pretty similar, you just need to change page controller and SObject which you process):
<apex:page standardController="Contact">
<apex:form >
<apex:pageBlock mode="inlineEdit">
<apex:pageBlockButtons >
<apex:commandButton action="{!edit}" id="editButton" value="Edit"/>
<apex:commandButton action="{!save}" id="saveButton" value="Save"/>
<apex:commandButton onclick="resetInlineEdit()" id="cancelButton" value="Cancel"/>
</apex:pageBlockButtons>
<apex:pageBlockSection >
<apex:outputField value="{!contact.lastname}">
<apex:inlineEditSupport showOnEdit="saveButton, cancelButton"
hideOnEdit="editButton" event="ondblclick"
changedStyleClass="myBoldClass" resetFunction="resetInlineEdit"/>
</apex:outputField>
<apex:outputField value="{!contact.accountId}"/>
<apex:outputField value="{!contact.phone}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
So, you can to investigate further in this way.
Why not use <apex:pageBlockTable> ? This will resolve your first issue as well ( not able to display a table ).