AEM Dialog Components #3: Checkbox - Selezione Boolean
AEM Dialog Components #3: Checkbox
Cos'è un Checkbox?
Il Checkbox è un componente Granite UI che permette agli autori di abilitare o disabilitare un'opzione (valore boolean: true/false).
Casi d'uso comuni:
- Mostra/nascondi elementi
- Abilita/disabilita feature
- Apri link in nuova tab
- Opt-in newsletter
- Flags di configurazione
Configurazione Base
XML Dialog Minimo
<showTitle
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./showTitle"
text="Show Title"
value="{Boolean}true"/>Proprietà essenziali:
sling:resourceType- Sempregranite/ui/components/coral/foundation/form/checkboxname- Percorso JCR (usa sempre./)text- Etichetta visibile accanto al checkboxvalue- Valore quando checked (default:{Boolean}true)
Proprietà Principali
1. Checked (Selezionato di 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"/>Quando usarlo: Feature abilitate di default che l'utente può disabilitare.
2. Value e 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"/>Importante:
value- Valore salvato quando checked (default:true)uncheckedValue- Valore salvato quando unchecked (default: non salva nulla)
Best practice: Imposta sempre uncheckedValue="{Boolean}false" per salvare esplicitamente 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"/>Esempi Pratici
Esempio 1: Mostra/Nascondi Titolo
<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>Esempio 2: Link in Nuova 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>Esempio 3: Abilita Animazioni
<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>Esempio 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"/>Uso: Badge "Featured" nel frontend, ordinamento prioritario.
Dialog Completa con Checkbox
<?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>Uso in HTL
Lettura Boolean Semplice
<!-- Mostra elemento se checked -->
<div data-sly-test="${properties.showTitle}">
<h2>${properties.title}</h2>
</div>
<!-- Aggiungi classe CSS se checked -->
<div class="component${properties.enableAnimations ? ' animated' : ''}">
Content
</div>
<!-- Attributo condizionale -->
<a href="${properties.url}"
data-sly-attribute.target="${properties.newTab ? '_blank' : ''}">
Link
</a>Con 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 con 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>Valori Personalizzati
Esempio: Stringhe invece di 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
| Componente | Uso | Valori |
|---|---|---|
| Checkbox | On/Off singolo | Boolean (true/false) |
| Radio | Scegli 1 da N opzioni | Stringa (valore selezionato) |
| Select | Scegli 1 da molte opzioni | Stringa (valore selezionato) |
Usa Checkbox quando: Hai una singola opzione da abilitare/disabilitare.
Problemi Comuni
❌ Problema 1: Valore non salvato quando unchecked
<!-- SBAGLIATO - unchecked non salva nulla nel JCR -->
<enabled
name="./enabled"
text="Enable"
value="{Boolean}true"/>
<!-- CORRETTO - salva esplicitamente false -->
<enabled
name="./enabled"
text="Enable"
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>Sintomo: In HTL ${properties.enabled} è null invece di false.
Soluzione: Aggiungi sempre uncheckedValue="{Boolean}false".
❌ Problema 2: Boolean senza type hint
<!-- SBAGLIATO -->
<enabled
value="true"
uncheckedValue="false"/>
<!-- CORRETTO -->
<enabled
value="{Boolean}true"
uncheckedValue="{Boolean}false"/>❌ Problema 3: Checked non funziona
<!-- SBAGLIATO - checked come stringa -->
<enabled
checked="true"/>
<!-- CORRETTO -->
<enabled
checked="{Boolean}true"/>❌ Problema 4: Test HTL sbagliato
<!-- RISCHIOSO - null è falsy -->
<div data-sly-test="${properties.enabled}">
<!-- Non appare se enabled non è impostato -->
</div>
<!-- MEGLIO - confronto esplicito -->
<div data-sly-test="${properties.enabled == true}">
<!-- Appare solo se esplicitamente true -->
</div>
<!-- OPPURE fallback nel model -->
public boolean isEnabled() {
return enabled != null ? enabled : false;
}Best Practices
- ✅ Sempre uncheckedValue:
uncheckedValue="{Boolean}false" - ✅ Type hints per boolean:
value="{Boolean}true" - ✅ Text descrittivo: "Show title" non solo "Title"
- ✅ fieldDescription: Spiega l'effetto del checkbox
- ✅ Default utili:
checked="{Boolean}true"per feature abilitate di default - ✅ Naming chiaro:
showTitle,enableFeature,isActive - ✅ Validazione in Model: Gestisci null → false
- ✅ Attributi condizionali: Usa operatore ternario in HTL
Pattern Avanzati
1. Checkbox con 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>Mostra/nascondi campi basato su checkbox.
2. Multiple Checkboxes Correlate
<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: Combina con OR logic
<div data-sly-test="${properties.enableFeatureA || properties.enableFeatureB || properties.enableFeatureC}">
At least one feature is enabled
</div>Prossima Lezione
Nella prossima lezione vedremo il componente Select per dropdown con opzioni predefinite.
Risorse:
Guida #3 della serie AEM Dialog Components - ← Lezione precedente | Prossima lezione →