A few weeks ago I encountered some unexpected behaviour around action regions and required fields which after some investigation turned out to be a consequence of using the HTML5 doctype. In this post I’ll present an example of the use of an action region in conjunction with required fields and show how it is impacted by HTML5.
Regular Form
As a very simple example, I have a page that allows the user to enter the name of an account and some additional information in a table. The user can click the ‘Add Row’ button to add a new row to the additional information:
The markup for this page is a regular apex:form (the controller isn’t relevant to this post, but is available in the Resources section at the end of this post):
<apex:page controller="RequiredCtrl" tabstyle="Account"> <apex:pageMessages id="msgs"/> <apex:form> <apex:pageBlock mode="maindetail"> <apex:pageBlockButtons location="top"> <apex:commandButton value="Save" action="{!save}" /> </apex:pageBlockButtons> <apex:pageBlockSection title="Account Information"> <apex:pageBlockSectionItem> <apex:outputlabel value="Name"/> <apex:inputfield value="{!Acc.Name}" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Related Information" columns="1"> <apex:pageBlockSectionItem> <apex:commandButton value="Add Row" action="{!addRow}"/> </apex:pageBlockSectionItem> <apex:pageBlockTable value="{!rows}" var="row"> <apex:column headerValue="Value 1"> <apex:inputText value="{!row.val1}" /> </apex:column> <apex:column headerValue="Value 2"> <apex:inputText value="{!row.val1}" /> </apex:column> <apex:column headerValue="Value 3"> <apex:inputText value="{!row.val3}" /> </apex:column> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
Clicking the 'Add Row’ button causes the post back to fail as there is a required field missing:
Adding an Action Region
An action region demarcates a limited section of the form to submit back with the post back. Note that this also requires a rerender component to turn the post back into an Ajax request. By enclosing my table in an output panel containing an action region, the required field no longer has an impact as it is outside the action region (note that I’m also rerendering my page messages component, as without that any errors will be swallowed as detailed in this post):
<apex:outputPanel id="rows"> <apex:actionRegion> <apex:pageBlockSection title="Related Information" columns="1"> <apex:pageBlockSectionItem> <apex:commandButton value="Add Row" action="{!addRow}" rerender="rows,msgs"/> </apex:pageBlockSectionItem> ... </apex:pageBlockSection> </apex:actionRegion> </apex:outputPanel>
I can now click the ‘Add Row’ button and a new row is generated without errors:
Using the HTML5 Doctype
If I then decide I’d like to take advantage of some HTML5 features and turn on the HTML5 doctype on the page:
<apex:page controller="RequiredCtrl" tabstyle="Account" doctype="html-5.0"> ... </apex:page>
Clicking the ‘Add Row’ button suddenly fails again, but with a different style of error decorator:
Digging into the rendered HTML shows that an HTML5 specific attribute has been generated:
<input id="..." required="required" size="20" type="text" value="">
this attribute is handled directly by the browser, which obviously has no idea that there is a bunch of JavaScript lying in wait to trap the post back and turn it into an Ajax request, so it just checks the input element and blocks the post back if it is blank.
immediate=“true"
Workarounds
- The easiest workaround, if you aren’t relying on any HTML5 features, is to turn off the HTML5 doctype.
- If you need HTML5 features, make the field non-required by specifying the required attribute as false in your Visualforce markup if you can (you can’t do this with standard object names unfortunately)
- Manage validation and error messages yourself - see the Field Level Error Messages … links in the Resources section.
- If neither of the above are suitable, use JavaScript to remove the required attribute from the rendered HTML. This is pretty fragile though, as it requires your JavaScript to know which fields are part of an action region and which aren’t.
Hi Bob ,
ReplyDeleteI am struggling to understand the difference between ActionRegion and reRender can you please explain in detail.
Hi Bob,
ReplyDeletethe easiest way to complete turn-off HTML5 validation is to add 'html-formnovalidate="true"' as apex:form attribute.
this way, you would have the rest of HTML5 features, minus the validation.
if you want to disable HTML5 validation only in a specific button is clicked, you can add the same attributte int "Add Row" apex:commandButton. this will not trigger HTML5 validation when clicked.
Regards,
Aldrin
Hi Bob,
ReplyDeletethe easiest way to completely turn-off HTML5 validation is to add 'html-formnovalidate="true"' as apex:form attribute.
this way, you would have the rest of HTML5 features, minus the validation.
if you want to disable HTML5 validation only in a specific button, you can add the same attributte in the button, i.e. in your sample's case, in "Add Row" apex:commandButton. HTML5 validation will not trigger when that button is clicked.
Regards,
Aldrin
P.S: realized that my comment above is messed-up...
Hi Bob,
ReplyDeletethe easiest way to completely turn-off HTML5 validation is to add 'html-novalidate="true"' as apex:form attribute.
this way, you would have the rest of HTML5 features, minus the validation.
if you want to disable HTML5 validation only in a specific button, you can add the corresponding attribute in the button, i.e. in your sample's case, in "Add Row" apex:commandButton. HTML5 validation will not trigger when that button is clicked.
Regards,
Aldrin
P.S: realized that my comment above is messed-up...
Hey Bob,
ReplyDeleteAnother way around this that I've just used - I separated different sections of the page into different forms (I had this issue on a modal).
Andy
@Bob, this blog is really helpful. I have also used two different forms. However, as it is for an AppExchange product will it cause any Security failure? For Checkmarx it says a Quality Issue: "Multiple Forms In Visualforce Page"
DeletePlease suggest. @Bob and @Andy
Now for your next trick...
ReplyDeletePut the red line on 1 or more fields in the pageblocktable..
By the way when I published under my google name after logging into gmail and being redirected to this site, the browser in the bottom left hand corner was trying to connect to alexgorbatchev.com.
Not sure if Bob´s site or my google account has been compromised.
Also when I publish there are attempted connections to alexgorbatchev.com
ReplyDeleteAlex Gorbatchev wrote the syntax highlighter that formats the code snippets - this blog includes JavaScript from his site. You can read more about how this works at : http://bobbuzzard.blogspot.co.uk/2014/01/syntax-highlighting-in-knowledge.html
DeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi Bob, I was able to use the HTML 5 required syntax on a force.com site and worked great on desktop. Leaving the fields blank produced the error message on the fields when clicking on the submit button. However, when I try it on a mobile device, the blank fields are not recognized as being blank and the form gets processed when I press the submit button.
ReplyDeleteDo you know what I'm missing in my CSS or maybe APEX when doing this on mobile? Thanks!!