You need to sign in to do that
Don't have an account?
Revealing adderror() message in VF page?
First off, thanks to Bob Buzzard and everyone else I've been learning from in these discussion boards. You've gotten me this far, and with a little more help I think I'll be home.
I'm trying to reveal an error message, "That event is already full" when a user tries to sign up for an event that's sold out (slots_remaining < 1).
The relevant part of the visualforce code is 5 lines from the bottom, where I'd like the error message to appear below the inputfield for slots_remaining__c.
This is the page (public_event_select_page):
<apex:page showheader="false" cache="false" standardController="Campaign" extensions="Public_Event_Controller2"> <apex:stylesheet value="{!$Resource.wg_styles}"/> <apex:detail subject="{!$CurrentPage.parameters.cid}" relatedList="false" title="false"/> <apex:form > <apex:dataTable value="{!campaign}" var="c" cellPadding="10" border="0"> <apex:column width="100px" style="vertical-align: top;"> <apex:facet name="header">Name</apex:facet> <apex:commandLink action="{!prepsignup}" value="{!c.name}" id="theButton"> <apex:param assignTo="{!passCampID}" value="{!c.ID}" name="passCampID"/> </apex:commandLink> </apex:column> <apex:column style="vertical-align: top;"> <apex:facet name="header">Short description</apex:facet> {!c.description} </apex:column> <apex:column style="vertical-align: top;"> <apex:facet name="header">Date and time</apex:facet> <apex:outputfield value="{!c.Event_Time_Shifted__c}"/> </apex:column> <apex:column style="vertical-align: top;"> <apex:facet name="header">Cost</apex:facet> <apex:outputText value="{0,number,$#,####.##}"> <apex:param value="{!c.Event_Cost__c}" /> </apex:outputText> </apex:column> <apex:column style="vertical-align: top;"> <apex:facet name="header">Places remaining</apex:facet> <apex:inputfield value="{!c.Slots_remaining__c}" /> </apex:column> </apex:dataTable> </apex:form> </apex:page>
And the relevant part of the controller (public_event_controller):
public PageReference prepSignup() { system.debug('Beginning prepSignup. passCampID is now '+ passCampID); Camp = [SELECT Id ,Name, Description, Description_Long__c, Event_Cost__c, Event_Location__c, Event_Date_time__c, Waiver_Required__c, Event_Time_Shifted__c, Slots_Remaining__c, CnP_URL__c FROM Campaign WHERE id = :passCampID limit 1]; system.debug('Camp.ID is now ' + Camp.ID); if (camp.Slots_remaining__c >= 1) { results = null; createNewLead = false; system.debug('Camp.slots_remaining__c is now '+ camp.slots_remaining__c); PageReference signUpForEvent = Page.Public_Event_Signup_Page2; signUpForEvent.setRedirect(false); return signUpForEvent;} else { camp.slots_remaining__c.addError('This event is full.'); return null; } } // END PREPSIGNUP()
At present the controller behaves as desired, except that no error message appears.
Maybe the problem is that when the controller returns null and visualforcepage rerenders the initial page (public_event_select_page2), the new error message is no longer associated with the campaign. the campaigns displayed on thep age are selected by
public List<Campaign> getCampaign() { return [select campaign.name, id, Description, Event_Date_Time__c, Event_Time_Shifted__c, recordtypeid, Event_Cost__c, Slots_Remaining__c, Waiver_Required__c, CnP_URL__c from Campaign where (Event_Date_Time__c >= Today and (recordtype.name = 'Public Event' or recordtype.name = 'Volunteer Event')) ORDER BY Event_Date_Time__c ASC]; }
I've tried to follow Bob Buzzard's example but since he's iterating through an object differently, I'm not surely how to get the error message back to the visualforce page.
Thanks in advance for your help,
Baird
Hi,
Try this:
Use <apex:pageMessages ></apex:pageMessages> statement below the <apex:form> tag.
Hope this helps.
Thanks,
Devendra S
Thanks, Devendra, that's almost perfect.
But it puts the error message at the top of the page. Do you know how I can position it right under the field itself?
Baird
Hi,
The posistion of <apex:pagMessages /> can be at anywhere on the vf, altenatively you can put a <div> element under inpuField and conditionally display that div with error message.
Hi,
Please follow below link to display error message at field level:
http://bobbuzzard.blogspot.com/2011/04/field-level-error-messages-with_29.html
Hope this helps.
Thanks,
Devendra
Hah - a circular reference if I'm not mistaken.
I suspect that what is happening is that you are retrieving the records anew each time, which means that you will lose the error message you added to the copy you originally retrieved.
I'd try caching the campaigns rather than retrieving each time:
that way you are always dealing with the same instance that you add the error to.
Thanks Bob, Devendra, and Hermant for your quick responses. I was out with clients yesterday and couldn't respond.
Still no solution. I've tried Bob's suggesting to cache the SOQL query results, and no luck.
I'm wondering whether the field.adderror() is being attached to the wrong object, ie one that doesn't get queried when the list of events(campaigns) on the VF page is revealed.
I'll post my full controller code at the bottom, but here's the sequence that I think matters:
1. The page reveals the results of the SOQL query for events(campaigns) that haven't yet passed. As Bob suggested, I've changed the code to cache the results so they don't change when I refresh the page.
2. When a user clicks on one of the campaign names (CommandURLs), the page sets the passCampID parameter and invokes prepsignup().
3. Prepsignup() SOQL uses the passCampID to select the chosen event "camp". If the event still has spaces available, the controller invokes the next VF page and signs the user up for the event. If it doesn't have spaces left, the controller adds the error to camp.slots_remaining__c, and returns null, which should theoretically take us back to the list of events, but this time with the error message.
The sequence works as planned, except there's no field-level error message visible.
My question: when the controller adds the error to camp.slots_remaining__c, is that registered within Salesforce as the same campaign instance as the one that's returned by the SOQL query Bob suggested in step one?
My second question: In Bob's example, he creates a value
and then sets that to true when the error condition exists within one of the iterations within it.
Was this error value essential to revealing the error messages? I'd assumed it wasn't, but maybe that's what I'm missing.
Once again, many thanks for your help.
Baird
Full controller code below: (Full VF page code is in first post).
I think you are correct, in that you are adding the error to a different sobject instance. When the pre-signup action method is invoked, you should locate the particular campaign in the mCampaign list rather than querying it from the database again. While you are retrieving the same data, it is stored in a different object to those in the list.
Thanks, let me mull this one over. It seems like it's worth squeezing everything I can out of field-level error messages. They're elegant and specific.
That's definitely how I'd approach it. Users tend to be able to resolve the errors faster if they are directed to the field, rather than having to read the error message and work out the erroneous data for themselves. Let us know if you hit further issues,