Using checkboxes in your Adobe Experience Manager component dialogs can be confusing to the new component developer. A few quick examples will reveal just how easy they really are. However, this article is meant to be more than a back-to-basics. We'll discuss best practices and take the opportunity to introduce the Sling Post Servlet. This is where many web developers and engineers have a breakthrough and recognize AEM for what it is - a powerful set of features and APIs, but at its core, it's simply an Apache Sling application.
Before diving into AEM's use of checkboxes, it's important to know the basics of how checkboxes are handled in ordinary HTML. Reading into the
, we find two important rules regarding checkboxes:
- "If the field element has a value attribute specified, then let value be the value of that attribute; otherwise, let value be the string 'on'." (See: 188.8.131.52 Common input element APIs, default/on)
- "When a form is submitted, only 'on' checkbox controls can become successful." (See: 184.108.40.206 Constructing the form data set)
The first bullet point simply means that the default value of a checkbox is the string literal "on" if a value attribute is not defined on the element. The second bullet point has much greater ramifications and will lead us into the topic of the Sling Post Servlet. The HTML specification states that while a checkbox in the on state is submitted with the default/on value, a checkbox in the off state is not submitted at all. The result is that the server will not receive a "false", null or "off" value for an unchecked checkbox, but rather will not receive either the name or a value in the form post.
The real power to control checkboxes in AEM is provided from the
Sling Post Servlet
. Sling provides nine suffixes, four of which we will concentrate on in this article. A suffix is used by submitting an additional request parameter with the parameter name appended with an "@" symbol and the suffix. For example, if you want to act on the "foo" parameter, you would submit "foo@SuffixName" in addition to the "foo" parameter.
Saving checkbox values as Boolean value types in the JCR
When posted to Sling and saved to the JCR, the default property type is String. While this is workable, wouldn't you rather have a Boolean value saved as a Boolean property type? When working in the strongly typed Java language you would use the boolean primitive or Boolean wrapper rather than a String literal to represent a Boolean value, so why not do the same in the JCR? You can use the Sling Post Servlet's
suffix to instruct Sling to set the property type as a Boolean (or other valid value type for that matter).
Removing checkbox values in the off state
suffix instructs Sling to always delete the JCR property before taking action with the request parameters. If the checkbox is unchecked, the JCR property is deleted and since a value wasn't submitted, no property is created in its place. If the checkbox is checked, the JCR property is deleted and simply recreated with the new value, whether the value is the same as before or otherwise.
Setting checkbox values in the off state
suffix instructs Sling to use a given default value should the request parameter not have a value. This alone isn't helpful in the case of an unchecked checkbox because neither the name nor value will be submitted. However, the
will be considered when used in addition to the
suffix because just as the suffix states, the value of an unchecked checkbox will be "missing" so the default value is used.
Tying it all together
So while you can use the
Delete suffix to completely remove a JCR property, you can use the
UseDefaultWhenMissing in conjunction to guarantee that a JCR property will always be present with a value. In fact, by combining the
UseDefaultWhenMissing suffixes, you can ensure a semantically correct Boolean JCR property type is always created with a proper value of true or false.
Run the following cURL commands against a running AEM/CQ instance and observe the JCR property values as well as the JCR property type.
AEM/CQ component dialogs
The most common checkbox control in the Classic UI is the
xtype with its type set to
. By default the Selection/Checkbox control will save the JCR property as the String literal "true." You can use the
suffix to save the String value as a true Boolean by either setting the
config option or by creating a
field for the
You can also use Ext JS's
xtypes in the Classic UI as the most basic checkbox controls. By default the Checkbox xtype will simply submit the default/on value, meaning if you don't specify a value, the default value is "on." You can use the
config option to change the value to the String literal "true" and you can use the
suffix to save the String value as a proper Boolean.
Retrieving Boolean values
One point to keep in mind is that when you set a checkbox to checked as default dialog, the JCR property is not set until the dialog is opened and saved for the first time. A newly created component will not have that
true Boolean value that your Sightly or JSP will be looking for. Therefore, you need to also make sure that your logic is defaults to the
true value if the JCR property doesn't exist.
We discussed the basics and best practices of using checkboxes in AEM component dialogs. However, the checkboxes were a mere prelude into an introduction to the Sling Post Servlet. Hopefully you've come to realize what happens when you update a component; while AEM provides valuable functionality such as validation through Ext JS or Granite, ultimately, the component dialog is simply an HTML form posting to Apache Sling, which in turn handles the JCR update. We introduced four Sling Post Servlet Suffixes. It's important to know that their uses are not limited to checkboxes and that there are five other suffixes to explore, which are detailed in the
. You'll find that the Sling Post Servlet is extremely powerful and invaluable in the case of AEM component dialogs especially for checkboxes and multi-value properties.