+ Start a Discussion
ShikibuShikibu 

SelectList with required = True doesn't display validation error

I have a selectList like this, with the required attribute set to True:

 

 

<apex:pageBlockButtons > <apex:commandButton action="{!saveAction}" value="Save"/> <apex:commandButton action="{!cancel}" value="Cancel"/> </apex:pageBlockButtons> <apex:pageBlockSection columns="1" title="Information"> <apex:inputhidden value="{!OpportunityCompetitor__c.Opportunity__c}"/> <apex:pageBlockSectionItem> <apex:outputLabel value="Competitor" for="competitor"/> <apex:selectList value="{!OpportunityCompetitor__c.Competitor__c}" required="True" size="1" id="competitor"> <apex:selectOptions value="{!competitorOptions}"/> <apex:actionSupport event="onchange" action="{!copyStrengthsWeaknesses}" rerender="strengths, weaknesses"/> </apex:selectList> </apex:pageBlockSectionItem>

 

 

  

The selectlist component is not displayed with a red bar.

 

The first value is an empty string, with '-- None --' as label. If the user presses the Save button, the page flashes but does not save, because the page validation is failing.

 

However, no validation message is displayed.

 

If I display apex messages, I can see the validation fails, but these messages are ugly; I don't want to display them to users.

 

How can I get the validation failure to display a nice message next to the field?

 

How can I get the red bar to display on the selectList?

 

 

 

Message Edited by Shikibu on 01-08-2010 10:59 AM
bmabma

Validation Message is not displayed unless you have an apex messages on your page.

 

As to the validation message, you can try to catch the exceptions or loop through Messages (ApexPages.Message) to remove the default message and replace it with your own.

ShikibuShikibu
Here's how to get the red bar displayed (thanks to this blog page).

 

 

<apex:pageBlockSectionItem>
<apex:outputLabel value="Competitor" for="competitor"/>
<apex:outputPanel layout="block" styleClass="requiredInput">
<apex:outputPanel layout="block" styleClass="requiredBlock"/>

<apex:selectList value="{!OpportunityCompetitor__c.Competitor__c}"
required="True" size="1" id="competitor">
<apex:selectOptions value="{!competitorOptions}"/>
<apex:actionSupport event="onchange"
action="{!copyStrengthsWeaknesses}"
rerender="strengths, weaknesses"/>
</apex:selectList>
<script>var competitor = document.getElementById("{!$Component.competitor}");</script>
</apex:outputPanel>
</apex:pageBlockSectionItem>

 

 

 

 

 

Message Edited by Shikibu on 01-08-2010 11:01 AM
ShikibuShikibu

And here's how I accomplished the validation:

 

 

<script type="text/javascript"> function validate_required(field,alerttxt) { with (field) { if (value==null||value=="") { alert(alerttxt); return false; } else { return true; } } } function validate_form() { if (validate_required(competitor,"Please select a competitor")==false) { competitor.focus(); return false; } } </script> <apex:pageBlockButtons > <apex:commandButton action="{!saveAction}" value="Save" onclick="validate_form();"/> <apex:commandButton action="{!cancel}" value="Cancel"/> </apex:pageBlockButtons>

 

 

 

jwetzlerjwetzler
Using salesforce stylesheets and style classes is not supported.  Our stylesheets can and do change often.  I would highly recommend using Firebug or a similar tool to recreate the styles so that they do not suddenly change on you after a release.
ShikibuShikibu

Ah, thanks for the gentle knuckle-rap, Jill.

 

For the benefit of anyone following this thread, here's how I implemented the css as a component, not a static resource (thanks for the suggestion, Wes):

 

 

<apex:component>
<style type="text/css">

.myRequiredInput {
position: relative;
height: 100%;
}

.myRequiredInput .myRequiredBlock {
background-color: #C00;
position: absolute;
left: -4px;
width: 3px;
top: 1px;
bottom: 1px;
}


</style>
</apex:component>

 

 

<apex:page title="Non Disclosure Agreement — Print"
standardController="Opportunity"
extensions="NDAPrinter"
>


<head>
<c:basic_css/>
</head>

<apex:form>

...

 

 

 

 

 

 

 

jwetzlerjwetzler

If you'd like another "gentle knuckle-rap" it is also not supported to specify your own <head> tag on a page where you have not specified showHeader="false".  I am guessing if you were to inspect the source of your page, you would see two head tags.  Most browsers will probably figure out what you mean but that could break as you upgrade your browser, potentially.

 

The advantage to putting these in a static resource is twofold.

1) You can use apex:stylesheet which will insert it into your <head> tag regardless of the structure of your page (and whether you're using the header or not)

2) Static resources generate URLs that are designed to work with your browser cache which, depending on the size your CSS eventually grows to, could have a noticeable impact on the performance of your page.

Message Edited by jwetzler on 01-11-2010 01:45 PM
ShikibuShikibu

Oh, grody.

 

What say you, Jill, if I simply remove the head tags I coded, allowing the css to be derived from the component, but located within body instead of head? This is for a button that prints a pdf contract; I would really rather streamline the developer's process than optimize the page caching (it will be used infrequently).

 

jwetzlerjwetzler
According to w3schools, "The style element always goes inside the head section."  So if you're following the rules, it really is more appropriate to put it in a static resource unless you're not using the header.