Skip to content

Commit 62bf2a0

Browse files
committed
feat: Improve event delegation for conditional logic and enhance field input checks
1 parent f2573d4 commit 62bf2a0

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

plugin/assets/admin/css/fields.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,6 @@
325325
.openfields-switch-checkbox:disabled + .openfields-switch-container {
326326
opacity: 0.5;
327327
cursor: not-allowed;
328-
}
329-
cursor: not-allowed;
330328
background: #ccc;
331329
border-color: #ccc;
332330
}

plugin/assets/admin/js/fields.js

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -467,20 +467,52 @@
467467
* Setup event listeners for conditional logic evaluation.
468468
*/
469469
setupConditionalListeners() {
470-
const formInputs = document.querySelectorAll(
471-
'.openfields-meta-box input, .openfields-meta-box select, .openfields-meta-box textarea'
472-
);
470+
// Use event delegation on meta-box wrapper so new repeater rows trigger updates too
471+
const metaBox = document.querySelector('.openfields-meta-box');
472+
if (!metaBox) return;
473+
474+
// Single listener on parent element catches all bubbling change/input events
475+
metaBox.addEventListener('change', (e) => {
476+
// Check if this is a field input that should trigger conditional evaluation
477+
const target = e.target;
478+
if (this.isFieldInput(target)) {
479+
this.evaluateAllConditions();
480+
}
481+
}, true); // Use capture phase to catch all events
473482

474-
formInputs.forEach(input => {
475-
// Skip if already initialized to prevent duplicate event listeners.
476-
if (input.dataset.ofConditionalInitialized) {
477-
return;
483+
metaBox.addEventListener('input', (e) => {
484+
const target = e.target;
485+
if (this.isFieldInput(target)) {
486+
this.evaluateAllConditions();
478487
}
479-
input.dataset.ofConditionalInitialized = 'true';
488+
}, true); // Use capture phase
489+
},
480490

481-
input.addEventListener('change', () => this.evaluateAllConditions());
482-
input.addEventListener('input', () => this.evaluateAllConditions());
483-
});
491+
/**
492+
* Check if an element is a field input that should trigger conditional evaluation.
493+
*
494+
* @param {HTMLElement} element - The element to check.
495+
* @returns {boolean} Whether this is a field input.
496+
*/
497+
isFieldInput(element) {
498+
// Check if it's an input, select, or textarea
499+
if (!element || !element.tagName) return false;
500+
501+
const tag = element.tagName.toLowerCase();
502+
if (['input', 'select', 'textarea'].includes(tag)) {
503+
return true;
504+
}
505+
506+
// Check if it's a switch or custom field input
507+
if (element.classList && (
508+
element.classList.contains('openfields-switch-checkbox') ||
509+
element.classList.contains('openfields-toggle-input') ||
510+
element.classList.contains('openfields-field-input')
511+
)) {
512+
return true;
513+
}
514+
515+
return false;
484516
},
485517

486518
/**
@@ -568,11 +600,21 @@
568600

569601
// rule.field is now a FIELD ID (immutable UUID/identifier)
570602
// Look for any field with data-field-id attribute matching this ID
571-
// This works for: root fields, repeater subfields, group subfields, anywhere
603+
// This works for: root fields, repeater subfields, group subfields, anywhere in the DOM
572604
const fieldId = rule.field;
573605
let fieldElement = document.querySelector(`[data-field-id="${fieldId}"]`);
574606

607+
if (fieldElement) {
608+
// Found by field ID - this is the preferred method
609+
// Look for the actual input element within this wrapper
610+
const input = fieldElement.querySelector('input, select, textarea');
611+
if (input) {
612+
fieldElement = input;
613+
}
614+
}
615+
575616
// Fallback: try to find by field name (backwards compatibility)
617+
// This is for fields created before data-field-id was implemented
576618
if (!fieldElement) {
577619
const fieldName = rule.field;
578620
fieldElement = document.querySelector(
@@ -584,7 +626,7 @@
584626

585627
if (!fieldElement) {
586628
console.warn(`[OpenFields] Conditional field not found: ${fieldId}`);
587-
return true; // If field not found, don't block.
629+
return true; // If field not found, don't block (assume condition passes).
588630
}
589631

590632
const currentValue = this.getFieldValue(fieldElement);

0 commit comments

Comments
 (0)