Custom Validator Erweiterung
Freilegen von versteckten Features im CFM Editor von AEM - Part 3
Einführung
In diesem Blog-Beitrag wird erklärt, wie Sie einen benutzerdefinierten Validator mit wenigen Code-Anpassungen zu bestehenden Content Fragment Elementen hinzufügen können.
Um dies zu tun, müssen wir Custom Properties zum Content Fragment Editor hinzufügen und auch den benutzerdefinierten Validierungscode hinzufügen. Folgen Sie den unten stehenden Schritten, um Ihre eigene Custom Validierung zu erstellen.
Bitte beachten Sie, dass diese Anleitung nicht für den Universial Editor in Edge Delivery Services erstellt wurde, sondern nur für den „klassischen“ AEM Content Fragment Editor.
(Getestet mit AEM 6.5.20)
Step 1 - Validator Namen als Custom Property hinzufügen
Um einen Custom Validator zu einem Element innerhalb des Inhaltsfragment Editors hinzuzufügen, müssen wir den Editor erweitern, indem wir dem Autor erlauben, den Namen des Validators als Eigenschaftsfeld hinzuzufügen, wie im Screenshot gezeigt.
Dieses Feld ist nicht von Haus aus vorhanden, so dass wir es zunächst erstellen müssen.
Der Code für das Eigenschaftsfeld kann hier eingefügt werden:
- /apps/dam/cfm/models/editor/components/datatypeproperties/customvalidation/customvalidation.jsp
<%@include file="/libs/granite/ui/global.jsp" %><%
%><%@ page session="false" contentType="text/html" pageEncoding="utf-8"
import="com.adobe.granite.ui.components.formbuilder.FormResourceManager,
org.apache.sling.api.resource.Resource,
org.apache.sling.api.resource.ValueMap,
java.util.HashMap" %><%
ValueMap fieldProperties = resource.adaptTo(ValueMap.class);
HashMap values = new HashMap();
values.put("granite:class", "field-custom-validation-descriptor");
values.put("fieldLabel", i18n.get("Custom Validator"));
values.put("name", "./content/items/" + resource.getName() + "/granite:data/custom-validator");
values.put("value", fieldProperties.get("granite:data/custom-validator", String.class));
values.put("fieldDescription", "The name of custom validator can be added here");
FormResourceManager formResourceManager = sling.getService(FormResourceManager.class);
Resource labelFieldResource = formResourceManager.getDefaultPropertyFieldResource(resource, values);
%>
In dieser JSP-Datei sehen Sie, dass wir alle Werte hinzufügen, die zum Speichern des Validatornamens in einem Element des Content Fragments erforderlich sind.
Der nächste Schritt ist das Hinzufügen dieser Custom Property zu dem eigentlichen Feld im Editor. In diesem Fall fügen wir sie der Textarea hinzu.
Erstellen Sie eine „.content.xml“ Datei unter
- /apps/settings/dam/cfm/models/formbuilderconfig/datatypes/.content.xml
und überschreiben Sie damit die entsprechende Datei unter /libs.
Der Inhalt der Datei „.content.xml“ sieht folgendermaßen aus:
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<text-multi jcr:primaryType="nt:unstructured" fieldProperties="[mvfields,multieditorfield,maptopropertyfield,multieditordefaultfield,rtemodelpickerfield,
requiredfield,translatablefield,customvalidation]" />
</items>
</jcr:root>
Disclaimer:
Bitte seien Sie vorsichtig beim Überschreiben von Dateien/Eigenschaften im /libs-Ordner. Stellen Sie immer sicher, dass Sie die aktuellsten Änderungen auch in Ihrer Datei in /apps haben.
Schritt 2 - Validierungswert als Custom Property hinzufügen
Als Nächstes tun wir dasselbe für den Validator-Wert. In unserem Fall kann er als maximale Zeichenlänge für die Textarea verwendet werden.
Der Code für das Eigenschaftsfeld kann hier eingefügt werden:
- /apps/dam/cfm/models/editor/components/datatypeproperties/customvalidation/customvalidationvalue.jsp
<%@include file="/libs/granite/ui/global.jsp" %><%
%><%@ page session="false" contentType="text/html" pageEncoding="utf-8"
import="com.adobe.granite.ui.components.formbuilder.FormResourceManager,
org.apache.sling.api.resource.Resource,
org.apache.sling.api.resource.ValueMap,
java.util.HashMap" %><%
ValueMap fieldProperties = resource.adaptTo(ValueMap.class);
HashMap values = new HashMap();
values.put("granite:class", "field-custom-validation-value-descriptor");
values.put("fieldLabel", i18n.get("Custom Validator Value"));
values.put("name", "./content/items/" + resource.getName() + "/granite:data/custom-validator-value");
values.put("value", fieldProperties.get("granite:data/custom-validator-value", String.class));
values.put("fieldDescription", "The value (if needed) of custom validator can be added here");
FormResourceManager formResourceManager = sling.getService(FormResourceManager.class);
Resource labelFieldResource = formResourceManager.getDefaultPropertyFieldResource(resource, values);
%>
Fügen wir nun den neuen benutzerdefinierten Datentyp wieder zum Textarea-Feld hinzu, indem wir ihn erneut zu dieser Datei hinzufügen:
- /apps/settings/dam/cfm/models/formbuilderconfig/datatypes/.content.xml
Der Inhalt der Datei sieht nach dem Hinzufügen von „customvalidationvalue“ wie folgt aus:
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured">
<items jcr:primaryType="nt:unstructured">
<text-multi jcr:primaryType="nt:unstructured" fieldProperties="[mvfields,multieditorfield,maptopropertyfield,multieditordefaultfield,rtemodelpickerfield,
requiredfield,translatablefield,customvalidation,customvalidationvalue]" />
</items>
</jcr:root>
Tipp
Um sicherzustellen, dass nur das richtige Element überschrieben wird, verwenden Sie die folgende filter.xml-Anweisung:
<filter root="/apps/settings/dam/cfm/models/formbuilderconfig/datatypes/item/text-multi"/>
Schritt 3 - Erstellen des benutzerdefinierten Validators
Wir werden einen Maximal-Längen-Validator für ein Textarea-Feld erstellen. Dieses Feld ist etwas Besonderes, denn es kann Klartext, Markup und Richtext mit HTML-Tags enthalten.
Um das Beispiel einfach zu halten, werden wir nur die HTML-Tags Option betrachten..
Der Code für den Validator sieht wie folgt aus:
/**
* Custom validator for textbox that checks the length of the text.
* HTML-Tags are not counted.
*
* Usage
* -----
* Add this to the Content Fragment Model field:
*
*/
(function ($, window) {
'use strict';
const VALIDATOR_ID = 'textbox-maxlength-validator';
// Add Custom Validation / ErrorUI
const registry = $(window).adaptTo("foundation-registry");
registry.register('foundation.validation.validator', {
selector: "[data-custom-validator='" + VALIDATOR_ID + "']",
validate: function(el) {
const maxlength = parseInt(el.getAttribute('data-custom-validator-value'));
if(el.value && el.value.replace(/<[^>]+>/g, '').length > maxlength) {
return Granite.I18n.get('Error: The text must not exceed {0} characters.', maxlength);
}
},
show: function(el, message, ctx) {
// modify appearance of div[contenteditable]
const $parent = $(el).parent();
const $input = $parent.find("[contenteditable=\"true\"]");
$input.addClass("is-invalid");
if (!$parent.find('.coral-Form-errorlabel').length){
const $label = document.createElement("label");
$label.innerHTML = message;
$label.classList.add("coral-Form-errorlabel");
const att = document.createAttribute("tabindex");
att.value = "0";
$label.setAttributeNode(att);
$parent.append($label);
}
},
clear: function(el, ctx) {
// reset style of div[contenteditable]
const $parent = $(el).parent();
const $input = $parent.find("[contenteditable=\"true\"]");
$input.removeClass("is-invalid");
$input.removeAttr("style");
// remove error message field
const $label = $parent.find(".coral-Form-errorlabel");
$label.remove();
}
});
}(jQuery, window));
- Im Code können Sie die VALIDATOR_ID sehen, die im Content Fragment Editor als Name des Validators verwendet wird. In unserem Fall ist es „textbox-maxlength-validator“.
Sie können die Datei zu einem clientlib-Ordner hinzufügen und die Kategorie "dam.cfm.authoring.contenteditor.v2" wie unten zu sehen:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
categories="dam.cfm.authoring.contenteditor.v2" />
Und et voila, wir können jetzt einen benutzerdefinierten Validator zu unseren Feldern innerhalb der Content Fragment Models hinzufügen und sogar einen benutzerdefinierten Wert dafür angeben. In unserem Fall ist es ein einfacher Textlängen-Validator für das Textbereich-Feld, aber es könnte natürlich auch etwas viel Komplexeres sein.
Das ist dann das Endergebnis
Wenn Sie wissen möchten, wie Sie das Tag-Feld erweitern können, um „forceSelection“ zu aktivieren, oder wie Sie einen benutzerdefinierten Before-Until-Datumsvalidator hinzufügen können, klicken Sie bitte hier:
- Mein früherer Blog-Beitrag über forceSelection - Teil 1
- Mein früherer Blog-Beitrag zur Datumsüberprüfung - Teil 2