TKK_E32230273/custom_tooltip.php

162 lines
5.5 KiB
PHP

<style>
/* Global Custom Tooltip for Form Validation */
#global-required-tooltip {
position: absolute;
background-color: white;
color: #333;
padding: 8px 15px;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
font-size: 14px;
white-space: nowrap;
z-index: 99999;
border: 1px solid #ddd;
display: none;
align-items: center;
gap: 8px;
pointer-events: none;
transform: translateX(-50%);
}
#global-required-tooltip::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border-width: 8px;
border-style: solid;
border-color: transparent transparent #ddd transparent;
}
#global-required-tooltip::after {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border-width: 7px;
border-style: solid;
border-color: transparent transparent white transparent;
}
#global-required-tooltip .error-icon {
background-color: #ff9800;
color: white;
width: 20px;
height: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 3px;
font-weight: bold;
font-family: serif;
}
</style>
<div id="global-required-tooltip">
<span class="error-icon">!</span>
<span id="global-required-text">Please fill out this field.</span>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const tooltip = document.getElementById('global-required-tooltip');
const tooltipText = document.getElementById('global-required-text');
let activeInput = null;
function hideTooltip() {
tooltip.style.display = 'none';
activeInput = null;
}
// Capture the 'invalid' event on all inputs within the document
document.addEventListener('invalid', function(e) {
e.preventDefault(); // Prevent native browser tooltip from showing
const target = e.target;
if (!target) return;
// Default to English text for various validation scenarios
let message = "Please fill out this field.";
if (target.validity.valueMissing) {
if (target.type === 'checkbox') {
message = "Please check this box if you want to proceed.";
} else if (target.type === 'radio') {
message = "Please select one of these options.";
} else {
message = "Please fill out this field.";
}
} else if (target.validity.typeMismatch) {
if (target.type === 'email') {
message = "Please enter an email address.";
} else if (target.type === 'url') {
message = "Please enter a URL.";
} else {
message = "Invalid value.";
}
} else if (target.validity.tooShort) {
message = "Please lengthen this text to " + target.getAttribute('minlength') + " characters or more.";
} else if (target.validity.tooLong) {
message = "Please shorten this text to no more than " + target.getAttribute('maxlength') + " characters.";
} else if (target.validity.patternMismatch) {
message = target.title || "Please match the requested format.";
}
// If there's a custom validity set by JS, use it instead
if (target.validity.customError && target.validationMessage) {
message = target.validationMessage;
}
tooltipText.textContent = message;
tooltip.style.display = 'flex';
// Calculate position based on the input element's bounds
const rect = target.getBoundingClientRect();
const topPos = rect.bottom + window.scrollY + 8;
const leftPos = rect.left + window.scrollX + (rect.width / 2);
tooltip.style.top = topPos + 'px';
tooltip.style.left = leftPos + 'px';
activeInput = target;
// Ensure input is focused and scrolled into view safely
if (document.activeElement !== target) {
target.focus({ preventScroll: true });
}
}, true);
// Hide tooltip dynamically as soon as the user interacts and validates the field
document.addEventListener('input', function(e) {
if (activeInput && e.target === activeInput) {
if (activeInput.validity.valid) {
hideTooltip();
}
}
});
// Hide tooltip when clicking anywhere outside the active input
document.addEventListener('mousedown', function(e) {
if (tooltip.style.display === 'flex' && e.target !== activeInput && !tooltip.contains(e.target)) {
hideTooltip();
}
});
// Keep tooltip positioned correctly on resize
window.addEventListener('resize', function() {
if (tooltip.style.display === 'flex' && activeInput) {
const rect = activeInput.getBoundingClientRect();
const topPos = rect.bottom + window.scrollY + 8;
const leftPos = rect.left + window.scrollX + (rect.width / 2);
tooltip.style.top = topPos + 'px';
tooltip.style.left = leftPos + 'px';
}
});
// Hide when scrolling for safety
document.addEventListener('scroll', function() {
if (tooltip.style.display === 'flex') {
hideTooltip();
}
}, true);
});
</script>