- Added new functions to the FormScriptEngine for enhanced field manipulation: setFieldByLabel() for setting fields by their display label, and getFieldOptions() for retrieving available options for select, radio, and checkbox fields. - Improved the setField() function to handle various field types more robustly, including select, radio, checkbox, and range inputs, with better event triggering for reactive updates. - Enhanced notification functions (showSuccess, showError, showInfo) to utilize Vue Toastification for improved user feedback, including customizable options for toast notifications. - Updated documentation in the form builder to reflect new field helper functions and their usage, improving developer guidance and usability.
444 lines
12 KiB
Markdown
444 lines
12 KiB
Markdown
# Form JavaScript API - Enhanced setField for Option Fields
|
|
|
|
## Overview
|
|
|
|
The Form JavaScript API provides powerful functions to interact with form fields dynamically. This document focuses on the enhanced `setField` functionality that properly handles option-based components like select dropdowns, radio buttons, and checkboxes.
|
|
|
|
## Enhanced setField Function
|
|
|
|
The `setField` function has been enhanced to intelligently handle different field types, especially option-based components where users can set values by either the internal value or the display label.
|
|
|
|
### Basic Usage
|
|
|
|
```javascript
|
|
// Basic text field
|
|
setField('first_name', 'John');
|
|
|
|
// Number field
|
|
setField('age', 25);
|
|
|
|
// Email field
|
|
setField('email', 'john@example.com');
|
|
```
|
|
|
|
### Option-Based Fields
|
|
|
|
#### Select Dropdown
|
|
|
|
For select dropdowns, you can set the value using either the internal value or the display label:
|
|
|
|
```javascript
|
|
// Setting by value (recommended)
|
|
setField('country', 'us');
|
|
|
|
// Setting by label (will automatically find the corresponding value)
|
|
setField('country', 'United States');
|
|
```
|
|
|
|
Example form configuration:
|
|
```json
|
|
{
|
|
"type": "select",
|
|
"props": {
|
|
"name": "country",
|
|
"label": "Country",
|
|
"options": [
|
|
{ "label": "United States", "value": "us" },
|
|
{ "label": "Canada", "value": "ca" },
|
|
{ "label": "United Kingdom", "value": "uk" }
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Radio Button Groups
|
|
|
|
Radio buttons work similarly - you can set by value or label:
|
|
|
|
```javascript
|
|
// Setting by value
|
|
setField('gender', 'male');
|
|
|
|
// Setting by label
|
|
setField('gender', 'Male');
|
|
```
|
|
|
|
#### Checkbox Groups
|
|
|
|
For checkboxes, you can set single values or arrays:
|
|
|
|
```javascript
|
|
// Single checkbox (boolean)
|
|
setField('newsletter', true);
|
|
|
|
// Multiple checkboxes - by value
|
|
setField('interests', ['sports', 'technology']);
|
|
|
|
// Multiple checkboxes - by label
|
|
setField('interests', ['Sports', 'Technology']);
|
|
|
|
// Single checkbox value
|
|
setField('interests', 'sports');
|
|
```
|
|
|
|
## Additional Helper Functions
|
|
|
|
### setFieldByLabel
|
|
|
|
Explicitly set a field by its label (display text) instead of value:
|
|
|
|
```javascript
|
|
// Explicitly set by label
|
|
setFieldByLabel('priority', 'High Priority');
|
|
setFieldByLabel('status', 'In Progress');
|
|
```
|
|
|
|
### getFieldOptions
|
|
|
|
Get all available options for a field:
|
|
|
|
```javascript
|
|
// Get all options for a select field
|
|
const countryOptions = getFieldOptions('country');
|
|
console.log(countryOptions);
|
|
// Output: [
|
|
// { label: "United States", value: "us" },
|
|
// { label: "Canada", value: "ca" },
|
|
// { label: "United Kingdom", value: "uk" }
|
|
// ]
|
|
|
|
// Use with conditional logic
|
|
const priorities = getFieldOptions('priority');
|
|
if (priorities.length > 0) {
|
|
setField('priority', priorities[0].value); // Set to first option
|
|
}
|
|
```
|
|
|
|
## Practical Examples
|
|
|
|
### Dynamic Field Updates Based on Selection
|
|
|
|
```javascript
|
|
// When country changes, update state/province options
|
|
onFieldChange('country', function(newValue) {
|
|
if (newValue === 'us') {
|
|
// Set to a US state
|
|
setField('state', 'california');
|
|
} else if (newValue === 'ca') {
|
|
// Set to a Canadian province
|
|
setField('province', 'ontario');
|
|
}
|
|
});
|
|
```
|
|
|
|
### Conditional Option Setting
|
|
|
|
```javascript
|
|
// Set different options based on user type
|
|
onFieldChange('user_type', function(userType) {
|
|
if (userType === 'premium') {
|
|
setField('support_level', 'priority');
|
|
setFieldByLabel('notification_preference', 'Email + SMS');
|
|
} else {
|
|
setField('support_level', 'standard');
|
|
setFieldByLabel('notification_preference', 'Email Only');
|
|
}
|
|
});
|
|
```
|
|
|
|
### Working with Multiple Selections
|
|
|
|
```javascript
|
|
// Add to existing checkbox selections
|
|
const currentInterests = getField('interests') || [];
|
|
const allInterests = [...currentInterests, 'photography'];
|
|
setField('interests', allInterests);
|
|
|
|
// Set multiple checkboxes by label
|
|
setFieldByLabel('services', ['Consulting', 'Development', 'Support']);
|
|
```
|
|
|
|
### Form Initialization
|
|
|
|
```javascript
|
|
// Set default values when form loads
|
|
setField('country', 'us');
|
|
setFieldByLabel('language', 'English');
|
|
setField('notifications', ['email', 'sms']);
|
|
|
|
// Show success message
|
|
showSuccess('Form initialized with default values');
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The enhanced setField provides helpful warnings when options are not found:
|
|
|
|
```javascript
|
|
// If option doesn't exist, warning is logged to console
|
|
setField('country', 'invalid_country');
|
|
// Console: [FormScriptEngine] Option "invalid_country" not found in select field "country"
|
|
|
|
// Check if field exists before setting
|
|
const options = getFieldOptions('priority');
|
|
if (options.some(opt => opt.value === 'urgent')) {
|
|
setField('priority', 'urgent');
|
|
} else {
|
|
console.log('Urgent priority option not available');
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Use Values When Possible**: Internal values are more reliable than labels
|
|
```javascript
|
|
// Preferred
|
|
setField('status', 'active');
|
|
|
|
// Works but less reliable if labels change
|
|
setFieldByLabel('status', 'Active Status');
|
|
```
|
|
|
|
2. **Check Options Exist**: Use `getFieldOptions` to verify options exist
|
|
```javascript
|
|
const statuses = getFieldOptions('status');
|
|
if (statuses.some(opt => opt.value === 'pending')) {
|
|
setField('status', 'pending');
|
|
}
|
|
```
|
|
|
|
3. **Handle Arrays for Multi-Select**: Always use arrays for checkbox groups
|
|
```javascript
|
|
// Correct for multiple checkboxes
|
|
setField('preferences', ['email', 'sms', 'push']);
|
|
|
|
// Also works for single selection
|
|
setField('preferences', ['email']);
|
|
```
|
|
|
|
4. **Use Descriptive Field Names**: Makes scripts more maintainable
|
|
```javascript
|
|
// Good
|
|
setField('notification_method', 'email');
|
|
setField('user_subscription_type', 'premium');
|
|
|
|
// Less clear
|
|
setField('field1', 'email');
|
|
setField('type', 'premium');
|
|
```
|
|
|
|
## Migration from Basic setField
|
|
|
|
If you're upgrading from the basic setField implementation:
|
|
|
|
### Before (Basic Implementation)
|
|
```javascript
|
|
// Only worked reliably with simple text fields
|
|
setField('name', 'John');
|
|
|
|
// Option fields required manual DOM manipulation
|
|
const select = document.querySelector('[data-name="country"] select');
|
|
select.value = 'us';
|
|
select.dispatchEvent(new Event('change'));
|
|
```
|
|
|
|
### After (Enhanced Implementation)
|
|
```javascript
|
|
// Works with all field types automatically
|
|
setField('name', 'John');
|
|
setField('country', 'us'); // By value
|
|
setField('country', 'United States'); // By label
|
|
setFieldByLabel('priority', 'High'); // Explicit label setting
|
|
```
|
|
|
|
## Summary
|
|
|
|
The enhanced `setField` function provides:
|
|
|
|
- ✅ **Smart option handling** - works with select, radio, and checkbox fields
|
|
- ✅ **Flexible value setting** - by internal value or display label
|
|
- ✅ **Array support** - for multiple checkbox selections
|
|
- ✅ **Error handling** - helpful warnings when options don't exist
|
|
- ✅ **Additional helpers** - `setFieldByLabel` and `getFieldOptions`
|
|
- ✅ **Backward compatibility** - existing scripts continue to work
|
|
|
|
This makes form scripting much more intuitive and powerful for complex forms with option-based fields.
|
|
|
|
---
|
|
|
|
## JavaScript API Functions Summary
|
|
|
|
All the functions documented above are now available in the Form JavaScript API:
|
|
|
|
### Core Form Functions
|
|
- `getField(fieldName)` - Get field value
|
|
- `setField(fieldName, value)` - Set field value (enhanced for options)
|
|
- `setFieldByLabel(fieldName, labelValue)` - Set field by display label
|
|
- `getFieldOptions(fieldName)` - Get available options for a field
|
|
- `hideField(fieldName)` / `showField(fieldName)` - Control field visibility
|
|
- `disableField(fieldName)` / `enableField(fieldName)` - Control field state
|
|
- `validateField(fieldName)` - Trigger field validation
|
|
- `getAllFieldValues()` - Get all form data
|
|
- `onFieldChange(fieldNames, callback)` - Register field change handlers
|
|
|
|
### Enhanced Alert Functions (Vue Toastification)
|
|
- `showSuccess(message, options)` - Success notifications
|
|
- `showError(message, options)` - Error notifications
|
|
- `showInfo(message, options)` - Info notifications
|
|
- `showWarning(message, options)` - Warning notifications
|
|
- `showToast(message, options)` - Toast notifications with type support
|
|
- `showConfirm(message, options)` - Confirmation dialogs with custom buttons (SweetAlert2)
|
|
- `showInputDialog(message, options)` - Input dialogs with validation (SweetAlert2)
|
|
- `showSelectDialog(message, options)` - Selection dialogs (SweetAlert2)
|
|
- `showProgress(message, options)` - Progress dialogs (SweetAlert2)
|
|
- `showCustomAlert(options)` - Fully customizable alerts (SweetAlert2)
|
|
- `closeAlert()` - Close any open alert (SweetAlert2)
|
|
- `$toast` - Direct access to Vue Toastification library
|
|
|
|
### Usage Examples for showConfirm with Custom Buttons
|
|
|
|
```javascript
|
|
// Basic confirmation with OK button
|
|
showConfirm('Are you sure you want to save?').then((result) => {
|
|
if (result.isConfirmed) {
|
|
// User clicked OK
|
|
console.log('User confirmed');
|
|
}
|
|
});
|
|
|
|
// Custom button labels
|
|
showConfirm('Delete this record?', {
|
|
confirmButtonText: 'Yes, Delete',
|
|
cancelButtonText: 'Keep It',
|
|
title: 'Confirm Deletion'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
showSuccess('Record deleted successfully!');
|
|
}
|
|
});
|
|
|
|
// Custom colors and styling
|
|
showConfirm('This action cannot be undone', {
|
|
title: 'Are you absolutely sure?',
|
|
confirmButtonText: 'Delete Forever',
|
|
cancelButtonText: 'Cancel',
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#3085d6',
|
|
icon: 'warning'
|
|
});
|
|
|
|
// Single OK button (no cancel)
|
|
showConfirm('Please read the terms and conditions', {
|
|
title: 'Important Notice',
|
|
confirmButtonText: 'I Understand',
|
|
showCancelButton: false,
|
|
icon: 'info'
|
|
});
|
|
```
|
|
|
|
All functions support custom options and return promises for easy async handling!
|
|
|
|
---
|
|
|
|
## Vue Toastification Integration
|
|
|
|
The notification functions now use Vue Toastification, which is already integrated in the project, providing beautiful and consistent toast notifications.
|
|
|
|
### Basic Toast Usage
|
|
|
|
```javascript
|
|
// Simple notifications
|
|
showSuccess('Form saved successfully!');
|
|
showError('Validation failed');
|
|
showInfo('Please review your entries');
|
|
showWarning('Some fields are incomplete');
|
|
|
|
// With custom options
|
|
showSuccess('Data updated!', {
|
|
timeout: 5000,
|
|
position: 'top-center'
|
|
});
|
|
|
|
// Different toast types
|
|
showToast('Custom message', { type: 'success' });
|
|
showToast('Warning message', { type: 'warning' });
|
|
showToast('Error message', { type: 'error' });
|
|
```
|
|
|
|
### Available Toast Options
|
|
|
|
```javascript
|
|
showSuccess('Message', {
|
|
timeout: 3000, // Auto-dismiss time (0 for no auto-dismiss)
|
|
position: 'bottom-right', // Position: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right
|
|
closeOnClick: true, // Close on click
|
|
pauseOnFocusLoss: true, // Pause timer when window loses focus
|
|
pauseOnHover: true, // Pause timer on hover
|
|
draggable: true, // Allow dragging to dismiss
|
|
draggablePercent: 0.6, // Percentage of drag needed to dismiss
|
|
showCloseButtonOnHover: false, // Show close button only on hover
|
|
hideProgressBar: false, // Hide progress bar
|
|
closeButton: "button", // Close button type
|
|
icon: true, // Show icon
|
|
rtl: false // Right-to-left text direction
|
|
});
|
|
```
|
|
|
|
### Direct Toast Access
|
|
|
|
For advanced usage, you can access the toast instance directly:
|
|
|
|
```javascript
|
|
// Get direct access to Vue Toastification
|
|
const toast = $toast;
|
|
|
|
if (toast) {
|
|
// Use all Vue Toastification methods
|
|
toast.success('Success message');
|
|
toast.error('Error message');
|
|
toast.warning('Warning message');
|
|
toast.info('Info message');
|
|
|
|
// Clear all toasts
|
|
toast.clear();
|
|
|
|
// Update a toast
|
|
const toastId = toast.success('Loading...', { timeout: false });
|
|
// Later update it
|
|
toast.update(toastId, {
|
|
content: 'Completed!',
|
|
options: { timeout: 3000, type: 'success' }
|
|
});
|
|
}
|
|
```
|
|
|
|
### Integration Examples
|
|
|
|
```javascript
|
|
// Form validation with toasts
|
|
onFieldChange('email', function(emailValue) {
|
|
if (emailValue && !emailValue.includes('@')) {
|
|
showWarning('Please enter a valid email address');
|
|
}
|
|
});
|
|
|
|
// Success feedback after form actions
|
|
onFieldChange('save_draft', function(value) {
|
|
if (value) {
|
|
showSuccess('Draft saved successfully!', {
|
|
position: 'top-center',
|
|
timeout: 2000
|
|
});
|
|
}
|
|
});
|
|
|
|
// Error handling
|
|
try {
|
|
// Some form operation
|
|
setField('complex_field', calculatedValue);
|
|
showInfo('Field updated automatically');
|
|
} catch (error) {
|
|
showError('Failed to update field: ' + error.message);
|
|
}
|
|
```
|