Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -131,50 +131,48 @@
line-height: $line-height;
color: $color-palette-gray-700;
background-color: $white;
border: 0.0625rem;
border: $field-border-size solid
color-mix(in srgb, $color-palette-primary-500 20%, transparent);
border-radius: $border-radius-md;
cursor: pointer;
outline: none;
transition: border-color $basic-speed;
transition:
border-color $basic-speed,
box-shadow $basic-speed;
text-align: left;
position: relative;
box-shadow: inset 0 0 0 0.0625rem
color-mix(in srgb, $color-palette-primary-500 20%, transparent);
min-height: $field-height-md;
overflow: hidden;

&::after {
content: "";
.pi {
position: absolute;
right: 0;
top: 0;
bottom: 0;
height: 100%;
width: $field-height-md;
background-color: $color-palette-gray-100;
min-width: $field-height-md;
max-height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: $color-palette-gray-200;
color: $color-palette-primary;
border-left: $field-border-size solid $color-palette-gray-300;
border-top-right-radius: $border-radius-md;
border-bottom-right-radius: $border-radius-md;
background-image:
linear-gradient(45deg, transparent 50%, $color-palette-primary-500 50%),
linear-gradient(135deg, $color-palette-primary-500 50%, transparent 50%);
background-position:
calc(50% - 0.1875rem) calc(50% + 0.0625rem),
calc(50% + 0.125rem) calc(50% + 0.0625rem);
background-size:
0.3125rem 0.3125rem,
0.3125rem 0.3125rem;
background-repeat: no-repeat;
pointer-events: none;
font-size: $font-size-sm;
box-sizing: border-box;
}

&:focus {
border-color: $color-palette-primary-500;
box-shadow:
inset 0 0 0 0.0625rem
color-mix(in srgb, $color-palette-primary-500 30%, transparent),
0 0 0 0.125rem color-mix(in srgb, $color-palette-primary-500 10%, transparent);
border-color: $color-palette-primary-400;
box-shadow: 0 0 0 $spacing-xxs
color-mix(in srgb, $color-palette-primary-500 10%, transparent);
}

&:hover {
border-color: $color-palette-primary-500;
border-color: $color-palette-primary-400;
}

&.placeholder {
Expand All @@ -187,13 +185,13 @@
}
}

/* Dropdown panel: single block matching PrimeNG native select behavior */
.custom-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: $white;
border: 0.0625rem solid $color-palette-gray-400;
border-radius: $border-radius-md;
box-shadow:
0 0.25rem 0.375rem -0.0625rem rgba(0, 0, 0, 0.1),
Expand All @@ -203,9 +201,11 @@
overflow-y: auto;
z-index: 1000;
display: none;
padding: $spacing-0;

&.open {
display: block;
padding: $spacing-0 $spacing-1;
}

&::-webkit-scrollbar {
Expand All @@ -226,30 +226,29 @@
}
}

/* Options as list rows matching native select, no individual card styling */
.custom-option {
padding: $spacing-2 $spacing-3;
padding: $spacing-2 $spacing-2;
cursor: pointer;
border-bottom: 0.0625rem solid $color-palette-gray-100;
transition: background-color $basic-speed;

&:last-child {
border-bottom: none;
}
border: none;
border-radius: 0;
margin: 0;

&:hover {
background-color: $color-palette-gray-200;
background-color: $color-palette-primary-100;
}

&.selected {
background-color: $color-palette-blue-tint;
background-color: $color-palette-primary-200;
}
}

.option-title {
font-size: $font-size-md;
color: $color-palette-gray-700;
font-weight: 400;
margin-bottom: $spacing-0;
margin: 0;
}

.option-subtitle {
Expand All @@ -269,7 +268,7 @@
cursor: pointer;
color: $color-palette-gray-700;
font-size: $font-size-md;
border-top: 0.0625rem solid $color-palette-gray-200;
border-top: $field-border-size solid $color-palette-gray-200;
background-color: $white;
transition: background-color $basic-speed;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
<button
id="browseButton"
type="button"
class="p-button p-button-outlined bg-primary"
>
$text.get('click-here-to-browse')
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,18 @@
});
}

/**
* Sets the select button label (span only, keeps PrimeNG chevron icon)
*/
function setSelectButtonLabel(text) {
const labelSpan = getElement("templateSelectButtonLabel");
if (labelSpan) labelSpan.textContent = text;
else {
const button = getElement("customSelectButton");
if (button) button.textContent = text;
}
}

/**
* Updates the button text with selected template
*/
Expand All @@ -475,10 +487,10 @@
}

if (template && template.identifier !== ALL_SITES_IDENTIFIER) {
button.textContent = getCleanTitle(template);
setSelectButtonLabel(getCleanTitle(template));
button.classList.remove("placeholder");
} else {
button.textContent = ALL_SITES_TITLE;
setSelectButtonLabel(ALL_SITES_TITLE);
button.classList.add("placeholder");
}
}
Expand Down Expand Up @@ -588,16 +600,23 @@
return;
}

// Create custom select button
// Use existing button (from HTML with span + PrimeNG icon) or create fallback with same structure
let selectButton = getElement("customSelectButton");
if (!selectButton) {
selectButton = document.createElement("button");
selectButton.id = "customSelectButton";
selectButton.className = "custom-select-button placeholder";
selectButton.type = "button";
selectButton.textContent = ALL_SITES_TITLE;
selectButton.setAttribute("aria-label", "Select template");
selectButton.setAttribute("aria-haspopup", "listbox");
const labelSpan = document.createElement("span");
labelSpan.id = "templateSelectButtonLabel";
labelSpan.textContent = ALL_SITES_TITLE;
const icon = document.createElement("i");
icon.className = "pi pi-chevron-down";
icon.setAttribute("aria-hidden", "true");
selectButton.appendChild(labelSpan);
selectButton.appendChild(icon);
templateHolder.appendChild(selectButton);
}

