fix wpcfto select and repeater related visibility and validation
This commit is contained in:
17
vendor/wpcfto/metaboxes/assets/js/metaboxes.js
vendored
17
vendor/wpcfto/metaboxes/assets/js/metaboxes.js
vendored
@@ -126,9 +126,18 @@
|
||||
if ($boxChild.hasClass('repeater')) {
|
||||
// Repeater parent label (the field label for the repeater itself)
|
||||
const parentLabel = ($boxChild.find('.wpcfto-field-aside__label span:first-child').first().text() || '').trim();
|
||||
|
||||
// checker for the parent itself
|
||||
if($boxChild.find('.wpcfto-repeater-single').length == 0){
|
||||
|
||||
// Determine if this repeater is required.
|
||||
// We prefer presence of the hidden proxy input (rendered only when required).
|
||||
// Fallback: a data attribute marker if used by templates.
|
||||
const isRequiredRepeater = (
|
||||
$boxChild.find('.wpcfto-required-proxy').length > 0 ||
|
||||
$boxChild.is('[data-required="true"]')
|
||||
);
|
||||
|
||||
// Parent-level empty check: only flag when the repeater itself is required
|
||||
const hasRows = $boxChild.find('.wpcfto-repeater-single').length > 0;
|
||||
if (isRequiredRepeater && !hasRows) {
|
||||
invalid.push({
|
||||
id: fieldId,
|
||||
tab: tabTitle,
|
||||
@@ -137,6 +146,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Child-level checks: scan only inputs that explicitly declare [required]
|
||||
$boxChild.find('.wpcfto-repeater-single').each(function (idx) {
|
||||
const $item = $(this);
|
||||
|
||||
@@ -156,6 +166,7 @@
|
||||
}
|
||||
if (!repeaterLabel) repeaterLabel = `Item #${idx+1}`;
|
||||
|
||||
// Only required child fields should be considered invalid when empty
|
||||
$item.find('input, textarea, select').filter('[required]').each(function () {
|
||||
const $f = $(this);
|
||||
if (isRequiredEmpty($f)) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
window.validationMixin = {
|
||||
methods: {
|
||||
// --- Helpers
|
||||
@@ -24,6 +23,12 @@ window.validationMixin = {
|
||||
if (Array.isArray(a) || Array.isArray(b)) return JSON.stringify(a) === JSON.stringify(b);
|
||||
return String(a) == String(b);
|
||||
},
|
||||
_coalesceValue() {
|
||||
// Prefer prop field_value if present; otherwise fall back to instance `value`
|
||||
if (typeof this.field_value !== 'undefined') return this.field_value;
|
||||
if (typeof this.value !== 'undefined') return this.value;
|
||||
return undefined;
|
||||
},
|
||||
|
||||
// --- Visibility according to dependencies
|
||||
isVisible() {
|
||||
@@ -56,7 +61,7 @@ window.validationMixin = {
|
||||
const visible = this.isVisible();
|
||||
const required = 'required' in this.fields && this.fields.required === true;
|
||||
const type = this.fields.type || '';
|
||||
const value = this.field_value;
|
||||
const value = this._coalesceValue();
|
||||
|
||||
let filled;
|
||||
if (!required) {
|
||||
@@ -66,8 +71,18 @@ window.validationMixin = {
|
||||
filled = true;
|
||||
} else if (type === 'checkbox') {
|
||||
filled = value === 1 || value === true || value === '1' || value === 'true';
|
||||
} else if (type === 'repeater' && required) {
|
||||
filled = this.fields.value && this.fields.value.length > 0;
|
||||
} else if (type === 'repeater') {
|
||||
if (!required) {
|
||||
filled = true; // optional repeater: always valid
|
||||
} else {
|
||||
// Prefer the component's live repeater array; fallback to value/field_value
|
||||
const list = Array.isArray(this.repeater)
|
||||
? this.repeater
|
||||
: (Array.isArray(value)
|
||||
? value
|
||||
: (this.fields && Array.isArray(this.fields.value) ? this.fields.value : []));
|
||||
filled = list.length > 0;
|
||||
}
|
||||
} else if (Array.isArray(value)) {
|
||||
filled = value.length > 0;
|
||||
} else if (typeof value === 'number') {
|
||||
@@ -95,6 +110,11 @@ window.validationMixin = {
|
||||
if (typeof this.validateField === 'function') {
|
||||
this.validateField();
|
||||
}
|
||||
},
|
||||
value() {
|
||||
if (typeof this.validateField === 'function') {
|
||||
this.validateField();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user