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' }} +
+
+ + +
+ +
+
+ +
{{ icon.name }}
+
+
+ + +
+
🔍 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">
+ + + - + +
+ +