Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,62 @@ Vue.component('builder-stage-v4-1', {
comp.openFieldPicker();
}
},

/**
* Filter CSS classes to prevent hiding fields in the builder
* Removes classes that would make the field invisible or hidden in the backend
* while preserving them for frontend rendering
*
* @param {string} cssClasses - Space-separated CSS class names
* @return {string} Filtered CSS classes safe for builder
*/
filter_builder_css_classes: function(cssClasses) {
if (!cssClasses || typeof cssClasses !== 'string') {
return '';
}

// List of CSS classes that should not be applied in the builder
// These classes would hide or make fields invisible in the backend
var forbiddenClasses = [
'hidden', // Tailwind: display: none
'd-none', // Bootstrap: display: none
'hide', // Generic hide class
'invisible', // Tailwind: visibility: hidden
'opacity-0', // Tailwind: opacity: 0 (could make field uneditable)
'sr-only', // Screen reader only
'visually-hidden', // Bootstrap screen reader only
];

// Split classes, filter out forbidden ones, and rejoin
var classes = cssClasses.split(/\s+/).filter(function(className) {
return className && forbiddenClasses.indexOf(className.toLowerCase()) === -1;
});

return classes.join(' ');
},

/**
* Check if field has CSS classes that would hide it on the frontend
* Used to display a visual indicator in the builder
*
* @param {string} cssClasses - Space-separated CSS class names
* @return {boolean} True if field has hiding CSS classes
*/
has_hidden_css_class: function(cssClasses) {
if (!cssClasses || typeof cssClasses !== 'string') {
return false;
}

var hiddenClasses = ['hidden', 'd-none', 'hide', 'invisible'];
var classes = cssClasses.toLowerCase().split(/\s+/);

for (var i = 0; i < hiddenClasses.length; i++) {
if (classes.indexOf(hiddenClasses[i]) !== -1) {
return true;
}
}

return false;
},
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class="wpuf-form sortable-list wpuf-py-8">
:data-index="index"
data-source="stage"
:class="[
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template,
'field-items', 'wpuf-el', field.name, filter_builder_css_classes(field.css), 'form-field-' + field.template,
field.width ? 'field-size-' + field.width : '',
('custom_hidden_field' === field.template) ? 'hidden-field' : ''
]"
Expand All @@ -24,7 +24,7 @@ class="wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-d
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-bg-green-50 wpuf-border-green-400' : 'wpuf-border-transparent'"
class="wpuf-flex wpuf-justify-between wpuf-p-6 wpuf-rounded-t-md wpuf-border-t wpuf-border-r wpuf-border-l wpuf-border-dashed group-hover:wpuf-border-green-400 group-hover:wpuf-cursor-pointer !wpuf-pb-3">
<div v-if="!(is_full_width(field.template) || is_pro_preview(field.template))" class="wpuf-w-1/4 wpuf-flex wpuf-items-center">
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'left_label'"
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'left_label'"
class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-mr-1">
<i :class="[field.field_icon, 'wpuf-field-icon']"></i>
</span>
Expand All @@ -34,8 +34,16 @@ class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-mr-1">
class="wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900">
{{ field.label }} <span v-if="field.required && 'yes' === field.required"
class="required">*</span>
<span v-if="has_hidden_css_class(field.css)"
class="wpuf-inline-flex wpuf-items-center wpuf-ml-2 wpuf-px-2 wpuf-py-0.5 wpuf-rounded wpuf-text-xs wpuf-font-medium wpuf-bg-yellow-100 wpuf-text-yellow-800 wpuf-border wpuf-border-yellow-300"
title="This field will be hidden on the frontend due to CSS class">
<svg class="wpuf-w-3 wpuf-h-3 wpuf-mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path>
</svg>
Hidden on frontend
</span>
</label>
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'right_label'"
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'right_label'"
class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-ml-2">
<i :class="[field.field_icon, 'wpuf-field-icon']"></i>
</span>
Expand Down
21 changes: 21 additions & 0 deletions assets/css/frontend-forms.css
Original file line number Diff line number Diff line change
Expand Up @@ -1794,3 +1794,24 @@ img.wpuf-eye {
top: 50%;
transform: translateY(-50%) translateX(-6%);
}
/* CSS utility classes for hiding fields on frontend */
.wpuf-form .hidden,
.wpuf-form .d-none,
.wpuf-form .hide {
display: none !important;
}
.wpuf-form .invisible {
visibility: hidden !important;
}
.wpuf-form .sr-only,
.wpuf-form .visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
14 changes: 11 additions & 3 deletions assets/js-templates/form-components.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class="wpuf-form sortable-list wpuf-py-8">
:data-index="index"
data-source="stage"
:class="[
'field-items', 'wpuf-el', field.name, field.css, 'form-field-' + field.template,
'field-items', 'wpuf-el', field.name, filter_builder_css_classes(field.css), 'form-field-' + field.template,
field.width ? 'field-size-' + field.width : '',
('custom_hidden_field' === field.template) ? 'hidden-field' : ''
]"
Expand All @@ -117,7 +117,7 @@ class="wpuf-group wpuf-rounded-lg hover:!wpuf-bg-green-50 wpuf-transition wpuf-d
:class="parseInt(editing_form_id) === parseInt(field.id) ? 'wpuf-bg-green-50 wpuf-border-green-400' : 'wpuf-border-transparent'"
class="wpuf-flex wpuf-justify-between wpuf-p-6 wpuf-rounded-t-md wpuf-border-t wpuf-border-r wpuf-border-l wpuf-border-dashed group-hover:wpuf-border-green-400 group-hover:wpuf-cursor-pointer !wpuf-pb-3">
<div v-if="!(is_full_width(field.template) || is_pro_preview(field.template))" class="wpuf-w-1/4 wpuf-flex wpuf-items-center">
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'left_label'"
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'left_label'"
class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-mr-1">
<i :class="[field.field_icon, 'wpuf-field-icon']"></i>
</span>
Expand All @@ -127,8 +127,16 @@ class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-mr-1">
class="wpuf-block wpuf-text-sm wpuf-font-medium wpuf-leading-6 wpuf-text-gray-900">
{{ field.label }} <span v-if="field.required && 'yes' === field.required"
class="required">*</span>
<span v-if="has_hidden_css_class(field.css)"
class="wpuf-inline-flex wpuf-items-center wpuf-ml-2 wpuf-px-2 wpuf-py-0.5 wpuf-rounded wpuf-text-xs wpuf-font-medium wpuf-bg-yellow-100 wpuf-text-yellow-800 wpuf-border wpuf-border-yellow-300"
title="This field will be hidden on the frontend due to CSS class">
<svg class="wpuf-w-3 wpuf-h-3 wpuf-mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path>
</svg>
Hidden on frontend
</span>
</label>
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'right_label'"
<span v-if="field.show_icon === 'yes' && field.field_icon && field.icon_position === 'right_label'"
class="wpuf-field-label-icon wpuf-inline-flex wpuf-items-center wpuf-ml-2">
<i :class="[field.field_icon, 'wpuf-field-icon']"></i>
</span>
Expand Down
57 changes: 57 additions & 0 deletions assets/js/wpuf-form-builder-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,63 @@ Vue.component('builder-stage-v4-1', {
comp.openFieldPicker();
}
},

