Nível 1
Nível 2
Faça login na Comunidade
Faça logon para exibir todas as medalhas
Hi,
I have a component with a select field inside one of its dialog tabs. Authors need to change this value often, and opening the dialog every time is slow.
Is it possible to add a custom dropdown directly in the component’s toolbar (similar to the Styles button), where the dropdown shows the same options as the dialog’s select field and updates the JCR property when changed?
Basically: can a toolbar action render a dropdown instead of a button, and change a component property immediately?
Any guidance or examples would help. Thanks!
Solucionado! Ir para a Solução.
Visualizações
respostas
Total de curtidas
hi @JulioRo,
by following this guide here I've implemented what you asked. You've to create a clientlib:
<?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="[cq.authoring.dialog.all]"/>then as JS code (replace "example/components/hello" with yours):
(function (window, $, Coral, $document, author) {
"use strict";
var POPOVER_ID = "my-dropdown-popover";
// Define the toolbar action
var dropdownAction = {
icon: 'coral-Icon--game',
id: 'dropdown-action-id',
text: 'Select Option',
handler: function (editable, param, target) {
var $popover = new Coral.Popover().set({
id: POPOVER_ID,
alignAt: Coral.Overlay.align.CENTER_BOTTOM,
alignMy: Coral.Overlay.align.CENTER_TOP,
target: target[0] // Attach to the toolbar button
});
// Create the Select component
var select = new Coral.Select();
select.placeholder = "Select an option";
var options = [
{ value: "option1", content: { innerHTML: "Option 1" } },
{ value: "option2", content: { innerHTML: "Option 2" } },
{ value: "option3", content: { innerHTML: "Option 3" } }
];
options.forEach(function (opt) {
var item = new Coral.Select.Item();
item.value = opt.value;
item.content.innerHTML = opt.content.innerHTML;
select.items.add(item);
});
// Fetch current value
$.ajax({
url: editable.path + ".json",
cache: false
}).done(function (data) {
if (data && data.selectField) {
select.value = data.selectField;
}
});
// Handle change
select.on('change', function () {
var value = select.value;
if (value) {
$.ajax({
url: editable.path,
type: 'POST',
data: { "./selectField": value }
}).done(function () {
// Close the popover
$popover.open = true;
// Refresh only the component
editable.refresh();
});
}
});
$popover.appendChild(select);
document.body.appendChild($popover);
// Toggle visibility
$popover.open = !$popover.open;
},
condition: function (editable) {
return editable.type === "example/components/hello";
},
isNonMulti: true
};
// Register the action
$document.on('cq-layer-activated', function (ev) {
if (ev.layer === 'Edit') {
author.EditorFrame.editableToolbar.registerAction('MY_DROPDOWN_ACTION', dropdownAction);
}
});
})(window, Granite.$, Coral, $(document), Granite.author);This will give you a new button:
Once clicked, you will see the popup:
The element is positioned at the top of the window, quite far from the toolbar. I attempted to set the target variable, but it didn't work. I understand that this isn't the ideal solution, so I'll leave it to you to correct this properly by making adjustments to the provided JavaScript.
hi @JulioRo,
by following this guide here I've implemented what you asked. You've to create a clientlib:
<?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="[cq.authoring.dialog.all]"/>then as JS code (replace "example/components/hello" with yours):
(function (window, $, Coral, $document, author) {
"use strict";
var POPOVER_ID = "my-dropdown-popover";
// Define the toolbar action
var dropdownAction = {
icon: 'coral-Icon--game',
id: 'dropdown-action-id',
text: 'Select Option',
handler: function (editable, param, target) {
var $popover = new Coral.Popover().set({
id: POPOVER_ID,
alignAt: Coral.Overlay.align.CENTER_BOTTOM,
alignMy: Coral.Overlay.align.CENTER_TOP,
target: target[0] // Attach to the toolbar button
});
// Create the Select component
var select = new Coral.Select();
select.placeholder = "Select an option";
var options = [
{ value: "option1", content: { innerHTML: "Option 1" } },
{ value: "option2", content: { innerHTML: "Option 2" } },
{ value: "option3", content: { innerHTML: "Option 3" } }
];
options.forEach(function (opt) {
var item = new Coral.Select.Item();
item.value = opt.value;
item.content.innerHTML = opt.content.innerHTML;
select.items.add(item);
});
// Fetch current value
$.ajax({
url: editable.path + ".json",
cache: false
}).done(function (data) {
if (data && data.selectField) {
select.value = data.selectField;
}
});
// Handle change
select.on('change', function () {
var value = select.value;
if (value) {
$.ajax({
url: editable.path,
type: 'POST',
data: { "./selectField": value }
}).done(function () {
// Close the popover
$popover.open = true;
// Refresh only the component
editable.refresh();
});
}
});
$popover.appendChild(select);
document.body.appendChild($popover);
// Toggle visibility
$popover.open = !$popover.open;
},
condition: function (editable) {
return editable.type === "example/components/hello";
},
isNonMulti: true
};
// Register the action
$document.on('cq-layer-activated', function (ev) {
if (ev.layer === 'Edit') {
author.EditorFrame.editableToolbar.registerAction('MY_DROPDOWN_ACTION', dropdownAction);
}
});
})(window, Granite.$, Coral, $(document), Granite.author);This will give you a new button:
Once clicked, you will see the popup:
The element is positioned at the top of the window, quite far from the toolbar. I attempted to set the target variable, but it didn't work. I understand that this isn't the ideal solution, so I'll leave it to you to correct this properly by making adjustments to the provided JavaScript.
Visualizações
Curtida
respostas