diff --git a/admin/form-builder/assets/js/components/builder-stage-v4-1/template.php b/admin/form-builder/assets/js/components/builder-stage-v4-1/template.php
index 0399eeaff..91635c9c6 100644
--- a/admin/form-builder/assets/js/components/builder-stage-v4-1/template.php
+++ b/admin/form-builder/assets/js/components/builder-stage-v4-1/template.php
@@ -24,6 +24,10 @@ 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">
+
+
+
-
+
+
diff --git a/admin/form-builder/assets/js/components/field-icon_selector/index.js b/admin/form-builder/assets/js/components/field-icon_selector/index.js
new file mode 100644
index 000000000..86bec5327
--- /dev/null
+++ b/admin/form-builder/assets/js/components/field-icon_selector/index.js
@@ -0,0 +1,109 @@
+Vue.component('field-icon_selector', {
+ template: '#tmpl-wpuf-field-icon_selector',
+
+ mixins: [
+ wpuf_mixins.option_field_mixin
+ ],
+
+ mounted: function() {
+ document.addEventListener('click', this.handleClickOutside);
+ },
+
+ data: function () {
+ return {
+ showIconPicker: false,
+ searchTerm: '',
+ icons: wpuf_form_builder.icons || []
+ };
+ },
+
+ computed: {
+ value: {
+ get: function () {
+ return this.editing_form_field[this.option_field.name];
+ },
+
+ set: function (value) {
+ this.$store.commit('update_editing_form_field', {
+ editing_field_id: this.editing_form_field.id,
+ field_name: this.option_field.name,
+ value: value
+ });
+ }
+ },
+
+ selectedIconDisplay: function() {
+ if (this.value) {
+ var icon = this.icons.find(function(item) {
+ return item.class === this.value;
+ }.bind(this));
+ return icon ? icon.name : this.value;
+ }
+ return 'Select an icon';
+ },
+
+ filteredIcons: function() {
+ var self = this;
+ if (!this.icons.length) return [];
+
+ if (!this.searchTerm) return this.icons;
+
+ var searchLower = this.searchTerm.toLowerCase();
+ return this.icons.filter(function(icon) {
+ return icon.name.toLowerCase().indexOf(searchLower) !== -1 ||
+ icon.keywords.toLowerCase().indexOf(searchLower) !== -1;
+ });
+ }
+ },
+
+ watch: {
+ 'editing_form_field.show_icon': function(newVal, oldVal) {
+ // When show_icon changes from 'no' to 'yes' and field_icon is empty or 'fas fa-0'
+ if (newVal === 'yes' && oldVal === 'no') {
+ if (!this.editing_form_field.field_icon || this.editing_form_field.field_icon === 'fas fa-0') {
+ // Set a proper default icon based on field type
+ var defaultIcons = wpuf_form_builder.defaultIcons || {};
+
+ // Get the field type/template
+ var fieldType = this.editing_form_field.template || this.editing_form_field.input_type || 'text';
+
+ // Set the default icon based on field type
+ var defaultIcon = defaultIcons[fieldType] || 'fa-solid fa-circle';
+
+ this.$store.commit('update_editing_form_field', {
+ editing_field_id: this.editing_form_field.id,
+ field_name: 'field_icon',
+ value: defaultIcon
+ });
+ }
+ }
+ }
+ },
+
+ methods: {
+
+ selectIcon: function(iconClass) {
+ this.value = iconClass;
+ this.showIconPicker = false;
+ },
+
+ clearIcon: function() {
+ this.value = '';
+ this.showIconPicker = false;
+ },
+
+ togglePicker: function() {
+ this.showIconPicker = !this.showIconPicker;
+ },
+
+ handleClickOutside: function(event) {
+ if (!this.$el.contains(event.target)) {
+ this.showIconPicker = false;
+ }
+ }
+ },
+
+ beforeDestroy: function() {
+ document.removeEventListener('click', this.handleClickOutside);
+ }
+});
\ No newline at end of file
diff --git a/admin/form-builder/assets/js/components/field-icon_selector/template.php b/admin/form-builder/assets/js/components/field-icon_selector/template.php
new file mode 100644
index 000000000..a6dec63e9
--- /dev/null
+++ b/admin/form-builder/assets/js/components/field-icon_selector/template.php
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+ {{ selectedIconDisplay }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ filteredIcons.length }} icons {{ searchTerm ? 'found' : 'available' }}
+
+
+
+
+
+
+
+
+
+
+
🔍 No icons found
+
Try searching with different keywords like "user", "email", "home"
+
+
+
+
+
\ No newline at end of file
diff --git a/admin/form-builder/assets/js/components/field-radio/template.php b/admin/form-builder/assets/js/components/field-radio/template.php
index 70d21c971..01980f9f3 100644
--- a/admin/form-builder/assets/js/components/field-radio/template.php
+++ b/admin/form-builder/assets/js/components/field-radio/template.php
@@ -17,7 +17,6 @@ class="wpuf-block text-sm/6 wpuf-font-medium wpuf-text-gray-900 !wpuf-mb-0">
type="radio"
:name="'radio_' + editing_form_field.id + '_' + option_field.name"
:value="key"
- :name="option_field.name"
v-model="value"
:class="builder_class_names('radio')">
{{ option }}
@@ -35,7 +34,6 @@ class="wpuf-flex wpuf-items-center"
:name="'radio_' + editing_form_field.id + '_' + option_field.name"
:value="key"
v-model="value"
- :name="option_field.name"
:class="builder_class_names('radio')">
{{ option }}
diff --git a/admin/form-builder/assets/js/form-builder.js b/admin/form-builder/assets/js/form-builder.js
index b4b9211a2..0ccb4a250 100644
--- a/admin/form-builder/assets/js/form-builder.js
+++ b/admin/form-builder/assets/js/form-builder.js
@@ -185,6 +185,16 @@
// add new form field element
add_form_field_element: function (state, payload) {
+ // Initialize icon properties for new fields to ensure Vue reactivity
+ if (!payload.field.hasOwnProperty('show_icon')) {
+ payload.field.show_icon = 'no';
+ }
+ if (!payload.field.hasOwnProperty('field_icon')) {
+ payload.field.field_icon = '';
+ }
+ if (!payload.field.hasOwnProperty('icon_position')) {
+ payload.field.icon_position = 'left_label';
+ }
state.form_fields.splice(payload.toIndex, 0, payload.field);
var sprintf = wp.i18n.sprintf;
@@ -729,6 +739,24 @@
},
mounted: function () {
+ // Ensure all fields have proper default values for icon settings when editing existing forms
+ this.$store.state.form_fields.forEach(function(field) {
+ // If show_icon is not set in the database, default it to 'no'
+ if (field.show_icon === undefined || field.show_icon === null) {
+ field.show_icon = 'no';
+ }
+
+ // If field_icon is not set in the database, set it to default icon fas fa-0
+ if (field.field_icon === undefined || field.field_icon === null) {
+ field.field_icon = 'fas fa-0';
+ }
+
+ // If icon_position is not set, default it to 'left_label'
+ if (field.icon_position === undefined || field.icon_position === null) {
+ field.icon_position = 'left_label';
+ }
+ });
+
// Check if there are hidden custom taxonomy fields and show warning
if (wpuf_form_builder.has_hidden_taxonomies && !wpuf_form_builder.is_pro_active) {
var self = this;
diff --git a/admin/form-builder/assets/less/form-builder.less b/admin/form-builder/assets/less/form-builder.less
index ef937bd28..217226b73 100644
--- a/admin/form-builder/assets/less/form-builder.less
+++ b/admin/form-builder/assets/less/form-builder.less
@@ -1537,5 +1537,12 @@ span.pro-icon svg path {
fill: #fff;
}
+/* Form Builder Field Icons */
+.wpuf-field-label-icon .wpuf-field-icon {
+ font-size: 20px;
+ color: #059669; /* emerald-600 */
+ margin-right: 6px;
+}
+
@import "builder-responsive.less";
diff --git a/assets/css/admin/form-builder.css b/assets/css/admin/form-builder.css
index 1d57e361c..bc897d9a7 100644
--- a/assets/css/admin/form-builder.css
+++ b/assets/css/admin/form-builder.css
@@ -4580,6 +4580,10 @@ input.wpuf-tab:checked + .wpuf-tab-content,
justify-content: space-evenly;
}
+.wpuf-gap-1 {
+ gap: 0.25rem;
+}
+
.wpuf-gap-12 {
gap: 3rem;
}
@@ -6820,6 +6824,11 @@ button.swal2-cancel.swal2-styled.swal2-default-outline {
color: rgb(5 150 105 / var(--tw-text-opacity));
}
+.hover\:wpuf-text-red-500:hover {
+ --tw-text-opacity: 1;
+ color: rgb(239 68 68 / var(--tw-text-opacity));
+}
+
.hover\:wpuf-text-white:hover {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
diff --git a/assets/css/wpuf-form-builder.css b/assets/css/wpuf-form-builder.css
index aea6ec72f..c039c47cd 100644
--- a/assets/css/wpuf-form-builder.css
+++ b/assets/css/wpuf-form-builder.css
@@ -1237,6 +1237,13 @@ span.pro-icon svg {
span.pro-icon svg path {
fill: #fff;
}
+/* Form Builder Field Icons */
+.wpuf-field-label-icon .wpuf-field-icon {
+ font-size: 20px;
+ color: #059669;
+ /* emerald-600 */
+ margin-right: 6px;
+}
@media (min-width: 768px) and (max-width: 991px) {
#wpuf-form-builder {
width: 100% !important;
diff --git a/assets/js-templates/form-components.php b/assets/js-templates/form-components.php
index 0130dc122..6e1ed4d73 100644
--- a/assets/js-templates/form-components.php
+++ b/assets/js-templates/form-components.php
@@ -18,12 +18,16 @@
data-source="stage"
>
+
+
+
-
+
+
@@ -113,6 +117,10 @@ 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">
+
+
+
-
+
+