During my adventures trying to get a <select required="required"> to actually be required, I discovered:

If a select element has a required attribute specified, does not have a multiple attribute specified, and has a display size of 1; and if the value of the first option element in the select element's list of options (if any) is the empty string, and that option element's parent node is the select element (and not an optgroup element), then that option is the select element's placeholder label option.

So I changed my markup to mirror that:

<select required="required" ...>
    <option value="">--</option>
    ...
</select>

But unfortunatley it rendered as:

<select required="required" ...>
    <option>--</option>
    ...
</select>

And because value="" was stripped out, it no longer meets the specification for <select required="required">, and the form can be submitted with no value selected.

How can I get the value="" attribute specification to stick?

up vote 6 down vote accepted

Here is another way to do it w/o javascript:

Set the value to a VisualForce function that evaluates to nothing:

<apex:page standardController="Contact" >
<apex:form>
    <select required="required">
        <option value="{!IF(1=1,'','')}">--</option>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
    </select>
    <apex:commandButton value="Test Submit" action="{!save}" />
</apex:form>

It will send the value attribute to the browser: HTML in browser

The browser will require it now:

Required on form submit

  • 1
    I prefer IF(true,...) to IF(1=1,...). Regardless, it is much better to avoid javascript than what I came to on my own. – Adrian Larson Oct 11 at 17:52

It's ugly, but below is the workaround I found. I would be happy to find one which does not require Javascript.

Since I already had a page load listener, I simply appended to it:

(function (w) {
    "use strict";
    w.addEventListener("load", function () {
        [].forEach.call(
            document.querySelectorAll("option:not([value])"),
            function (element) { element.value = ''; }
        );
    }
})(window);

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.