Skip to content

Instantly share code, notes, and snippets.

@soluml
Last active January 4, 2022 23:34
Show Gist options
  • Save soluml/4f8b32c5a63f23dbda3bc94f02141f16 to your computer and use it in GitHub Desktop.
Save soluml/4f8b32c5a63f23dbda3bc94f02141f16 to your computer and use it in GitHub Desktop.
Building an AEM Authoring Component out of HTL/Sightly; no JSP required!
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:Folder"
sling:resourceSuperType="granite/ui/components/coral/foundation/form/field"/>
package com.mysite.core.models;
import com.adobe.granite.ui.components.FormData;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
import java.util.Stack;
@Model(
adaptables = {SlingHttpServletRequest.class},
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class DialogValues {
@SlingObject
private SlingHttpServletRequest request;
/**
* @return Returns values
*/
public ValueMap getValues() {
Stack<FormData> formData = (Stack<FormData>) request.getAttribute(FormData.class.getName());
return formData.peek().getValueMap();
}
}
use(function () {
var path = parseInt(this.path, 10) || 0;
var sprites = ["/etc.clientlibs/mysite/clientlibs/site/resources/sprite.svg"];
return sprites[path];
});
$(document).on('foundation-contentloaded', function () {
const $iconSelects = $('.authoringIconSelect');
const spriteXMLMap = new Map();
// Get Sprite's
$iconSelects.each(function () {
const {svgPath, nameStartsWith, value} = this.dataset;
const $this = $(this);
const $sel = $this.find('coral-select');
if (!spriteXMLMap.get(svgPath)) {
spriteXMLMap.set(svgPath, $.ajax(svgPath, {cache: true}));
}
spriteXMLMap.get(svgPath).done((svg) => {
const $svg = $(svg);
const $icons = $svg.find('symbol[id]');
$icons.each(function () {
const {id} = this;
const title = this.querySelector('title')?.innerHTML ?? id;
if (
(!nameStartsWith || id.startsWith(nameStartsWith)) &&
!$sel.find(`option[value="${id}"]`).length
) {
$sel.append(
`<coral-select-item value="${id}"${value == id ? ' selected' : ''}>
<svg><use xlink:href="${svgPath}#${id}"></use></svg>
${title}
</coral-select-item>`
);
}
});
});
});
});
.authoringIconSelect {
coral-select {
width: 100%;
.coral3-Select-label {
overflow: visible;
}
}
svg {
color: currentColor;
height: 1em;
margin: 0 0.625rem 0 0;
transform: scale(1.5) translateY(-5%);
vertical-align: middle;
width: 1em;
}
button svg {
margin: 0 0.625rem;
}
}
<div data-sly-use.sprite="${'mysite/components/icon/icon.use.js'}"
data-sly-use.dialogvalues="com.mysite.core.models.DialogValues"
class="authoringIconSelect coral-Form-field coral-Select"
data-init="select"
data-collision="none"
data-name-starts-with="${properties.nameStartsWith}"
data-svg-path="${sprite}"
data-value="${dialogvalues.values[properties.name]}"
data-sly-test.noIcon="${'No Icon' @ i18n}">
<label id="${currentNode.path}" class="coral-Form-fieldlabel">${properties.fieldLabel}</label>
<coral-select name="${properties.name}" value="${dialogvalues.values[properties.name]}" labelledby="${currentNode.path}" required="${properties.required}">
<coral-select-item value="">
<svg></svg>
${noIcon}
</coral-select-item>
</coral-select>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment