NAME
Chandra::Form - Form helpers with two-way binding for Chandra applications
SYNOPSIS
use Chandra::Form;
my $form = Chandra::Form->new(
id => 'settings-form',
action => sub {
my ($data) = @_;
# $data = { username => 'alice', theme => 'dark', notify => 1 }
save_settings($data);
},
);
# Add fields
$form->text('username', {
label => 'Username',
placeholder => 'Enter username',
required => 1,
value => 'alice',
maxlength => 50,
});
$form->password('password', {
label => 'Password',
required => 1,
minlength => 8,
});
$form->email('email', {
label => 'Email Address',
value => 'alice@example.com',
});
$form->textarea('bio', {
label => 'Biography',
rows => 4,
value => 'Hello world',
});
$form->select('theme', {
label => 'Theme',
options => [
{ value => 'light', label => 'Light' },
{ value => 'dark', label => 'Dark' },
{ value => 'auto', label => 'System' },
],
value => 'dark',
});
$form->checkbox('notify', {
label => 'Enable notifications',
checked => 1,
});
$form->radio('priority', {
label => 'Priority',
options => [
{ value => 'low', label => 'Low' },
{ value => 'medium', label => 'Medium' },
{ value => 'high', label => 'High' },
],
value => 'medium',
});
$form->number('font_size', {
label => 'Font Size',
min => 8,
max => 72,
step => 1,
value => 14,
});
$form->range('volume', {
label => 'Volume',
min => 0,
max => 100,
value => 75,
});
$form->hidden('csrf_token', { value => 'abc123' });
$form->submit('Save Settings');
# Render to HTML
my $html = $form->render;
DESCRIPTION
Chandra::Form provides form building helpers with automatic two-way data binding between Perl and the DOM for Chandra desktop applications.
Forms are built by chaining field methods, then rendered to HTML via render(). When used with Chandra::App, the generated JavaScript handles form submission, change events, and value synchronization through the Chandra bridge.
METHODS
new
my $form = Chandra::Form->new(
id => 'my-form', # optional, auto-generated if omitted
action => sub { ... }, # submit handler
class => 'custom-class', # additional CSS class
app => $app, # Chandra::App instance
);
Create a new form builder. The action coderef receives a hashref of form data when the form is submitted.
text
$form->text('username', {
label => 'Username',
placeholder => 'Enter name',
value => 'default',
required => 1,
maxlength => 100,
minlength => 3,
pattern => '[A-Za-z0-9]+',
disabled => 0,
readonly => 0,
autofocus => 1,
class => 'custom',
});
Add a text input field. All option keys are optional. Returns $self for chaining.
password
$form->password('pass', { label => 'Password', required => 1 });
Add a password input field. Same options as text().
$form->email('email', { label => 'Email', value => 'a@b.com' });
Add an email input field. Same options as text().
textarea
$form->textarea('bio', {
label => 'Biography',
rows => 4,
cols => 60,
value => 'Hello',
});
Add a textarea field. Accepts rows and cols in addition to standard options.
select
$form->select('theme', {
label => 'Theme',
options => [
{ value => 'light', label => 'Light' },
{ value => 'dark', label => 'Dark', disabled => 1 },
],
value => 'dark',
});
Add a dropdown select field. options is an arrayref of hashrefs, each with value and label keys. An option can be disabled.
checkbox
$form->checkbox('agree', {
label => 'I agree to the terms',
checked => 1,
value => 'yes', # defaults to "1"
});
Add a checkbox. The label appears after the checkbox. Serialized as 1/0 in form data.
radio
$form->radio('priority', {
label => 'Priority',
options => [
{ value => 'low', label => 'Low' },
{ value => 'high', label => 'High' },
],
value => 'low',
});
Add a radio button group. options and value work like select().
number
$form->number('qty', { label => 'Quantity', min => 1, max => 99, step => 1 });
Add a numeric input. Accepts min, max, and step.
range
$form->range('volume', { label => 'Volume', min => 0, max => 100, value => 50 });
Add a range slider. Same numeric options as number().
hidden
$form->hidden('token', { value => 'secret' });
Add a hidden field. No label or error placeholder is rendered.
submit
$form->submit('Save');
Set the submit button label. Defaults to "Submit".
group
$form->group('Appearance' => sub {
$form->select('theme', { ... });
$form->number('font_size', { ... });
});
Wrap fields in a <fieldset> with a <legend>.
render
my $html = $form->render;
Render the form to an HTML string. Each field is wrapped in a <div class="chandra-field"> with a label and error placeholder.
bind_js
my $js = $form->bind_js;
Returns JavaScript that intercepts form submit and change/input events, sending data to Perl via window.chandra.invoke().
attach
$form->attach($app);
Register this form with the global form registry and bind the bridge events (_form_submit, _form_change, _form_input, _form_values) on the given Chandra::App. The binding JS is automatically injected via dispatch_eval.
Multiple forms can be attached to the same app; each submit/change event is routed to the correct form by its id.
detach
$form->detach;
Remove this form from the global registry. Future bridge events for this form's id will be silently ignored.
set_values_js
my $js = $form->set_values_js({ username => 'bob', theme => 'light' });
Returns JavaScript that sets DOM field values from a hashref.
get_values_js
my $js = $form->get_values_js;
Returns JavaScript that reads current form values and sends them via bridge.
show_errors_js
my $js = $form->show_errors_js({ username => 'Required' });
Returns JavaScript that displays error messages next to fields.
clear_errors_js
my $js = $form->clear_errors_js;
Returns JavaScript that clears all error messages.
on_change
# Global handler - called for any field change
$form->on_change(sub {
my ($field, $value) = @_;
print "$field changed to: $value\n";
});
# Field-specific handler
$form->on_change('theme', sub {
my ($value) = @_;
apply_theme($value);
});
Register change event handlers. Field-specific handlers receive just the value; global handlers receive field name and value.
dispatch
$form->dispatch('_form_submit', $json_string);
Internal method called by the Chandra bridge to dispatch events. Not intended for direct use.
field_count
my $count = $form->field_count;
Returns the number of fields added to the form.
id
my $id = $form->id;
Returns the form's HTML id attribute.
fields
my $names = $form->fields; # ['username', 'email', 'theme']
Returns an arrayref of field names in order.
action
$form->action(sub { ... }); # set
my $cb = $form->action; # get
Get or set the form submit action handler.
CSS CLASSES
The generated HTML uses these CSS classes for styling:
.chandra-form — the <form> element
.chandra-field — wrapper <div> around each field
.chandra-field-checkbox — checkbox field wrapper
.chandra-field-radio — radio group wrapper
.chandra-field-submit — submit button wrapper
.chandra-label — <label> elements
.chandra-submit — submit <button>
.chandra-error — error message <span>
.chandra-group — <fieldset> from group()
.chandra-radio-option — individual radio <div>
SEE ALSO
Chandra, Chandra::Element, Chandra::App, Chandra::Bind
AUTHOR
LNATION <email@lnation.org>
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 352:
Non-ASCII character seen before =encoding in '—'. Assuming UTF-8