/**
* Filter CSS classes to prevent hiding fields in the builder
* Removes classes that would make the field invisible or hidden in the backend
* while preserving them for frontend rendering
*
* @param {string} cssClasses - Space-separated CSS class names
* @return {string} Filtered CSS classes safe for builder
*/
filter_builder_css_classes: function(cssClasses) {
if (!cssClasses || typeof cssClasses !== 'string') {
return '';
}

// List of CSS classes that should not be applied in the builder
// These classes would hide or make fields invisible in the backend
var forbiddenClasses = [
'hidden', // Tailwind: display: none
'd-none', // Bootstrap: display: none
'hide', // Generic hide class
'invisible', // Tailwind: visibility: hidden
'opacity-0', // Tailwind: opacity: 0 (could make field uneditable)
'sr-only', // Screen reader only
'visually-hidden', // Bootstrap screen reader only
];

// Split classes, filter out forbidden ones, and rejoin
var classes = cssClasses.split(/\s+/).filter(function(className) {
return className && forbiddenClasses.indexOf(className.toLowerCase()) === -1;
});

return classes.join(' ');
},

/**
* Check if field has CSS classes that would hide it on the frontend
* Used to display a visual indicator in the builder
*
* @param {string} cssClasses - Space-separated CSS class names
* @return {boolean} True if field has hiding CSS classes
*/
has_hidden_css_class: function(cssClasses) {
if (!cssClasses || typeof cssClasses !== 'string') {
return false;
}

var hiddenClasses = ['hidden', 'd-none', 'hide', 'invisible'];
var classes = cssClasses.toLowerCase().split(/\s+/);

for (var i = 0; i < hiddenClasses.length; i++) {
if (classes.indexOf(hiddenClasses[i]) !== -1) {
return true;
}
}

return false;
},
}
});

Expand Down
26 changes: 26 additions & 0 deletions assets/less/frontend-forms.less
Original file line number Diff line number Diff line change
Expand Up @@ -2086,3 +2086,29 @@ img.wpuf-eye {
top: 50%;
transform: translateY(-50%) translateX(-6%);
}

/* CSS utility classes for hiding fields on frontend */
.wpuf-form {
.hidden,
.d-none,
.hide {
display: none !important;
}

.invisible {
visibility: hidden !important;
}

.sr-only,
.visually-hidden {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0, 0, 0, 0) !important;
white-space: nowrap !important;
border: 0 !important;
}
}
Loading