Dear All,
I am customizing RTE plugin by following blog https://aemlab.blogspot.com/2019/07/aem-rte-custom-plugins-1.html for upload asset and facing below two issues.
1) My upload ICON should come as below highlighted in yellow but it is not coming.
I have written below JavaScript and added below node in RTE plugins as below.
************ BELOW JAVASCRIPT *************
(function ($, $document) {
console.log("inside asset upload");
var EAEM_PLUGIN_ID = "assetuploadButton",
EAEM_ASSETUPLOAD_FEATURE = "assetUploadButton",
EAEM_ASSETUPLOAD_ICON = EAEM_PLUGIN_ID + "#" + EAEM_ASSETUPLOAD_FEATURE,
BUTTON_FORM_URL = "/apps/cfm-rte-plugins/rte-assetUpload-form.html",
SENDER = "experience-aem-button", REQUESTER = "requester", $eaemButtonFormModal;
var url = document.location.pathname;
console.log("EAEM_ASSETUPLOAD_ICON ==== " + EAEM_ASSETUPLOAD_ICON);
var assetUploadPath;
var SUPPORTED_TYPES = [
{
"type": "image",
"mimeTypeDetector": function (mimeType) {
if (CUI.rte.Common.strStartsWith(mimeType, "image/")) {
return true;
}
return false;
},
createHTML: function (path) {
return "<img src=\"" + encodeURI(path) + "\">";
}
}, {
"type": "video",
"mimeTypeDetector": function (mimeType) {
if (CUI.rte.Common.strStartsWith(mimeType, "video/")) {
return true;
}
return false;
},
createHTML: function (path) {
return "<video src=\"" + path + "\" controls=\"controls\"></video>";
}
}
];
if (url.indexOf("/editor.html") == 0) {
extendButtonPlugin();
registerPlugin();
} else if (url.indexOf(BUTTON_FORM_URL) == 0) {
handleForm();
}
function handleForm() {
$document.on("foundation-contentloaded", fillDefaultValues);
setTimeout(function () {
$('a[data-foundation-wizard-control-action="cancel"]').click(sendCancelMessage);
$('button[data-foundation-wizard-control-action="next"]').hide();
validateForm();
}, 100);
}
function replaceLastString(str) {
var myArr = str.split("/");
var lastIndex = str.lastIndexOf("/");
str = str.slice(0, lastIndex);
return str;
}
function initSelectBehavior($form) {
$(window.document).unbind("foundation-validation-valid");
$(window.document).unbind("foundation-validation");
var $form = $("coral-panel");
$form.addClass("coral-Form coral-Form--vertical foundation-layout-util-maximized-container");
$form.find('button[data-foundation-wizard-control-action="next"]').prop('disabled', true);
var $buttonSelect = $form.find('coral-select[name="button_select"]');
$buttonSelect[0].addEventListener('change', function (event) {
validateForm();
});
assetUploadPath = getParent().location.pathname.replace("/editor.html", "").replace(getcontentFragmentType(), "assets/images");
assetUploadPath = replaceLastString(assetUploadPath);
var $altTextInput = $form.find('input[name="altText"]');
$altTextInput.on('change', validateForm);
var $assetNameInput = $form.find('input[name="assetName"]');
$assetNameInput.on("change", function (event) {
if (validateAssetName(this.value)) {
addOrReplaceInCustomPatameter(document.querySelector('coral-fileupload[name="file"]')._uploadQueue[0], "fileName", this.value);
}
validateForm();
});
var $rteAssetUpload = $('coral-fileupload[name="file"]');
$rteAssetUpload.attr('action', assetUploadPath + '.createasset.html');
$assetNameInput.parent().appendTo($rteAssetUpload);
$altTextInput.parent().appendTo($rteAssetUpload);
var uploadButton = new Coral.Button().set({
label: {
innerHTML: "Upload Asset"
},
icon: "upload",
iconSize: "S",
id: 'uploadButton',
class: 'coral3-Button coral3-Button--secondary',
size: 'S',
variant: 'secondary',
title: 'Upload Asset',
type: 'button'
});
$(uploadButton).attr('coral-fileupload-submit', '');
$(uploadButton).appendTo($rteAssetUpload);
uploadButton.on('click', function (event){
var loadingDialog = FORM.createLoadingModal();
loadingDialog.show();
});
$rteAssetUpload.width('100%');
$rteAssetUpload.on('coral-fileupload:fileadded', function (event) {
//validate/change filename
var item = event.detail.item;
var isAssetNameValid = validateAssetName(item.file.name);
var $assetName = $('input[name="assetName"]');
if (!isAssetNameValid) {
$assetName.addClass('is-invalid');
$(uploadButton).prop('disabled', true);
} else {
$assetName.removeClass('is-invalid');
$(uploadButton).prop('disabled', false);
addOrReplaceInCustomPatameter(item, "fileName", item.file.name);
}
$assetName.val(item.file.name);
});
$rteAssetUpload.on('coral-fileupload:load', function (event) {
var item = event.detail.item;
var altText = $('input[name="altText"]').val();
//alert("altText is : " + altText);
if (item.status === 200) {
var assetPath = assetUploadPath + '/' + item.name;
$.ajax({
type: 'GET',
url: '/bin/updateproperty',
data: {
assetpath: assetPath,
AltText: altText
},
dataType: 'json',
success: function (data) {
console.log("success");
}
});
var message = {
sender: SENDER,
action: "submit",
data: {}
};
message.assetPath = assetPath;
parent.postMessage(JSON.stringify(message), "*");
}
if (item._xhr.statusText !== "OK") {
var errorDialog = document.querySelector('#uploadErrorDialog');
loadingDialog.hide();
errorDialog.show();
}
});
$rteAssetUpload.parent().hide();
function addOrReplaceInCustomPatameter(item, name, value) {
item.parameters = item.parameters ? item.parameters : [];
var isPresent = false;
item.parameters.forEach(function (itm) {
isPresent = true;
if (itm.name === name) {
itm.value = value;
}
});
if (!isPresent) {
item.parameters.push({
name: name,
value: value
});
}
// Specific handling for file name. As file object also contains name
if (name === "fileName") {
item.name = value;
}
};
}
function getcontentFragmentType() {
return getParent().location.pathname.split("/")[6];
}
function validateForm() {
$assetName = $('input[name="assetName"]');
var isAssetNameValid = validateAssetName($assetName.val());
$rteAssetUpload = $('coral-fileupload[name="file"]');
if (!isAssetNameValid) {
$assetName.addClass('is-invalid');
$('#uploadButton').prop('disabled', true);
} else {
$assetName.removeClass('is-invalid');
$('#uploadButton').prop('disabled', false);
addOrReplaceInCustomPatameter($rteAssetUpload, "fileName", $assetName.val());
}
$buttonSelect = $('coral-select[name="button_select"]');
if ($buttonSelect[0].selectedItem.value !== '') {
$buttonSelect.prop('invalid', false);
$rteAssetUpload.parent().show();
setTimeout(function () { $buttonSelect.prop('invalid', false); });
if ($buttonSelect[0].selectedItem.value === 'Image') {
$('input[name="altText"]').parent().show();
$rteAssetUpload.attr('accept', 'image/*');
assetUploadPath = getParent().location.pathname.replace("/editor.html", "").replace(getcontentFragmentType(), "assets/images");
assetUploadPath = replaceLastString(assetUploadPath);
$rteAssetUpload.attr('action', assetUploadPath + '.createasset.html');
}
else {
$rteAssetUpload.attr('accept', 'video/*');
$('input[name="altText"]').val('');
$('input[name="altText"]').parent().hide();
assetUploadPath = getParent().location.pathname.replace("/editor.html", "").replace(getcontentFragmentType(), "assets/videos");
assetUploadPath = replaceLastString(assetUploadPath);
$rteAssetUpload.attr('action', assetUploadPath + '.createasset.html');
}
} else {
setTimeout(function () { $buttonSelect.prop('invalid', true); });
$rteAssetUpload.parent().hide();
$buttonSelect.prop('invalid', true);
$('#uploadButton').prop('disabled', true);
}
}
function addOrReplaceInCustomPatameter(item, name, value) {
item.parameters = item.parameters ? item.parameters : [];
var isPresent = false;
item.parameters.forEach(function (itm) {
isPresent = true;
if (itm.name === name) {
itm.value = value;
}
});
if (!isPresent) {
item.parameters.push({
name: name,
value: value
});
}
// Specific handling for file name. As file object also contains name
if (name === "fileName") {
item.name = value;
}
}
function validateAssetName(assetName) {
var illegalCharacters = ["*", "/", ":", "[", "\\", "]", "|", "#", "%", "{", "}", "?", "`", "‘", "’", "'", "!", "$", "<", ">", "~", "@", "&", "^", "+", "=", ",", "é", "à", "è", "ù", "â", "ê", "î", "ô", "û", "ä", "ë", "ü", "ç", "ó", "ï", "Ç", "œ", "«", "»", ";", "æ", "€", "—", "–", "À", "Â",
"Ä", "Æ", "Ç", "È", "É", "Ê", "Ë", "Î", "Ï", "Ô", "Œ", "Ù", "Û", "Ü", " "];
var pattern = /\.[0-9a-z]{3,4}$/i;
if (typeof assetName === "string") {
if (contains(assetName, illegalCharacters) || !assetName.match(pattern)) {
return false;
} else {
return true;
}
}
}
function contains(str, chars) {
for (var i = 0; i < chars.length; i++) {
if (str.indexOf(chars[i]) > -1) {
return true;
}
}
return false;
}
function fillDefaultValues() {
var $form = $("coral-panel"),
form = $("form")[0];
initSelectBehavior($form);
}
function sendCancelMessage() {
var message = {
sender: SENDER,
action: "cancel"
};
getParent().postMessage(JSON.stringify(message), "*");
}
function getParent() {
if (window.opener) {
return window.opener;
}
return parent;
}
function closePicker(event) {
event = event.originalEvent || {};
if (_.isEmpty(event.data)) {
return;
}
var message, action;
try {
message = JSON.parse(event.data);
} catch (err) {
return;
}
if (!message || message.sender !== SENDER) {
return;
}
action = message.action;
if (action === "submit") {
if (message.assetPath !== undefined) {
getData(message.assetPath, function (assetToInsert) {
// create HTML and insert it
if (assetToInsert) {
var assetPath = assetToInsert.path;
var type = assetToInsert.type;
var html = type.createHTML(assetPath);
$eaemButtonFormModal.eaemButtonPlugin.editorKernel.execCmd("insertprocessed", html);
} else {
// TODO error handling?
}
if ($eaemButtonFormModal) {
var modal = $eaemButtonFormModal.data('modal');
modal.hide();
modal.$element.remove();
}
var uploadAssetSuccessDialog = new Coral.Dialog().set({
id: "uploadAssetSuccessDialog",
header: {
innerHTML: Granite.I18n.get('Asset Uploaded')
},
backdrop: Coral.Dialog.backdrop.STATIC,
content: {
innerHTML:
`Your asset is saved at ${assetPath || message.assetPath}`
},
footer: {
innerHTML: "<button is=\"coral-button\" variant=\"primary\" coral-close=\"\" class=\"coral3-Button coral3-Button--primary\" size=\"M\"><coral-button-label>Ok</coral-button-label></button>"
},
variant: "success"
});
var loadingDialog = FORM.createLoadingModal();
loadingDialog.hide();
uploadAssetSuccessDialog.show();
});
}
}
if (action === "cancel") {
if ($eaemButtonFormModal) {
var modal = $eaemButtonFormModal.data('modal');
modal.hide();
modal.$element.remove();
}
}
}
function getMetaData(data) {
var metaData = undefined;
if (data.hasOwnProperty("jcr:content")) {
metaData = data["jcr:content"]["metadata"];
}
return metaData;
}
function getAssetTypeFromMimeType(mimeType) {
if (!mimeType) {
return undefined;
}
for (var t = 0; t < SUPPORTED_TYPES.length; t++) {
var type = SUPPORTED_TYPES[t];
if (type.mimeTypeDetector(mimeType)) {
return type;
}
}
return undefined;
}
function getData(path, callback) {
$.ajax(path + ".2.json", {
success: function (data) {
var assetData = undefined;
if (data) {
if (data["jcr:primaryType"] === "dam:Asset") {
var metaData = getMetaData(data);
if (metaData) {
var mimeType = metaData["dam:MIMEtype"]
|| metaData["dc:format"];
var assetType = getAssetTypeFromMimeType(mimeType);
if (assetType) {
assetData = {
"type": assetType,
"path": path,
"metaData": metaData
};
}
}
}
}
if (callback) {
callback(assetData);
}
},
error: function () {
if (callback) {
callback(undefined);
}
}
});
}
function extendButtonPlugin() {
var origFn = Dam.CFM.StyledTextEditor.prototype._start;
Dam.CFM.StyledTextEditor.prototype._start = function () {
addRTEPluginSettings(this);
origFn.call(this);
}
}
function addRTEPluginSettings(editor) {
var config = editor.$editable.data("config");
config.rtePlugins[EAEM_PLUGIN_ID] = {
features: "*"
};
config.uiSettings.cui.multieditorFullscreen.toolbar.push(EAEM_ASSETUPLOAD_ICON);
}
function registerPlugin() {
var EAEM_CFM_ASSETUPLOAD_PLUGIN = new Class({
toString: "eaemCFMUploadPlugin",
extend: CUI.rte.plugins.Plugin,
buttonFormUI: null,
getFeatures: function () {
return [EAEM_ASSETUPLOAD_FEATURE];
},
notifyPluginConfig: function (pluginConfig) {
var defaults = {
tooltips: {}
};
defaults.tooltips[EAEM_ASSETUPLOAD_FEATURE] = {
title: "Upload Asset from your desktop..."
};
CUI.rte.Utils.applyDefaults(pluginConfig, defaults);
this.config = pluginConfig;
},
initializeUI: function (tbGenerator) {
if (!this.isFeatureEnabled(EAEM_ASSETUPLOAD_FEATURE)) {
return;
}
this.buttonFormUI = new tbGenerator.createElement(EAEM_ASSETUPLOAD_FEATURE, this, false,
this.config.tooltips[EAEM_ASSETUPLOAD_FEATURE]);
tbGenerator.addElement(EAEM_ASSETUPLOAD_FEATURE, 999, this.buttonFormUI, 999);
if (tbGenerator.registerIcon) {
tbGenerator.registerIcon(EAEM_ASSETUPLOAD_ICON, "upload");
}
$(window).off('message', closePicker).on('message', closePicker);
},
isValidSelection: function () {
var winSel = window.getSelection();
return winSel && winSel.rangeCount == 1 && winSel.getRangeAt(0).toString().length > 0;
},
execute: function (pluginCommand, value, envOptions) {
var context = envOptions.editContext;
if (pluginCommand != EAEM_ASSETUPLOAD_FEATURE) {
return;
}
var selection = CUI.rte.Selection.createProcessingSelection(context),
ek = this.editorKernel, startNode = selection.startNode;
var winSel = window.getSelection();
if (winSel && winSel.rangeCount == 1 && winSel.getRangeAt(0).toString().length == 0 && ($(window.getSelection().baseNode).prop('tagName') !== 'A' && $(window.getSelection().baseNode).parent().prop("tagName") !== 'A')) {
if ((selection.startOffset === startNode.length) && (startNode != selection.endNode)) {
startNode = startNode.nextSibling;
}
this.showModal(this.getButtonFormFrameUrl());
}
},
showModal: function (url) {
var self = this, $iframe = $('<iframe id="rteAssetUploadFrame">'),
$modal = $('<div>').addClass('eaem-cfm-font-size-rte coral-Modal');
$iframe.attr('src', url).appendTo($modal);
$modal.appendTo('body').modal({
type: 'default',
buttons: [],
visible: true
});
$eaemButtonFormModal = $modal;
$eaemButtonFormModal.eaemButtonPlugin = self;
$modal.nextAll(".coral-Modal-backdrop").addClass("cfm-coral2-backdrop-rte");
},
getButtonFormFrameUrl: function () {
return Granite.HTTP.externalize(BUTTON_FORM_URL) + "?" + REQUESTER + "=" + SENDER;
},
updateState: function (selDef) {
var hasUC = this.editorKernel.queryState(EAEM_ASSETUPLOAD_FEATURE, selDef);
if (this.buttonFormUI != null && this.buttonFormUI.$ui != null) {
var winSel = window.getSelection(),
isTextSelected = winSel && winSel.rangeCount == 1 && winSel.getRangeAt(0).toString().length == 0 && ($(window.getSelection().baseNode).prop('tagName') !== 'A' && $(window.getSelection().baseNode).parent().prop("tagName") !== 'A');
isTextSelected ? this.buttonFormUI.$ui.removeClass('is-disabled') : this.buttonFormUI.$ui.addClass('is-disabled');
this.buttonFormUI.setSelected(isTextSelected);
}
}
});
CUI.rte.plugins.PluginRegistry.register(EAEM_PLUGIN_ID, EAEM_CFM_ASSETUPLOAD_PLUGIN);
}
}(jQuery, jQuery(document)));
and I have added below highlighted in yellow in RTE Plugins
and then I have added assetupload#assetUploadButton in both inline and dialogFullscreen under UIsettings , as shown below.
But after adding all upload asset ICON is coming blank , as shown below
2) The second issue is that I am getting below error in my console for dam is not defined for button plugin as shown below.
function extendButtonPlugin() {
var origFn = Dam.CFM.StyledTextEditor.prototype._start;
Can anybody please help me here.
Solved! Go to Solution.
Views
Replies
Total Likes
It seems the problem is in your code. Maybe the "selection" is getting null so that "startNode" is not going to be read as a property. Please do some debugging in your code. I hope you will find the problem asap.
Thanks.
Hello @subnaik,
If everything is ok that means you have registered the icon properly and added "assetupload#assetUploadButton" properly you can check this thing for you "icon" not showing issue
You may have a category for your custom RTE plugin
<?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"
allowProxy="{Boolean}true"
categories="[your.custom.rte-upload-plugin]"/>
You need to add this category into your "Text" component's dialog by extraClientlib
<?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"
extraClientlibs="[your.custom.rte-upload-plugin]">
@AsifChowdhury Thanks for your reply.
Now my icon is coming fine after I add below in category but my function is not working properly and upload asset is going to back , as shown below
Upload Asset is coming as below.
and getting below error in console for js.
var selection = CUI.rte.Selection.createProcessingSelection(context),
ek = this.editorKernel, startNode = selection.startNode;
Also can we call upload asset (dam library) under RTE Plugin in AEM 6.5 ?
It seems the problem is in your code. Maybe the "selection" is getting null so that "startNode" is not going to be read as a property. Please do some debugging in your code. I hope you will find the problem asap.
Thanks.
Views
Likes
Replies