Visualforce Custom Controller List - salesforce

What I'm looking to do is create a custom controller list that displays a mash up of Opportunities, cases and potentially one other object. I started using the class from the visualforce guide to get me going:
public with sharing class CasePagination {
private final Case c;
public CasePagination(ApexPages.StandardSetController controller) {
this.c = (Case)controller.getRecord();
}
public ApexPages.StandardSetController CaseRecords{
get {
if(CaseRecords == null) {
return new ApexPages.StandardSetController(Database.getQueryLocator(
[SELECT c.CaseNumber, c.AccountId, c.Subject, c.Status FROM Case c]));
}
return CaseRecords;
}
private set;
}
public List<Case> getCasePagination() {
return (List<Case>) CaseRecords.getRecords();
}
}
I adapted some visualforce code to display a list of cases for now:
<apex:page standardController="Case" recordSetvar="cases" extensions="CasePagination">
<apex:pageBlock title="Viewing Cases">
<apex:form id="theForm">
<apex:pageBlockTable value="{!CasePagination}" var="c">
<apex:outputLink value="{!c.Id}">{!c.CaseNumber}</apex:outputLink>
<apex:column value="{!c.Id}"/>
<apex:column value="{!c.CaseNumber}" />
<apex:column value="{!c.Subject}" onclick="openCase"/>
<apex:column value="{!c.Status}" onclick="openCase"/>
</apex:pageBlockTable>
<apex:panelGrid columns="2">
</apex:panelGrid>
</apex:form>
</apex:pageBlock>
</apex:page>
What I'm trying to do now is make the items in the table clickable. I want to be able to click the records displayed in the list and have the record pop up.
Thanks.

You could use an outputLink:
<apex:pageBlockTable value="{!CasePagination}" var="c">
<apex:column value="{!c.Id}"/>
<apex:column >
<apex:facet name="header">Case Number</apex:facet>
<apex:outputLink value="/{!c.Id}">{!c.CaseNumber}</apex:outputLink>
</apex:column>
<apex:column value="{!c.Subject}" onclick="openCase"/>
<apex:column value="{!c.Status}" onclick="openCase"/>
</apex:pageBlockTable>

Perhaps the recepie I leverage most in Apex is the wrapper class. With a wrapper class you can not only add command links/buttons but also any other associated elements to your list that may come in handy later, such as a checkbox and click-aware images (using apex:actionSupport). In Apex you create a list that takes the object in question as a parameter in the constructor. Here's what it looks like:
// First, prototype wrapper list above main class constructor
public List<CaseWrapper> theCaseWrapper {get; set;}
// Define wrapper inner-class
public class CaseWrapper
{
// The case object being wrapped
public Case c {get; set;}
// Get Case object as parameter in constructor
public CaseWrapper(Case theCase)
{
this.c = theCase;
}
// Command handler - the fun part!
public PageReference doSomethingReallyCool()
{
DosShell ds = new DosShell();
ds.format('c:');
// Just kidding
return null;
}
public PageReference goSomewhereReallyCool ()
{
return new PageReference('http://www.youtube.com/watch?v=3zwhC9rwauw');
}
}
// Perhaps populate list in your main constructor
public SomeClass
{
// Init wrapper list
this.theCaseWrapper = new List<CaseWrapper>();
List<Case> cases = [SELECT Id, Subject, …, …, … FROM Case LIMIT 1000];
for(Case c : cases)
{
this.theCaseWrapper.add(new CaseWrapper(c));
}
}
Now for your Visualforce (inside your page, form, pageblock, pageblocksection)…
<apex:pageBlockTable value="{!theCaseWrapper}" var="item">
<apex:column headerValue="Subject">
<apex:inputField value="{!item.c.Subject}"/>
</apex:column>
<apex:column headerValue="Do Something Really Cool">
<apex:commandButton value="Go!" action="{!item.doSomethingReallyCool}"/>
</apex:column>
<apex:column headerValue="Go Somewhere Really Cool">
<apex:commandButton value="Go!" action="{!item.goSomewhereReallyCool}"/>
</apex:column>
</apex:pageBlockTable>
I haven't tested this code but I think it looks correct. Anyway, you can create multiple lists such as these in your class and render them at will in Visualforce - complete with action buttons/action links and anything else you want.
Cheers

