| Form-Factory documentation | Contained in the Form-Factory distribution. |
Form::Factory::Interface::HTML - Simple HTML form interface
version 0.020
use Form::Factory;
my $q = CGI->new;
my $html = '<form>';
my $form = Form::Factory->new(HTML => {
renderer => sub { $html .= join('', @_) },
consumer => sub { shift->Vars },
});
my $action = $form->new_action('MyApp::Action::Foo');
$action->consume_and_clean_and_check_and_process( request => $q );
$action->render;
$html .= '</form>';
print $q->header('text/html');
print $html;
This renders plain HTML forms and consumes value from a hash.
This is a code reference responsible for printing the HTML elements. The HTML for the controls is passed to this subroutine as a string. The default implementation just prints to the screen.
sub { print @_ }
This is a code reference responsible for taking the request object and turning it into a hash reference of values passed in from the HTTP request. The value passed in is the value passed as the request parameter to consume in Form::Factory::Action.
Returns a Form::Factory::Interface::HTML::Widget implementation for the given control.
Returns a widget for a Form::Factory::Control::Checkbox.
Returns a widget for a Form::Factory::Control::FullText.
Returns a widget for a Form::Factory::Control::Password.
Returns a widget for a Form::Factory::Control::SelectMany.
Returns a widget for a Form::Factory::Control::SelectOne.
Returns a widget for a Form::Factory::Control::Text.
Returns a widget for a Form::Factory::Control::Value.
Renders the widget for the given control.
Consumes values using the widget for the given control.
When I initially implemented this, using the widget classes made sense. However, the API has changed in some subtle ways since then. Originally, widgets were a required piece of the factory API, but they are not anymore. As such, they don't make nearly as much sense as they once did.
They will probably be removed in a future release.
Andrew Sterling Hanenkamp <hanenkamp@cpan.org>
Copyright 2009 Qubling Software LLC.
This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.
| Form-Factory documentation | Contained in the Form-Factory distribution. |
package Form::Factory::Interface::HTML; BEGIN { $Form::Factory::Interface::HTML::VERSION = '0.020'; } use Moose; with qw( Form::Factory::Interface ); use Carp (); use Scalar::Util qw( blessed ); use Form::Factory::Interface::HTML::Widget::Div; use Form::Factory::Interface::HTML::Widget::Input; use Form::Factory::Interface::HTML::Widget::Label; use Form::Factory::Interface::HTML::Widget::List; use Form::Factory::Interface::HTML::Widget::ListItem; use Form::Factory::Interface::HTML::Widget::Select; use Form::Factory::Interface::HTML::Widget::Span; use Form::Factory::Interface::HTML::Widget::Textarea;
has renderer => ( is => 'ro', isa => 'CodeRef', required => 1, default => sub { sub { print @_ } }, );
has consumer => ( is => 'ro', isa => 'CodeRef', required => 1, default => sub { sub { $_[0] } }, );
sub new_widget_for_control { my $self = shift; my $control = shift; my $results = shift; my $control_type = blessed $control; my ($name) = $control_type =~ /^Form::Factory::Control::(\w+)$/; return unless $name; $name = lc $name; my @alerts; @alerts = _alerts_for_control($control->name, $name, $results) if $results; my $method = 'new_widget_for_' . $name; return $self->$method($control, @alerts) if $self->can($method); return; } sub _wrapper($$@) { my ($name, $type, @widgets) = @_; return Form::Factory::Interface::HTML::Widget::Div->new( id => $name . '-wrapper', classes => [ qw( widget wrapper ), $type ], widgets => \@widgets, ); } sub _label($$$;$) { my ($name, $type, $label, $is_required) = @_; return Form::Factory::Interface::HTML::Widget::Label->new( id => $name . '-label', classes => [ qw( widget label ), $type ], for => $name, content => $label . _required_marker($is_required), ); } sub _required_marker($) { my ($is_required) = @_; if ($is_required) { return Form::Factory::Interface::HTML::Widget::Span->new( classes => [ qw( required ) ], content => '*', )->render; } else { return ''; } } sub _input($$$;$%) { my ($name, $type, $input_type, $value, %args) = @_; return Form::Factory::Interface::HTML::Widget::Input->new( id => $name, name => $name, type => $input_type, classes => [ qw( widget field ), $type ], value => $value || '', %args, ); } sub _alerts($$@) { my ($name, $type, @items) = @_; return Form::Factory::Interface::HTML::Widget::List->new( id => $name . '-alerts', classes => [ qw( widget alerts ), $type ], items => \@items, ); } sub _alerts_for_control { my ($name, $type, $results) = @_; my @items; my $count = 0; my @messages = $results->field_messages($name); for my $message (@messages) { push @items, Form::Factory::Interface::HTML::Widget::ListItem->new( id => $name . '-message-' . ++$count, classes => [ qw( widget message ), $type, $message->type ], content => $message->english_message, ); } return @items; }
sub new_widget_for_button { my ($self, $control) = @_; return _input($control->name, 'button', 'submit', $control->label); }
sub new_widget_for_checkbox { my ($self, $control, @alerts) = @_; return _wrapper($control->name, 'checkbox', _input($control->name, 'checkbox', 'checkbox', $control->true_value, checked => $control->is_true || ''), _label($control->name, 'checkbox', $control->label), _alerts($control->name, 'checkbox', @alerts), ); }
sub new_widget_for_fulltext { my ($self, $control, @alerts) = @_; return _wrapper($control->name, 'full-text', _label($control->name, 'full-text', $control->label, $control->has_feature('required')), Form::Factory::Interface::HTML::Widget::Textarea->new( id => $control->name, name => $control->name, classes => [ qw( widget field full-text ) ], content => $control->current_value, ), _alerts($control->name, 'full-text', @alerts), ); }
sub new_widget_for_password { my ($self, $control, @alerts) = @_; return _wrapper($control->name, 'password', _label($control->name, 'password', $control->label, $control->has_feature('required')), _input($control->name, 'password', 'password', $control->current_value), _alerts($control->name, 'password', @alerts), ); }
sub new_widget_for_selectmany { my ($self, $control, @alerts) = @_; my @checkboxes; for my $choice (@{ $control->available_choices }) { push @checkboxes, _input( $control->name, 'select-many choice', 'checkbox', $choice->value, checked => $control->is_choice_selected($choice), ); } return _wrapper($control->name, 'select-many', _label($control->name, 'select-many', $control->label, $control->has_feature('required')), Form::Factory::Interface::HTML::Widget::Div->new( id => $control->name . '-list', classes => [ qw( widget list select-many ) ], widgets => \@checkboxes, ), _alerts($control->name, 'select-many', @alerts), ); }
sub new_widget_for_selectone { my ($self, $control, @alerts) = @_; return _wrapper($control->name, 'select-one', _label($control->name, 'select-one', $control->label, $control->has_feature('required')), Form::Factory::Interface::HTML::Widget::Select->new( id => $control->name, name => $control->name, classes => [ qw( widget field select-one ) ], size => 1, available_choices => $control->available_choices, selected_choices => [ $control->current_value ], ), _alerts($control->name, 'select-one', @alerts), ); }
sub new_widget_for_text { my ($self, $control, @alerts) = @_; return _wrapper($control->name, 'text', _label($control->name, 'text', $control->label, $control->has_feature('required')), _input($control->name, 'text', 'text', $control->current_value), _alerts($control->name, 'text', @alerts), ); }
sub new_widget_for_value { my ($self, $control, @alerts) = @_; if ($control->is_visible) { return _wrapper($control->name, 'value', _label($control->name, 'value', $control->label), Form::Factory::Interface::HTML::Widget::Span->new( id => $control->name, content => $control->value, classes => [ qw( widget field value ) ], ), _alerts($control->name, 'text', @alerts), ); } return; }
sub render_control { my ($self, $control, %options) = @_; my $widget = $self->new_widget_for_control($control, $options{results}); return unless $widget; $self->renderer->($widget->render); }
sub consume_control { my ($self, $control, %options) = @_; Carp::croak("no request option passed") unless defined $options{request}; my $widget = $self->new_widget_for_control($control); return unless defined $widget; my $params = $widget->consume( params => $self->consumer->($options{request}) ); return unless defined $params->{ $control->name }; $control->current_value( $params->{ $control->name } ); }
1;