Find your content:

Search form

You are here

Select from PricebookEntry breaks call from Visualforce


For some reason the second query in the constructor makes the Cancel button in my visualforce page not work. Does this have to do with some special quirk in PricebookEntry?

If you comment out the second query (the one that populates HwAndSwProducts) the cancel button works fine.

This is the controller:

public with sharing class ManageAddSupportController {

    public Opportunity opp { get; private set; } 
    public List<PricebookEntry> HwAndSwProducts { get; private set; } 

    public ManageAddSupportController() {
        //Populate controller properties
        opp = [SELECT name, id, Pricebook2Id FROM Opportunity 
            WHERE Id =: ApexPages.currentPage().getParameters().get('id')]; 

        //This is the query that if we comment out the Cancel works    
        HwAndSwProducts = [SELECT name, id, ProductCode, UnitPrice 
            FROM PricebookEntry WHERE Pricebook2Id =:opp.Pricebook2Id 
            AND (NOT name LIKE '%Service%')]; 

    public PageReference cancelSupport() {
        System.debug('we want to cancel!!!');
        PageReference ref = new PageReference('/' + opp.Id);
        return ref;         

And this is the view:

<apex:page controller="ManageAddSupportController">

<h1>Opportunity {!}</h1>
<p>Please choose those products you'd like to add support to.</p>

<apex:form >
    <div style="text-align:center">
        <apex:commandButton action="{!cancelSupport}" value="Cancel" id="cancelAddSupport" />
    <apex:pageBlock >
        <apex:pageBlockTable value="{!HwAndSwProducts}" var="product">
            <apex:column style="width: 5%">
                <apex:inputCheckbox value="{!product.Id}"/>
            <apex:column value="{!product.Name}"/>
            <apex:column value="{!product.ProductCode}"/>
            <apex:column value="{!product.UnitPrice}"/>

When I add debugging statements in the cancel action I see that it's not even being called when that second query is present. If you look at the logs it seems like the constructor is being called again. Very strange...

Attribution to: ceiroa

Possible Suggestion/Solution #1

This "cancel" action (like any other button) is doing a postback to the controller. That's a lot of work (deserialize viewstate, perform basic checks on the data such as "were the fields marked as required actually filled in"...)

To bypass these checks use immediate="true" in your commandButton. Furthermore - I don't think you even need the whole cancelSupport function. URLFOR will do - and less code to maintain and provide code coverage is always a good thing.

Combine these 2 for maximum performance ;)

    action="{!URLFOR($Action.Opportunity.View, opp.Id)}"
    immediate="true" />

Being able to modify the link in future right in the VF page (without redeploying the Apex) is just an added bonus!

EDIT Why do you have a custom controller actually? This page looks like a candidate to have standardController="Opportunity". Then your job would be even easier, action="{!view}" :)

Attribution to: eyescream

Possible Suggestion/Solution #2

This was a tricky one, adding this to the Visualforce page

<apex:pageMessages />

finally grassed up the culprit !

Incorrect Binding !

This is the offending binding :

 <apex:inputCheckbox value="{!product.Id}"/>

You're binding a boolean to an Id field, which fails conversion at runtime.

Commenting out this line makes the Cancel button work just fine.

If you intend using a checkbox to select Products, make use of the wrapper pattern, where you can have a boolean instance variable for selection.

P.S. As for the mystery of why commenting out the second SOQL query makes it works - no Products selected, so no Runtime Exception converting Boolean to Id.

Attribution to: techtrekker
This content is remixed from stackoverflow or stackexchange. Please visit

My Block Status

My Block Content