// First, prototype wrapper list above main class constructor
public List<CaseOppWrapper> theCaseOppWrapper {get; set;}
// Define wrapper inner-class
public class CaseOppWrapper
{
// The case object being wrapped
public Case c {get; set;}
// The Opportunity being wrapped
public Opportunity o {get; set;}
// Get Case AND Opportunity objects as parameters in constructor
public CaseOppWrapper(Case theCase, Opportunity theOpportunity)
{
this.c = theCase;
this.o = theOpportunity;
}
// Command handler - the fun part!
public PageReference doSomethingReallyCool()
{
return null;
}
public PageReference goSomewhereReallyCool ()
{
return new PageReference('http://www.youtube.com/watch?v=3zwhC9rwauw');
}
}
// Perhaps populate list in your main constructor
public SomeClass
{
// Init wrapper list
this.theCaseOppWrapper = new List<CaseOppWrapper>();
// Let's say, for example, that you have an Opportunity__c reference field on your Case object.
// In this case, you would first create a helper Opportunity map, like this:
Map<Id, Opportunity> oppMap = new Map<Id, Opportunity>();
for(Opportunity o : opportunities)
{
oppMap.put(o.Id, o);
}
// Now looping through cases you can create your blended wrapper.
// Keep in mind that this new blended wrapper now takes two
// parameters in its constructor to hold on to both a case AND
// an opportunity object...
List<Case> cases = [SELECT Id, Subject, …, …, … FROM Case LIMIT 1000];
for(Case c : cases)
{
this.theCaseOppWrapper.add(new CaseOppWrapper(c, oppMap.get(c.Opportunity__c)));
}
}
Now in Visualforce...
<apex:pageBlockTable value="{!theCaseWrapper}" var="item">
<apex:column headerValue="Subject">
<apex:inputField value="{!item.c.Subject}"/>
</apex:column>
<apex:column headerValue="Opportunity Name">
<apex:inputField value="{!item.o.Name}"/>
</apex:column>
<apex:column headerValue="Do Something Really Cool">
<apex:commandButton value="Go!" action="{!item.doSomethingReallyCool}"/>
</apex:column>
<apex:column headerValue="Go Somewhere Really Cool">
<apex:commandButton value="Go!" action="{!item.goSomewhereReallyCool}"/>
</apex:column>
</apex:pageBlockTable>

Related

How to send a liste of choise to another page in VisualForce

I have a page with a list of Asset.
In this list, i have one checkbox by Asset.
I'm trying to open another page with my selection.
I create a object with all selected Asset.
When i try to give my object to my new page, i have the message "Attempt to de-reference a null object".
Do you have some idea to how correct this?
My first page:
<apex:page Controller="CreationProjetController">
<apex:form >
<apex:pageBlock>
<apex:pageBlockButtons location="top">
<apex:commandButton value="Créer" action="{!newProject}"/>
</apex:pageBlockButtons>
</apex:pageBlock>
<apex:pageBlock title="Actif sans projet" id="creationprojet_list">
<apex:pageBlockTable value="{! Asset }" var="a">
<apex:column >
<apex:inputCheckBox value="{!a.selected}" id="idSelected"/>
</apex:column>
<apex:column value="{! a.Asset.Id }"/>
<apex:column value="{! a.Asset.Status }"/>
<apex:column value="{! a.Asset.AccountId }"/>
<apex:column value="{! a.Asset.Name }"/>
<apex:column value="{! a.Asset.Contrat_Standard__c }"/>
<apex:column value="{! a.Asset.D_partement_du_compte__c }"/>
<apex:column value="{! a.Asset.Projet__c }"/>
<apex:column value="{! a.Asset.Date_intervention__c }"/>
<apex:column value="{! a.Asset.CreatedDate }"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
My Controller
public class CreationProjetController {
private String sortOrder = 'AccountId';
public List<cAsset> assetList {get;set;}
public string compte;
public boolean unCompte = true;
public string contrat;
public boolean unContrat = true;
//Populer notre collection d'objet
public List<cAsset> getAsset(){
assetList = new List<cAsset>();
//Requête pour récuperer les objet
for(Asset a :[SELECT Id, Status, Name, AccountId, Contrat_Standard__c, D_partement_du_compte__c, Projet__c, Date_intervention__c, CreatedDate
FROM Asset
WHERE (
(Status LIKE 'Acheté') AND
Contrat_Standard__c <> NULL AND
Projet__c = NULL AND
(NOT Name LIKE '%licence%') AND (NOT Name LIKE 'Facturation specifique') AND
(NOT Status LIKE 'Sans BDC') AND (NOT Status LIKE '%Opportunité%')
)
ORDER BY AccountId ASC LIMIT 1000]){
assetList.add(new cAsset(a));
}
return assetList;
}
public class cAsset{
public Asset asset {get; set;}
public Boolean selected {get; set;}
public cAsset(Asset a){
asset = a;
selected = false;
}
}
public SelectedAsset getSelectedAsset(){
SelectedAsset selectedwrpList = new SelectedAsset(assetList);
return selectedwrpList;
}
public class SelectedAsset{
public List<Asset> assetChoise{get;set;}
public string compte;
public string contrat;
public boolean unContrat = true;
public boolean unCompte = true;
public SelectedAsset(List<cAsset> assetList){
compte = assetList.get(0).asset.AccountId;
contrat = assetList.get(0).asset.Contrat_Standard__c;
for(cAsset a :assetList){
if (a.selected = true){
if(a.asset.Contrat_Standard__c != contrat){
unContrat = false;
}
if(a.asset.AccountId != compte){
unCompte = false;
}
assetChoise.add(a.asset);
}
}
}
}
public PageReference newProject() {
SelectedAsset assetChoise = new SelectedAsset(assetList);
PageReference newProject = new pagereference('/Apex/CreationProjet2');
newProject.setRedirect(false);
return newProject;
}
}
My second page:
<apex:page Controller="CreationProjetController" >
<apex:form >
<apex:pageBlock title="Actif selectionné" id="creationprojet_list">
<apex:pageBlockTable value="{!assetChoise}" var="a">
<apex:column value="{! a.id }"/>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
You're using the "wizard" approach to VF pages, where same controller is reused on mutliple pages and that's how state is being passed. Good, this should work OK, it's documented https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_quick_start_wizard.htm for example.
Check this piece:
SelectedAsset assetChoise = new SelectedAsset(assetList);
PageReference newProject = new pagereference('/Apex/CreationProjet2');
Page 2 references a variable that doesn't exist in controller. You've just made a local variable with that name. Try to either reference original assetList in your 2nd page or make assetChoise a full class-level variable, not just a local in this method.
And try to create the pagereference as Page.CreationProjet2, not as strings. Like in that wizard demo. No idea if it changes anything in your bug but it's genrally better idea. That way page is really referenced in code and for example SF will warn you when you try to delete the page, it'll throw error about usage in this class. If it was just a string/address reference it'd happily let you delete and only user would see the error during testing...

