AEM Dialog Components #3: Checkbox - Boolean Selection
AEM Dialog Components #3: Checkbox
What is a Checkbox?
The Checkbox is a Granite UI component that allows authors to enable or disable an option (boolean value: true/false).
Common use cases:
- Show/hide elements
- Enable/disable features
- Open links in new tab
- Newsletter opt-in
- Configuration flags
Basic Configuration
Minimal XML Dialog
<showTitle
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./showTitle"
text="Show Title"
value="{Boolean}true"/>Essential properties:
sling:resourceType- Alwaysgranite/ui/components/coral/foundation/form/checkboxname- JCR path (always use./)text- Visible label next to the checkboxvalue- Value when checked (default:{Boolean}true)
Main Properties
1. Checked (Selected by Default)
<enabled
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./enabled"
text="Enable Feature"
checked="{Boolean}true"
value="{Boolean}true"/>When to use: Features enabled by default that the user can disable.
2. Value and uncheckedValue
<openInNewTab
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./openInNewTab"
text="Open in new tab"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>Important:
value- Value saved when checked (default:true)uncheckedValue- Value saved when unchecked (default: saves nothing)
Best practice: Always set uncheckedValue="{Boolean}false" to explicitly save false!
3. Disabled
<readOnlyFlag
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./readOnlyFlag"
text="Read Only (System Managed)"
checked="{Boolean}true"
disabled="{Boolean}true"
value="{Boolean}true"/>Practical Examples
Example 1: Show/Hide Title
<showTitle
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
fieldLabel="Title Visibility"
fieldDescription="Control title display"
name="./showTitle"
text="Show component title"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>HTL:
<h2 data-sly-test="${properties.showTitle}">
${properties.title}
</h2>Example 2: Link in New Tab
<newTab
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./newTab"
text="Open link in new tab"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>HTL:
<a href="${properties.url}"
data-sly-attribute.target="${properties.newTab ? '_blank' : ''}"
data-sly-attribute.rel="${properties.newTab ? 'noopener noreferrer' : ''}">
${properties.linkText}
</a>Example 3: Enable Animations
<enableAnimations
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
fieldLabel="Animations"
name="./enableAnimations"
text="Enable animations"
checked="{Boolean}true"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>HTL:
<div class="component${properties.enableAnimations ? ' animated' : ''}">
<!-- Content -->
</div>Example 4: Featured Content
<isFeatured
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
fieldLabel="Featured"
fieldDescription="Mark this content as featured"
name="./isFeatured"
text="Feature this content"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>Usage: "Featured" badge in frontend, priority sorting.
Complete Dialog with Checkboxes
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Link Component"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<content
jcr:primaryType="nt:unstructured"
jcr:title="Content"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<!-- Link Text -->
<linkText
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Link Text"
name="./linkText"
required="{Boolean}true"/>
<!-- URL -->
<url
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldLabel="URL"
name="./url"
required="{Boolean}true"
rootPath="/content"/>
<!-- Open in new tab -->
<newTab
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./newTab"
text="Open in new tab"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>
<!-- Show icon -->
<showIcon
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./showIcon"
text="Show link icon"
checked="{Boolean}true"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>
</items>
</content>
</items>
</tabs>
</items>
</content>
</jcr:root>Usage in HTL
Simple Boolean Reading
<!-- Show element if checked -->
<div data-sly-test="${properties.showTitle}">
<h2>${properties.title}</h2>
</div>
<!-- Add CSS class if checked -->
<div class="component${properties.enableAnimations ? ' animated' : ''}">
Content
</div>
<!-- Conditional attribute -->
<a href="${properties.url}"
data-sly-attribute.target="${properties.newTab ? '_blank' : ''}">
Link
</a>With Sling Model
@Model(adaptables = Resource.class)
public class LinkModel {
@ValueMapValue
private String linkText;
@ValueMapValue
private String url;
@ValueMapValue(name = "newTab")
private boolean openInNewTab;
@ValueMapValue(name = "showIcon")
private boolean showIcon;
public String getLinkText() {
return linkText;
}
public String getUrl() {
return url;
}
public boolean isOpenInNewTab() {
return openInNewTab;
}
public String getTarget() {
return openInNewTab ? "_blank" : null;
}
public String getRel() {
return openInNewTab ? "noopener noreferrer" : null;
}
public boolean isShowIcon() {
return showIcon;
}
public String getLinkClasses() {
return showIcon ? "link link-with-icon" : "link";
}
}HTL with Model:
<a data-sly-use.model="com.mysite.models.LinkModel"
href="${model.url}"
class="${model.linkClasses}"
data-sly-attribute.target="${model.target}"
data-sly-attribute.rel="${model.rel}">
${model.linkText}
<span data-sly-test="${model.showIcon}" class="icon">→</span>
</a>Custom Values
Example: Strings Instead of Boolean
<alignment
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./centerAlign"
text="Center align content"
value="center"
uncheckedValue="left"/>JCR Result:
- Checked →
centerAlign = "center" - Unchecked →
centerAlign = "left"
HTL:
<div class="content align-${properties.centerAlign || 'left'}">
Content
</div>Checkbox vs Select vs Radio
| Component | Use | Values |
|---|---|---|
| Checkbox | Single On/Off | Boolean (true/false) |
| Radio | Choose 1 from N options | String (selected value) |
| Select | Choose 1 from many options | String (selected value) |
Use Checkbox when: You have a single option to enable/disable.
Common Issues
❌ Issue 1: Value not saved when unchecked
<!-- WRONG - unchecked doesn't save anything in JCR -->
<enabled
name="./enabled"
text="Enable"
value="{Boolean}true"/>
<!-- CORRECT - explicitly saves false -->
<enabled
name="./enabled"
text="Enable"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>Symptom: In HTL ${properties.enabled} is null instead of false.
Solution: Always add uncheckedValue="{Boolean}false".
❌ Issue 2: Boolean without type hint
<!-- WRONG -->
<enabled
value="true"
uncheckedValue="false"/>
<!-- CORRECT -->
<enabled
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>❌ Issue 3: Checked doesn't work
<!-- WRONG - checked as string -->
<enabled
checked="true"/>
<!-- CORRECT -->
<enabled
checked="{Boolean}true"/>❌ Issue 4: Wrong HTL test
<!-- RISKY - null is falsy -->
<div data-sly-test="${properties.enabled}">
<!-- Doesn't appear if enabled is not set -->
</div>
<!-- BETTER - explicit comparison -->
<div data-sly-test="${properties.enabled == true}">
<!-- Appears only if explicitly true -->
</div>
<!-- OR fallback in model -->
public boolean isEnabled() {
return enabled != null ? enabled : false;
}Best Practices
- ✅ Always uncheckedValue:
uncheckedValue="{Boolean}false" - ✅ Type hints for boolean:
value="{Boolean}true" - ✅ Descriptive text: "Show title" not just "Title"
- ✅ fieldDescription: Explain the effect of the checkbox
- ✅ Useful defaults:
checked="{Boolean}true"for features enabled by default - ✅ Clear naming:
showTitle,enableFeature,isActive - ✅ Validation in Model: Handle null → false
- ✅ Conditional attributes: Use ternary operator in HTL
Advanced Patterns
1. Checkbox with Show/Hide
<showAdvanced
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./showAdvanced"
text="Show advanced options"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>
<advancedOptions
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
granite:hide="${!properties.showAdvanced}">
<items jcr:primaryType="nt:unstructured">
<!-- Advanced fields here -->
</items>
</advancedOptions>Show/hide fields based on checkbox.
2. Multiple Related Checkboxes
<enableFeatureA
name="./enableFeatureA"
text="Enable Feature A"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>
<enableFeatureB
name="./enableFeatureB"
text="Enable Feature B"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>
<enableFeatureC
name="./enableFeatureC"
text="Enable Feature C"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>HTL: Combine with OR logic
<div data-sly-test="${properties.enableFeatureA || properties.enableFeatureB || properties.enableFeatureC}">
At least one feature is enabled
</div>Next Lesson
In the next lesson we'll see the Select component for dropdowns with predefined options.
Resources:
Guide #3 of the AEM Dialog Components series - ← Previous lesson | Next lesson →