Expand Down Expand Up @@ -809,7 +828,15 @@

<div class="custom-field-wrapper">
<div class="select-wrapper">
<div id="templateHolder"></div>
<div id="templateHolder">
<button
type="button"
id="customSelectButton"
class="custom-select-button placeholder"
aria-label="Select template"
aria-haspopup="listbox"
><span id="templateSelectButtonLabel">All Sites</span><i class="pi pi-chevron-down" aria-hidden="true"></i></button>
</div>
</div>

<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,30 @@
keyTagField.setValue(keyTagStr);
}

const labelEdit = editButton.dataset.labelEdit || editButton.textContent.trim();
const labelSave = editButton.dataset.labelSave || "Save";

function makeKeyTagEditable() {
keyTagWrapper.classList.remove("bg-surface-200");
keyTagWrapper.classList.remove("bg-gray-200");
keyTagWrapper.classList.add("bg-white");
showKeyTagInput.classList.remove("bg-gray-200");
showKeyTagInput.classList.add("bg-white");
showKeyTagInput.removeAttribute("readonly");
editButton.textContent = labelSave;
showKeyTagInput.focus();
}

function finalizeEdit() {
const myKeyTag = showKeyTagInput.value || "";
const keyTagStr = _camelizeMe(myKeyTag);
keyTagWrapper.classList.remove("bg-white");
keyTagWrapper.classList.add("bg-surface-200");
keyTagWrapper.classList.add("bg-gray-200");
showKeyTagInput.classList.remove("bg-white");
showKeyTagInput.classList.add("bg-gray-200");
showKeyTagInput.setAttribute("readonly", "true");
showKeyTagInput.value = keyTagStr;
keyTagField.setValue(keyTagStr);
editButton.textContent = labelEdit;
}

// When name field loses focus: if keyTag is empty, derive from name (same as title_custom_field_new / old onblur)
Expand Down Expand Up @@ -66,15 +75,24 @@
showKeyTagInput.value = initialValue;

showKeyTagInput.addEventListener("blur", finalizeEdit);
editButton.addEventListener("click", makeKeyTagEditable);
editButton.addEventListener("mousedown", (e) => {
e.preventDefault();
});
editButton.addEventListener("click", () => {
if (showKeyTagInput.hasAttribute("readonly")) {
makeKeyTagEditable();
} else {
finalizeEdit();
}
});
});
</script>

<div class="flex gap-2 align-items-center w-full">
<div id="keyTagWrapper" class="flex-1 min-w-0 border-1 border-round border-gray-400 bg-surface-200 font-bold white-space-nowrap">
<input type="text" id="showKeyTag" readonly="true" class="w-full border-none bg-transparent outline-none" placeholder="">
<div id="keyTagWrapper" class="flex-1 min-w-0 border-1 border-round border-gray-400 bg-gray-200 font-bold white-space-nowrap">
<input type="text" id="showKeyTag" readonly="true" class="w-full border-none bg-gray-200 outline-none" placeholder="">
</div>
<button id="keyTagEditButton" type="button" >
<button id="keyTagEditButton" type="button" data-label-edit="$text.get('Edit')" data-label-save="$text.get('Save')">
$text.get("Edit")
</button>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
aria-haspopup="listbox"
aria-expanded="false"
#if($isCopyingHost && $UtilMethods.isSet($tagStorageFromURL)) disabled="disabled" #end
>Select host</button>
><span id="tagStorageLabelSpan">Select host</span><i class="pi pi-chevron-down" aria-hidden="true"></i></button>
<div id="tagStorageDropdown" class="custom-dropdown" role="listbox">
#foreach($c in $tagStorageHostList)
#if($c.isSystemHost)
Expand Down Expand Up @@ -66,20 +66,21 @@
const button = document.getElementById("tagStorageSelectButton");
const dropdown = document.getElementById("tagStorageDropdown");
if (!holder || !button || !dropdown) return;
const defaultLabel = (button.textContent || "").trim();
const labelSpan = document.getElementById("tagStorageLabelSpan");
const defaultLabel = labelSpan ? (labelSpan.textContent || "").trim() : "";

const options = Array.from(dropdown.querySelectorAll(".custom-option"));
let selectedOption = dropdown.querySelector(".custom-option.selected");
const currentValue = field ? (field.getValue() || "") : "";
if (selectedOption && selectedOption.dataset.label) {
button.textContent = selectedOption.dataset.label;
if (labelSpan) labelSpan.textContent = selectedOption.dataset.label;
button.classList.remove("placeholder");
} else if (currentValue && options.length) {
const match = options.find(function(o) { return o.dataset.identifier === currentValue; });
if (match) {
match.classList.add("selected");
match.setAttribute("aria-selected", "true");
button.textContent = match.dataset.label || defaultLabel;
if (labelSpan) labelSpan.textContent = match.dataset.label || defaultLabel;
button.classList.remove("placeholder");
selectedOption = match;
}
Expand Down Expand Up @@ -121,7 +122,7 @@
const identifier = this.dataset.identifier;
const label = this.dataset.label;
if (field) field.setValue(identifier || "");
button.textContent = label || defaultLabel;
if (labelSpan) labelSpan.textContent = label || defaultLabel;
button.classList.remove("placeholder");
options.forEach(function(o) { o.classList.remove("selected"); });
this.classList.add("selected");
Expand Down
Loading