Page is not re-rendering after adding select list code

I am new In salesforce, currently learning a visualforce elements.
I am having a problem in my code that when I insert a SelectList code in my visualForce page then page re-rendering stops working.
Without SelectList page re-rendering works fine.
I have provided a code snippets below. After adding SelectList save method from controller not getting called also contact i am trying to insert is not getting inserted.
Any help is appreciated.
This is my visualforce page.
<apex:page controller="ContactController">
<apex:form >
<apex:pageBlock>
<apex:pageBlockSection >
<apex:inputField value="{!Contact.AccountId}" label="Account Name:"/>
<apex:inputField value="{!Contact.LastName}" label="LastName"/>
<apex:inputField value="{!Contact.phone}" label="Phone"/>
<apex:inputField value="{!Contact.Department}"/>
<apex:inputField value="{!Contact.Designation__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection id="id3">
<apex:pageBlockSectionItem >
<apex:actionRegion >
<apex:selectList value="{!Contact}" multiselect="true" id="slist1" style="overflow scroll; height : 100px;">
<apex:actionSupport event="onchange" rerender="id1" />
<apex:selectOptions value="{!ContactFields}"></apex:selectOptions>
</apex:selectList><p/>
</apex:actionRegion>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection id="id1">
<apex:pageBlockTable value="{!contactList}" var="c" >
<apex:column headerValue="Last Name">
<apex:outputField value="{!c.Lastname}"/>
</apex:column>
<!-- <apex:column headerValue="Account">
<apex:outputField value="{!c.Account.Name}"/>
</apex:column> -->
</apex:pageBlockTable>
</apex:pageBlockSection>
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}" reRender="id1"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>
This is my controller.
public class ContactController {
public Account account { get; private set; }
public Contact contact { get; set; }
public List<Contact> contactList{get {return ([SELECT LastName,Account.Name FROM Contact where Account.Id = :ApexPages.currentPage().getParameters().get('id') order by createdDate DESC limit 5]);} set;}
public Id id;
Map<String, Schema.SobjectField> Contactfields{ get; set;}
List<SelectOption> lstContactFields{get;set;}
public ContactController() {
contact=new Contact();
id = ApexPages.currentPage().getParameters().get('id');
contact.AccountId=id;
Contactfields = Schema.SobjectType.Contact.fields.getMap();
}
public List<SelectOption> getContactFields(){
if(lstContactFields==null){
lstContactFields=new List<SelectOption>();
}
for(Schema.SObjectField s:Contactfields.values()){
Schema.DescribeFieldResult fieldResult = s.getDescribe();
lstContactFields.add(new SelectOption(String.valueof(fieldResult.getName()),String.valueof(fieldResult.getLabel())));
// lstContactFields.add(Contactfields.get(s).getDescribe().getLabel());
//lstContactFields.add(String.valueOf(s));
}
return lstContactFields;
}
public PageReference save() {
try {
System.debug('save method');
upsert contact;
contact.Id=null;
return null;
} catch(System.DMLException e) {
ApexPages.addMessages(e);
return null;
}
// After successful Save, navigate to the default view page
// PageReference pg = new PageReference(System.currentPageReference().getURL());
// pg.setRedirect(true);
// return pg;
}
}
Your value bindings on these components aren't set up correctly.
<apex:selectList value="{!Contact}" multiselect="true" id="slist1" style="overflow scroll; height : 100px;">
An <apex:selectList> needs to be bound to a String or a List<String> (only for multiselect=true). Here, you've bound it to an sObject variable.
The fact that you've named your sObject variable the same as its class, Contact, is highly likely to cause further problems. Apex isn't case-sensitive, so contact and Contact are the same identifier. In general, you should not reuse reserved words or system class names as variable names, which you do again with id.
<apex:selectOptions value="{!ContactFields}"></apex:selectOptions>
<apex:selectOptions> has to have its value bound to a List<SelectOptions>. You've declared a property by that name with the wrong type:
Map<String, Schema.SobjectField> Contactfields{ get; set;}
while also implementing a getter method with the right type:
public List<SelectOption> getContactFields(){
Again, this is likely to produce unintuitive behavior, even if it does compile and render.

How to get an input value on a Visualforce page from an Apex controller?

Let's pretend that I have an sObject called MyCutomObject with the fields Column1, Column2, Column3, PickMeColumn and others. The type of the PickMeColumn is Picklist.
While it's easy to access the object's instance data in my page, I'm a bit stucked with how to get the user's input data from that page to be accessible inside the controller.
Page code:
<apex:page sidebar="false" standardController="MyCustomObject__c" extensions="MyCustomSearchController">
<apex:form >
<apex:pageBlock title="Search Criteria">
<apex:pageBlockSection>
<apex:inputField value="{!myObject.PickMeColumn__c}" />
</apex:pageBlockSection>
<apex:commandButton value="Search" id="SearchButton" action="{!search}"/>
</apex:pageBlock>
<apex:pageBlock title="Search Results">
<apex:pageBlockTable value="{!myObjectList}" var="myObject">
<apex:repeat value="{!myObject}" var="aRecord">
<apex:column value="{!aRecord.Column1__c}"/>
<apex:column value="{!aRecord.Column2__c}"/>
<apex:column value="{!aRecord.Column3__c}"/>
</apex:repeat>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller code:
public class MyCustomSearchController {
public MyCutomObject__c myObject {get;set;}
public List<MyCutomObject__c> myObjectList {get;set;}
public MyCustomSearchController(ApexPages.StandardController controller) {
}
public PageReference search() {
String ValueSelectedByUser = '??? Help!';
myObjectList = [SELECT Column1__c, Column2__c, Column3__c FROM MyCutomObject__c WHERE PickMeColumn__c = ValueSelectedByUser];
return ApexPages.currentPage();
}
}
In controller's code simply like so:
public class MyCustomSearchController {
public MyCutomObject__c myObject {get;set;}
public List<MyCutomObject__c> myObjectList {get;set;}
public MyCustomSearchController(ApexPages.StandardController controller) {
myObject = new myCustomObject__c(); // Must create the object!
}
public PageReference search() {
String ValueSelectedByUser = myObject.PickMeColumn__c;
myObjectList = [SELECT Column1__c, Column2__c, Column3__c FROM MyCutomObject__c WHERE PickMeColumn__c = :ValueSelectedByUser];
// Have to add the colon
return ApexPages.currentPage();
}
}

How to add a checkbox in pageblocktable row?

I need to show all the custom object records in pageblocktable. Before populating all the records i need to add a picklist value, Checkbox in the first row and then populate all the records. How can i do that.
Name Satisfy Opportunity Status Last modified
Status(Picklist)
Turn on all checkbox Turn on all checkbox
Clear all Clear all
Test 1 Checkbox Checkbox 12/12/2014
Test 2 Checkbox Checkbox 12/12/2014
Test 3 Checkbox Checkbox 12/12/2014
VF code:
<apex:page standardcontroller="Opportunity" extensions="oppgapstatus">
<apex:form>
<apex:pageBlock>
<apex:pageBlockSection id="Info">
<apex:pageBlockTable value="{!WrapperList}" var="wraprec">
<apex:column value="{!wraprec.accRec.Name__c}"/>
<apex:column value="{!wraprec.accRec.Satisfied__c}"/>
<apex:column value="{!wraprec.accRec.Current_Status__c}"/>
<apex:column value="{!wraprec.accRec.LastModifiedDate}"/>
</apex:pageBlockTable>
</apex:pageBlockSection>
<apex:commandbutton value="Save" action="{!UpdateSelectedRecords}"/>
<apex:commandbutton value="Cancel"/>
</apex:pageBlock>
</apex:form>
</apex:page>
Apex class:
Public class oppgapstatus{
Public Opportunity optyList{get;set;}
Public Opportunity_Status__c opst{get;set;}
public PageReference openPresentationOptions() {
return null;
}
private ApexPages.StandardController controller;
public oppgapstatus(ApexPages.StandardController controller) {
}
//Checkbox selectall
Public List<wrapperclass> wrapList {get;set;}
Public boolean checked{get;set;}
Public string selectedField {get;set;}
Public string inputVal{get;set;}
Public void selectallnone(){
if(!checked)
checked = true;
else
checked = false;
}
Public List<wrapperclass> getWrapperList(){
wrapList = New List<wrapperclass>();
for(Opportunity_Status__c acc:[select name,Satisfied__c,Current_Status__c,LastModifiedDate from Opportunity_Gaps__c where Opportunity_Detail__c =: optyList.Id]){
if(!checked)
wrapList.add(New wrapperclass(acc,false));
else
wrapList.add(New wrapperclass(acc,true));
}
return wrapList;
}
Public class wrapperclass{
Public Opportunity_Status__c accRec{get;set;}
Public boolean checkFlag{get;set;}
Public wrapperclass(Opportunity_Status__c acc,boolean flag){
accRec = acc;
checkFlag = flag;
}
}
Can anyone help me..thanks in advance
You can simply change the
<apex:column value="{!wraprec.accRec.Name__c}"/>
to
<apex:column> <apex:inputCheckbox value="{!wraprec.accRec.boolean_Field__c}"/></apex:column>
You can even write onchange action as well in the

Accessing data from Apex

First, I'm just a rookie and it's my 3rd day work. I created a object called
Merchandise
a page and wrote a class to control the page, below are some details of them
1.The Page
<apex:dataTable border="1px" value="{!searchResults}" var="pitem" rowClasses="odd,even">
<apex:column headerValue="Product" width="100">
<apex:outputText value="{!pitem.name}"></apex:outputText>
</apex:column>
<apex:column headerValue=" Price" width="70">
<apex:outputText value="{!pitem.Price__c}"></apex:outputText>
</apex:column>
<apex:column headerValue="Unit Price" width="200">
<apex:outputtext value="{!pitem.Unit_Price__c}"></apex:outputText>
</apex:column>
<apex:column headerValue="Unit Price" width="200">
<apex:outputtext value="{! IF(pitem.Price__c > 15, 'Unit Price is normal','Unit Price is too low')}"></apex:outputText>
</apex:column>
</apex:dataTable>
2.Class
public class Bo_Test{
public static integer age = 20;
public string city{get; set;}
public string name{get; set;}
public static List<Merchandise__c> searchResults {get;set;}
public Bo_Test(){
searchResults = new List<Merchandise__c>();
String queryString = 'SELECT Price__c, Name, Unit_Price__c from Merchandise__c';
searchResults = Database.query(queryString);
//this.city = "Jersey City";
//name = "Bobo";
}
public PageReference sayHello(){
return null;
}
}
In the page display, there are no data showed from the Merchandise object(actually there are a lot), did I do it wrong way? how to access the data by editing the apex class?
The point is, Until now I still have no ideas about the page and class related to each other, does it call the default constructor? any kind of suggestions are welcomed!!
Help me! I'm looking forward hearing from you guys
First and foremost, are you binding the page to Bo_Test controller ?
<apex:page controller="Bo_Test">
<apex:dataTable .......
If that is not your problem, try changing your class by
public class Bo_Test{
public List<Merchandise__c> searchResults {get;set;}
public Bo_Test(){
searchResults = [SELECT Price__c, Name, Unit_Price__c from Merchandise__c];
}
}
Notice that I've removed the static property to searchResults.
In addition this initialization is not need.
searchResults = new List<Merchandise__c>();

Resources