# 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);
}
```
