FORMS_AND_WIDGETS(3) RSX Framework Manual FORMS_AND_WIDGETS(3)
NAME
Forms and Widgets - RSX form system with reusable widget components
SYNOPSIS
// Blade form markup
// JavaScript - wire save button to form
$('#save-btn').on('click', function() {
const $form = $('.Rsx_Form').first();
$form.component().submit();
});
DESCRIPTION
The RSX form system provides a clean separation between form structure
(Rsx_Form), field layout (Form_Field), and input widgets (Text_Input,
Select_Input, etc). This architecture enables:
- Reusable widgets across all forms
- Consistent validation error display
- Automatic value collection and population
- Test data generation via seeders
- Read-only/disabled states
- Custom field layouts without modifying widget code
Key Components:
- Rsx_Form: Container managing form submission and validation
- Form_Field: Layout wrapper providing labels, help text, error display
- Widgets: Reusable input components (Text_Input, Select_Input, etc)
RSX_FORM COMPONENT
The Rsx_Form component manages form data flow, submission, and validation.
Required Attributes:
$action - Controller method reference for form submission
Example: Frontend_Clients_Controller.save
Optional Attributes:
$data - JSON-encoded object with initial form values
Used for edit mode to populate fields
Example: $data="{{ json_encode($client_data) }}"
Methods:
vals() - Get all form values as object
vals(values) - Set all form values from object
submit() - Submit form to $action endpoint
seed() - Fill all fields with test data (debug mode only)
Form Discovery:
Rsx_Form automatically discovers all widgets using shallowFind('.Widget')
and collects values based on their data-name attributes. No registration
or manual wiring required.
Example - Basic Form:
Example - Edit Mode with Initial Data:
@php
$form_data = [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'email' => $user->email,
];
@endphp
FORM_FIELD WRAPPER
Form_Field provides consistent layout for labels, help text, and error
display. It wraps a single widget and connects it to the form.
Required Attributes:
$name - Field name for form serialization and error display
Optional Attributes:
$label - Label text displayed above field
$required - Boolean, adds red asterisk to label
$help - Help text displayed below field
Responsibilities:
- Display label with optional required indicator
- Set data-name attribute on child widget
- Display validation errors returned from server
- Provide consistent spacing and styling
Example - Basic Field:
Example - Required Field with Help Text:
Example - Field with HTML in Label:
Twitter">
Custom Layout:
Form_Field can be extended or replaced with custom jqhtml to change
field layout. The only requirement is that the child widget must
have the data-name attribute set to the field name.
Example - Horizontal Layout:
<%= content() %>
<% if (this.has_error()) { %>
<%= this.get_error() %>
<% } %>
WIDGET INTERFACE
All form widgets must implement the standard widget interface:
Required:
- CSS class "Widget" on root element
- val() method for getting current value
- val(value) method for setting value
Optional:
- seed() method for generating test data
- Support for $disabled attribute
Widget Responsibilities:
1. Value Management
Widgets must implement getter/setter via val() method:
val() {
// Getter - return current value
if (arguments.length === 0) {
return this.$id('input').val();
}
// Setter - update value
else {
this.data.value = value || '';
this.$id('input').val(this.data.value);
}
}
2. Disabled State
Widgets should respect $disabled attribute:
- Render with disabled HTML attribute
- Display grayed-out appearance
- Still return value via val() getter
- Do not submit in HTML form (handled by browser)
3. Test Data (Optional)
Widgets may implement seed() for debug mode:
async seed() {
if (this.args.seeder) {
// Generate test data
this.val('Test Value');
}
}
BUILT-IN WIDGETS
Text_Input
Basic text input supporting multiple types and textarea.
Attributes:
$type - Input type (text, email, url, tel, number, textarea)
$rows - Number of rows for textarea (default: 3)
$placeholder - Placeholder text
$prefix - Text to prepend (creates input-group)
$suffix - Text to append (creates input-group)
$min - Minimum value for number inputs
$max - Maximum value for number inputs
$maxlength - Maximum length for text inputs
$disabled - Disable input (grayed out, still returns value)
$seeder - Seeder function name for test data
Examples:
Select_Input
Dropdown select with options.
Attributes:
$options - Array of options (see below)
$placeholder - Placeholder option text
$disabled - Disable select (grayed out, still returns value)
$seeder - Seeder function name for test data
Options Format:
Simple array: ['Option 1', 'Option 2', 'Option 3']
Object array: [
{value: 'opt1', label: 'Option 1'},
{value: 'opt2', label: 'Option 2'}
]
From Blade: $options="{{ json_encode($options_array) }}"
Examples:
@php
$industries = ['Technology', 'Finance', 'Healthcare'];
@endphp
@php
$sizes = [
['value' => 'sm', 'label' => 'Small (1-10)'],
['value' => 'md', 'label' => 'Medium (11-50)'],
['value' => 'lg', 'label' => 'Large (50+)'],
];
@endphp
Checkbox_Input
Checkbox with optional label.
Attributes:
$label - Label text displayed next to checkbox
$checked_value - Value when checked (default: "1")
$unchecked_value - Value when unchecked (default: "0")
$disabled - Disable checkbox (grayed out, still returns value)
Examples:
Wysiwyg_Input
Rich text editor using Quill.
Attributes:
$placeholder - Placeholder text
$disabled - Disable editor (not yet implemented)
$seeder - Seeder function name for test data
Example:
SEEDING TEST DATA
The seed system generates realistic test data for forms during development.
Enabled only when window.rsxapp.debug is true.
Seed Button:
Rsx_Form automatically displays a "Fill Test Data" button in debug mode.
Clicking this button calls seed() on all widgets.
Widget Seeding:
Widgets implement seed() to generate appropriate test data:
async seed() {
if (this.args.seeder) {
// TODO: Implement Rsx_Random_Values endpoint
let value = 'Test ' + (this.args.seeder || 'Value');
this.val(value);
}
}
Seeder Names:
Specify seeder via $seeder attribute:
Future Implementation:
Planned Rsx_Random_Values endpoint will provide:
- company_name() - Random company names
- email() - Random email addresses
- phone() - Random phone numbers
- first_name() - Random first names
- last_name() - Random last names
- address() - Random street addresses
- city() - Random city names
DISABLED STATE
Disabled widgets display as read-only but still participate in form
value collection.
Behavior:
- Widget displays grayed-out appearance
- User cannot interact with widget
- val() getter still returns current value
- Value included in form submission via Ajax
- HTML disabled attribute prevents browser form submission
Example - Disable Individual Fields:
Example - Conditional Disable:
Use Cases:
- Display data that cannot be edited
- Show calculated or system-managed values
- Enforce permissions (some users see but cannot edit)
- Multi-step forms (disable completed steps)
FORM SUBMISSION
Form submission uses Ajax to send data to controller methods.
JavaScript Submission:
$('#save-btn').on('click', function() {
const $form = $('.Rsx_Form').first();
const form_component = $form.component();
form_component.submit();
});
What Happens:
1. Form calls vals() to collect all widget values
2. Sends values to this.args.action via Ajax.call()
3. Handles response:
- Success: Redirect if response.redirect provided
- Validation errors: Display errors on fields
- General errors: Log to console
Controller Method:
#[Ajax_Endpoint]
public static function save(Request $request, array $params = []) {
// Validation
$validated = $request->validate([
'email' => 'required|email',
'name' => 'required|string|max:255',
]);
// Save data
$user = User::create($validated);
// Return response
return [
'success' => true,
'redirect' => Rsx::Route('Users_Controller', 'view', $user->id),
];
}
Validation Errors:
When validation fails, return errors in format:
return [
'success' => false,
'errors' => [
'email' => 'The email field is required.',
'name' => 'The name field is required.',
],
];
Form automatically displays errors below each field.
MULTI-COLUMN LAYOUTS
Use Bootstrap grid for multi-column field layouts:
CREATING CUSTOM WIDGETS
Create custom widgets by implementing the widget interface.
Example - Rating Widget:
File: rating_input.jqhtml
<% for (let i = 1; i <= 5; i++) { %>
"
class="bi bi-star<%= this.data.value >= i ? '-fill' : '' %>"
data-rating="<%= i %>">
<% } %>