feat: add form builder AJAX handlers (F2.11)
- Create FormBuilderAjax class for React form builder - Add formipay_save_form_fields AJAX action - Add formipay_load_form_fields AJAX action - Sanitize field data on save - Update FormBuilder to load fields on mount - Add save status feedback (saving, saved, error) - Register FormBuilderAjax singleton in main plugin file
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useState, useCallback } from '@wordpress/element';
|
||||
import { useState, useCallback, useEffect } from '@wordpress/element';
|
||||
import FormCanvas from './FormCanvas';
|
||||
import FieldPalette from './FieldPalette';
|
||||
import FieldSettingsPanel from './FieldSettingsPanel';
|
||||
@@ -13,9 +13,36 @@ import './FormBuilder.css';
|
||||
export default function FormBuilder({ formId, initialData = {} }) {
|
||||
const [fields, setFields] = useState(initialData.fields || []);
|
||||
const [selectedFieldId, setSelectedFieldId] = useState(null);
|
||||
const [saveStatus, setSaveStatus] = useState(null);
|
||||
|
||||
const selectedField = fields.find(f => f.field_id === selectedFieldId) || null;
|
||||
|
||||
// Load existing fields on mount
|
||||
useEffect(() => {
|
||||
if (formId && !initialData.fields) {
|
||||
loadFields();
|
||||
}
|
||||
}, [formId]);
|
||||
|
||||
const loadFields = useCallback(() => {
|
||||
const params = new URLSearchParams({
|
||||
action: 'formipay_load_form_fields',
|
||||
post_id: formId,
|
||||
_wpnonce: window.formipayAdmin?.nonce || '',
|
||||
});
|
||||
|
||||
fetch(`${window.formipayAdmin?.ajaxUrl || '/wp-admin/admin-ajax.php'}?${params}`)
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.success && result.data.fields) {
|
||||
setFields(result.data.fields);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Load error:', error);
|
||||
});
|
||||
}, [formId]);
|
||||
|
||||
const handleDrop = useCallback((newField) => {
|
||||
setFields([...fields, newField]);
|
||||
setSelectedFieldId(newField.field_id);
|
||||
@@ -42,7 +69,7 @@ export default function FormBuilder({ formId, initialData = {} }) {
|
||||
}, [fields, selectedFieldId]);
|
||||
|
||||
const handleSave = useCallback(() => {
|
||||
// Save form fields via AJAX
|
||||
setSaveStatus('saving');
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'formipay_save_form_fields');
|
||||
formData.append('post_id', formId);
|
||||
@@ -57,13 +84,15 @@ export default function FormBuilder({ formId, initialData = {} }) {
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
// Show success message
|
||||
console.log('Form saved successfully');
|
||||
setSaveStatus('saved');
|
||||
setTimeout(() => setSaveStatus(null), 2000);
|
||||
} else {
|
||||
setSaveStatus('error');
|
||||
console.error('Failed to save form:', result.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
setSaveStatus('error');
|
||||
console.error('Save error:', error);
|
||||
});
|
||||
}, [fields, formId]);
|
||||
@@ -82,10 +111,14 @@ export default function FormBuilder({ formId, initialData = {} }) {
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="button button-primary"
|
||||
className={`button button-primary ${saveStatus === 'saving' ? 'is-busy' : ''}`}
|
||||
onClick={handleSave}
|
||||
disabled={saveStatus === 'saving'}
|
||||
>
|
||||
{ __('Save Form', 'formipay') }
|
||||
{ saveStatus === 'saved' ? __('Saved!', 'formipay') :
|
||||
saveStatus === 'error' ? __('Failed', 'formipay') :
|
||||
saveStatus === 'saving' ? __('Saving...', 'formipay') :
|
||||
__('Save Form', 'formipay') }
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user