| line | stmt | bran | cond | sub | pod | time | code | 
| 1 | 404 |  |  | 404 |  | 38265614 | use strict; | 
|  | 404 |  |  |  |  | 4548 |  | 
|  | 404 |  |  |  |  | 20844 |  | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | package HTML::FormFu; | 
| 4 |  |  |  |  |  |  | $HTML::FormFu::VERSION = '2.07'; | 
| 5 |  |  |  |  |  |  | # ABSTRACT: HTML Form Creation, Rendering and Validation Framework | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 404 |  |  | 404 |  | 214943 | use Moose; | 
|  | 404 |  |  |  |  | 187541543 |  | 
|  | 404 |  |  |  |  | 2966 |  | 
| 8 | 404 |  |  | 404 |  | 3226350 | use MooseX::Attribute::Chained; | 
|  | 404 |  |  |  |  | 5196732 |  | 
|  | 404 |  |  |  |  | 24938 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | with 'HTML::FormFu::Role::Render', | 
| 11 |  |  |  |  |  |  | 'HTML::FormFu::Role::CreateChildren', | 
| 12 |  |  |  |  |  |  | 'HTML::FormFu::Role::GetProcessors', | 
| 13 |  |  |  |  |  |  | 'HTML::FormFu::Role::ContainsElements', | 
| 14 |  |  |  |  |  |  | 'HTML::FormFu::Role::ContainsElementsSharedWithField', | 
| 15 |  |  |  |  |  |  | 'HTML::FormFu::Role::FormAndBlockMethods', | 
| 16 |  |  |  |  |  |  | 'HTML::FormFu::Role::FormAndElementMethods', | 
| 17 |  |  |  |  |  |  | 'HTML::FormFu::Role::FormBlockAndFieldMethods', | 
| 18 |  |  |  |  |  |  | 'HTML::FormFu::Role::NestedHashUtils', | 
| 19 |  |  |  |  |  |  | 'HTML::FormFu::Role::Populate', | 
| 20 |  |  |  |  |  |  | 'HTML::FormFu::Role::CustomRoles'; | 
| 21 |  |  |  |  |  |  |  | 
| 22 | 404 |  |  |  |  | 37289 | use HTML::FormFu::Attribute qw( | 
| 23 |  |  |  |  |  |  | mk_attrs | 
| 24 |  |  |  |  |  |  | mk_attr_accessors | 
| 25 |  |  |  |  |  |  | mk_output_accessors | 
| 26 |  |  |  |  |  |  | mk_inherited_accessors | 
| 27 |  |  |  |  |  |  | mk_inherited_merging_accessors | 
| 28 | 404 |  |  | 404 |  | 213758 | ); | 
|  | 404 |  |  |  |  | 1260 |  | 
| 29 | 404 |  |  | 404 |  | 3479 | use HTML::FormFu::Constants qw( $EMPTY_STR ); | 
|  | 404 |  |  |  |  | 864 |  | 
|  | 404 |  |  |  |  | 35153 |  | 
| 30 | 404 |  |  | 404 |  | 196531 | use HTML::FormFu::Constraint; | 
|  | 404 |  |  |  |  | 1444 |  | 
|  | 404 |  |  |  |  | 17559 |  | 
| 31 | 404 |  |  | 404 |  | 3543 | use HTML::FormFu::Exception; | 
|  | 404 |  |  |  |  | 875 |  | 
|  | 404 |  |  |  |  | 10291 |  | 
| 32 | 404 |  |  | 404 |  | 215037 | use HTML::FormFu::FakeQuery; | 
|  | 404 |  |  |  |  | 1148 |  | 
|  | 404 |  |  |  |  | 12469 |  | 
| 33 | 404 |  |  | 404 |  | 171716 | use HTML::FormFu::Filter; | 
|  | 404 |  |  |  |  | 1364 |  | 
|  | 404 |  |  |  |  | 16273 |  | 
| 34 | 404 |  |  | 404 |  | 203901 | use HTML::FormFu::Inflator; | 
|  | 404 |  |  |  |  | 1420 |  | 
|  | 404 |  |  |  |  | 15024 |  | 
| 35 | 404 |  |  | 404 |  | 198172 | use HTML::FormFu::Localize; | 
|  | 404 |  |  |  |  | 1272 |  | 
|  | 404 |  |  |  |  | 33203 |  | 
| 36 | 404 |  |  |  |  | 30692 | use HTML::FormFu::ObjectUtil qw( | 
| 37 |  |  |  |  |  |  | form | 
| 38 |  |  |  |  |  |  | load_config_file            load_config_filestem | 
| 39 |  |  |  |  |  |  | clone                       stash | 
| 40 |  |  |  |  |  |  | parent | 
| 41 |  |  |  |  |  |  | _load_file | 
| 42 | 404 |  |  | 404 |  | 3162 | ); | 
|  | 404 |  |  |  |  | 900 |  | 
| 43 | 404 |  |  |  |  | 29283 | use HTML::FormFu::Util qw( | 
| 44 |  |  |  |  |  |  | DEBUG | 
| 45 |  |  |  |  |  |  | DEBUG_PROCESS | 
| 46 |  |  |  |  |  |  | DEBUG_CONSTRAINTS | 
| 47 |  |  |  |  |  |  | debug | 
| 48 |  |  |  |  |  |  | require_class               _get_elements | 
| 49 |  |  |  |  |  |  | xml_escape                  split_name | 
| 50 |  |  |  |  |  |  | _parse_args                 process_attrs | 
| 51 |  |  |  |  |  |  | _filter_components | 
| 52 | 404 |  |  | 404 |  | 2671 | ); | 
|  | 404 |  |  |  |  | 941 |  | 
| 53 |  |  |  |  |  |  |  | 
| 54 | 404 |  |  | 404 |  | 2631 | use Clone (); | 
|  | 404 |  |  |  |  | 796 |  | 
|  | 404 |  |  |  |  | 11632 |  | 
| 55 | 404 |  |  | 404 |  | 2381 | use List::Util 1.45 qw( first any none uniq ); | 
|  | 404 |  |  |  |  | 8534 |  | 
|  | 404 |  |  |  |  | 34884 |  | 
| 56 | 404 |  |  | 404 |  | 2943 | use Scalar::Util qw( blessed weaken reftype ); | 
|  | 404 |  |  |  |  | 961 |  | 
|  | 404 |  |  |  |  | 20510 |  | 
| 57 | 404 |  |  | 404 |  | 2617 | use Carp qw( croak ); | 
|  | 404 |  |  |  |  | 994 |  | 
|  | 404 |  |  |  |  | 38086 |  | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | use overload ( | 
| 60 |  |  |  |  |  |  | 'eq'       => '_string_equals', | 
| 61 |  |  |  |  |  |  | '=='       => '_object_equals', | 
| 62 | 168 |  |  | 168 |  | 11957 | '""'       => sub { return shift->render }, | 
| 63 | 1 |  |  | 1 |  | 714 | 'bool'     => sub {1}, | 
| 64 | 404 |  |  |  |  | 9297 | 'fallback' => 1, | 
| 65 | 404 |  |  | 404 |  | 3423 | ); | 
|  | 404 |  |  |  |  | 953 |  | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | __PACKAGE__->mk_attr_accessors(qw( id action enctype method )); | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | for my $name ( qw( | 
| 70 |  |  |  |  |  |  | _elements | 
| 71 |  |  |  |  |  |  | _output_processors | 
| 72 |  |  |  |  |  |  | _valid_names | 
| 73 |  |  |  |  |  |  | _plugins | 
| 74 |  |  |  |  |  |  | _models | 
| 75 |  |  |  |  |  |  | ) ) | 
| 76 |  |  |  |  |  |  | { | 
| 77 |  |  |  |  |  |  | has $name => ( | 
| 78 |  |  |  |  |  |  | is      => 'rw', | 
| 79 |  |  |  |  |  |  | default => sub { [] }, | 
| 80 |  |  |  |  |  |  | lazy    => 1, | 
| 81 |  |  |  |  |  |  | isa     => 'ArrayRef', | 
| 82 |  |  |  |  |  |  | ); | 
| 83 |  |  |  |  |  |  | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | has languages => ( | 
| 86 |  |  |  |  |  |  | is      => 'rw', | 
| 87 |  |  |  |  |  |  | default => sub { ['en'] }, | 
| 88 |  |  |  |  |  |  | lazy    => 1, | 
| 89 |  |  |  |  |  |  | isa     => 'ArrayRef', | 
| 90 |  |  |  |  |  |  | traits  => ['Chained'], | 
| 91 |  |  |  |  |  |  | ); | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | has input => ( | 
| 94 |  |  |  |  |  |  | is      => 'rw', | 
| 95 |  |  |  |  |  |  | default => sub { {} }, | 
| 96 |  |  |  |  |  |  | lazy    => 1, | 
| 97 |  |  |  |  |  |  | isa     => 'HashRef', | 
| 98 |  |  |  |  |  |  | traits  => ['Chained'], | 
| 99 |  |  |  |  |  |  | ); | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | has _processed_params => ( | 
| 102 |  |  |  |  |  |  | is      => 'rw', | 
| 103 |  |  |  |  |  |  | default => sub { {} }, | 
| 104 |  |  |  |  |  |  | lazy    => 1, | 
| 105 |  |  |  |  |  |  | isa     => 'HashRef', | 
| 106 |  |  |  |  |  |  | ); | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | has form_error_message_class => ( | 
| 109 |  |  |  |  |  |  | is      => 'rw', | 
| 110 |  |  |  |  |  |  | default => 'form_error_message', | 
| 111 |  |  |  |  |  |  | lazy    => 1, | 
| 112 |  |  |  |  |  |  | ); | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | our @MULTIFORM_SHARED = ( qw( | 
| 115 |  |  |  |  |  |  | javascript | 
| 116 |  |  |  |  |  |  | javascript_src | 
| 117 |  |  |  |  |  |  | indicator | 
| 118 |  |  |  |  |  |  | filename | 
| 119 |  |  |  |  |  |  | query_type | 
| 120 |  |  |  |  |  |  | force_error_message | 
| 121 |  |  |  |  |  |  | localize_class | 
| 122 |  |  |  |  |  |  | tt_module | 
| 123 |  |  |  |  |  |  | nested_name | 
| 124 |  |  |  |  |  |  | nested_subscript | 
| 125 |  |  |  |  |  |  | default_model | 
| 126 |  |  |  |  |  |  | tmp_upload_dir | 
| 127 |  |  |  |  |  |  | params_ignore_underscore | 
| 128 |  |  |  |  |  |  | ) ); | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | for (@MULTIFORM_SHARED) { | 
| 131 |  |  |  |  |  |  | has $_ => ( | 
| 132 |  |  |  |  |  |  | is     => 'rw', | 
| 133 |  |  |  |  |  |  | traits => ['Chained'], | 
| 134 |  |  |  |  |  |  | ); | 
| 135 |  |  |  |  |  |  | } | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | has submitted => ( is => 'rw', traits => ['Chained'] ); | 
| 138 |  |  |  |  |  |  | has query     => ( is => 'rw', traits => ['Chained'] ); | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | has _auto_fieldset => ( is => 'rw' ); | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | __PACKAGE__->mk_output_accessors(qw( form_error_message )); | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | *elements          = \&element; | 
| 145 |  |  |  |  |  |  | *constraints       = \&constraint; | 
| 146 |  |  |  |  |  |  | *filters           = \&filter; | 
| 147 |  |  |  |  |  |  | *deflators         = \&deflator; | 
| 148 |  |  |  |  |  |  | *inflators         = \&inflator; | 
| 149 |  |  |  |  |  |  | *validators        = \&validator; | 
| 150 |  |  |  |  |  |  | *transformers      = \&transformer; | 
| 151 |  |  |  |  |  |  | *output_processors = \&output_processor; | 
| 152 |  |  |  |  |  |  | *loc               = \&localize; | 
| 153 |  |  |  |  |  |  | *plugins           = \&plugin; | 
| 154 |  |  |  |  |  |  | *add_plugins       = \&add_plugin; | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | our $build_defaults = { | 
| 157 |  |  |  |  |  |  | action             => '', | 
| 158 |  |  |  |  |  |  | method             => 'post', | 
| 159 |  |  |  |  |  |  | filename           => 'form', | 
| 160 |  |  |  |  |  |  | render_method      => 'string', | 
| 161 |  |  |  |  |  |  | tt_args            => {}, | 
| 162 |  |  |  |  |  |  | tt_module          => 'Template', | 
| 163 |  |  |  |  |  |  | query_type         => 'CGI', | 
| 164 |  |  |  |  |  |  | default_model      => 'DBIC', | 
| 165 |  |  |  |  |  |  | localize_class     => 'HTML::FormFu::I18N', | 
| 166 |  |  |  |  |  |  | auto_error_message => 'form_%s_%t', | 
| 167 |  |  |  |  |  |  | error_tag          => 'span', | 
| 168 |  |  |  |  |  |  | }; | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | sub BUILD { | 
| 171 |  |  |  |  |  |  | my ( $self, $args ) = @_; | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | $self->populate($build_defaults); | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | return; | 
| 176 |  |  |  |  |  |  | } | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | sub auto_fieldset { | 
| 179 | 1007 |  |  | 1007 | 1 | 4112 | my ( $self, $element_ref ) = @_; | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | # if there's no arg, just return whether there's an auto_fieldset already | 
| 182 | 1007 | 100 |  |  |  | 33283 | return $self->_auto_fieldset if !$element_ref; | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | # if the argument isn't a reference, assume it's just a "1" meaning true, | 
| 185 |  |  |  |  |  |  | # and use an empty hashref | 
| 186 | 87 | 100 |  |  |  | 446 | if ( !ref $element_ref ) { | 
| 187 | 46 |  |  |  |  | 129 | $element_ref = {}; | 
| 188 |  |  |  |  |  |  | } | 
| 189 |  |  |  |  |  |  |  | 
| 190 | 87 |  |  |  |  | 276 | $element_ref->{type} = 'Fieldset'; | 
| 191 |  |  |  |  |  |  |  | 
| 192 | 87 |  |  |  |  | 1002 | $self->element($element_ref); | 
| 193 |  |  |  |  |  |  |  | 
| 194 | 87 |  |  |  |  | 2645 | $self->_auto_fieldset(1); | 
| 195 |  |  |  |  |  |  |  | 
| 196 | 87 |  |  |  |  | 379 | return $self; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | sub default_values { | 
| 200 | 7 |  |  | 7 | 1 | 73 | my ( $self, $default_ref ) = @_; | 
| 201 |  |  |  |  |  |  |  | 
| 202 | 7 |  |  |  |  | 14 | for my $field ( @{ $self->get_fields } ) { | 
|  | 7 |  |  |  |  | 44 |  | 
| 203 | 18 |  |  |  |  | 80 | my $name = $field->nested_name; | 
| 204 | 18 | 50 |  |  |  | 47 | next if !defined $name; | 
| 205 | 18 | 100 |  |  |  | 61 | next if !exists $default_ref->{$name}; | 
| 206 |  |  |  |  |  |  |  | 
| 207 | 10 |  |  |  |  | 48 | $field->default( $default_ref->{$name} ); | 
| 208 |  |  |  |  |  |  | } | 
| 209 |  |  |  |  |  |  |  | 
| 210 | 7 |  |  |  |  | 27 | return $self; | 
| 211 |  |  |  |  |  |  | } | 
| 212 |  |  |  |  |  |  |  | 
| 213 |  |  |  |  |  |  | sub model { | 
| 214 | 21 |  |  | 21 | 1 | 95 | my ( $self, $model_name ) = @_; | 
| 215 |  |  |  |  |  |  |  | 
| 216 | 21 |  | 66 |  |  | 817 | $model_name ||= $self->default_model; | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | # search models already loaded | 
| 219 | 21 |  |  |  |  | 50 | for my $model ( @{ $self->_models } ) { | 
|  | 21 |  |  |  |  | 581 |  | 
| 220 | 14 | 50 |  |  |  | 444 | return $model | 
| 221 |  |  |  |  |  |  | if $model->type =~ /\Q$model_name\E$/; | 
| 222 |  |  |  |  |  |  | } | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | # class not found, try require-ing it | 
| 225 | 7 | 100 |  |  |  | 50 | my $class | 
| 226 |  |  |  |  |  |  | = $model_name =~ s/^\+// | 
| 227 |  |  |  |  |  |  | ? $model_name | 
| 228 |  |  |  |  |  |  | : "HTML::FormFu::Model::$model_name"; | 
| 229 |  |  |  |  |  |  |  | 
| 230 | 7 |  |  |  |  | 43 | require_class($class); | 
| 231 |  |  |  |  |  |  |  | 
| 232 | 7 |  |  |  |  | 326 | my $model = $class->new( | 
| 233 |  |  |  |  |  |  | {   type   => $model_name, | 
| 234 |  |  |  |  |  |  | parent => $self, | 
| 235 |  |  |  |  |  |  | } ); | 
| 236 |  |  |  |  |  |  |  | 
| 237 | 7 |  |  |  |  | 33 | push @{ $self->_models }, $model; | 
|  | 7 |  |  |  |  | 239 |  | 
| 238 |  |  |  |  |  |  |  | 
| 239 | 7 |  |  |  |  | 201 | return $model; | 
| 240 |  |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | sub process { | 
| 243 | 459 |  |  | 459 | 1 | 77024 | my ( $self, $query ) = @_; | 
| 244 |  |  |  |  |  |  |  | 
| 245 | 459 |  |  |  |  | 14597 | $self->input(             {} ); | 
| 246 | 459 |  |  |  |  | 13320 | $self->_processed_params( {} ); | 
| 247 | 459 |  |  |  |  | 13242 | $self->_valid_names( [] ); | 
| 248 |  |  |  |  |  |  |  | 
| 249 | 459 |  |  |  |  | 2837 | $self->clear_errors; | 
| 250 |  |  |  |  |  |  |  | 
| 251 | 459 |  | 100 |  |  | 2899 | $query ||= $self->query; | 
| 252 |  |  |  |  |  |  |  | 
| 253 | 459 | 100 | 100 |  |  | 4391 | if ( defined $query && !blessed($query) ) { | 
| 254 | 404 |  |  |  |  | 4087 | $query = HTML::FormFu::FakeQuery->new( $self, $query ); | 
| 255 |  |  |  |  |  |  | } | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | # save it for further calls to process() | 
| 258 | 459 | 100 |  |  |  | 2712 | if ($query) { | 
| 259 | 413 | 50 |  |  |  | 2261 | DEBUG && debug( QUERY => $query ); | 
| 260 |  |  |  |  |  |  |  | 
| 261 | 413 |  |  |  |  | 13375 | $self->query($query); | 
| 262 |  |  |  |  |  |  | } | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | # run all elements pre_process() methods | 
| 265 | 459 |  |  |  |  | 1063 | for my $elem ( @{ $self->get_elements } ) { | 
|  | 459 |  |  |  |  | 3065 |  | 
| 266 | 926 |  |  |  |  | 5844 | $elem->pre_process; | 
| 267 |  |  |  |  |  |  | } | 
| 268 |  |  |  |  |  |  |  | 
| 269 |  |  |  |  |  |  | # run all plugins pre_process() methods | 
| 270 | 459 |  |  |  |  | 2224 | for my $plugin ( @{ $self->get_plugins } ) { | 
|  | 459 |  |  |  |  | 3160 |  | 
| 271 | 0 |  |  |  |  | 0 | $plugin->pre_process; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | # run all elements process() methods | 
| 275 | 459 |  |  |  |  | 1110 | for my $elem ( @{ $self->get_elements } ) { | 
|  | 459 |  |  |  |  | 1874 |  | 
| 276 | 926 |  |  |  |  | 5128 | $elem->process; | 
| 277 |  |  |  |  |  |  | } | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | # run all plugins process() methods | 
| 280 | 459 |  |  |  |  | 2255 | for my $plugin ( @{ $self->get_plugins } ) { | 
|  | 459 |  |  |  |  | 2134 |  | 
| 281 | 0 |  |  |  |  | 0 | $plugin->process; | 
| 282 |  |  |  |  |  |  | } | 
| 283 |  |  |  |  |  |  |  | 
| 284 | 459 |  |  |  |  | 1112 | my $submitted; | 
| 285 |  |  |  |  |  |  | # refetch query in-case anything in pre_process/process changed it | 
| 286 | 459 |  |  |  |  | 11652 | $query = $self->query; | 
| 287 |  |  |  |  |  |  |  | 
| 288 | 459 | 100 |  |  |  | 2005 | if ( defined $query ) { | 
| 289 | 413 |  |  |  |  | 1047 | eval { my @params = $query->param }; | 
|  | 413 |  |  |  |  | 2498 |  | 
| 290 | 413 | 50 |  |  |  | 2075 | croak "Invalid query object: $@" if $@; | 
| 291 |  |  |  |  |  |  |  | 
| 292 | 413 |  |  |  |  | 2151 | $submitted = $self->_submitted($query); | 
| 293 |  |  |  |  |  |  | } | 
| 294 |  |  |  |  |  |  |  | 
| 295 | 459 | 50 |  |  |  | 2092 | DEBUG_PROCESS && debug( SUBMITTED => $submitted ); | 
| 296 |  |  |  |  |  |  |  | 
| 297 | 459 |  |  |  |  | 15430 | $self->submitted($submitted); | 
| 298 |  |  |  |  |  |  |  | 
| 299 | 459 | 100 |  |  |  | 1582 | if ($submitted) { | 
| 300 | 409 |  |  |  |  | 915 | my %input; | 
| 301 | 409 |  |  |  |  | 1629 | my @params = $query->param; | 
| 302 |  |  |  |  |  |  |  | 
| 303 | 409 |  |  |  |  | 1297 | for my $field ( @{ $self->get_fields } ) { | 
|  | 409 |  |  |  |  | 1788 |  | 
| 304 | 1211 |  |  |  |  | 4006 | my $name = $field->nested_name; | 
| 305 |  |  |  |  |  |  |  | 
| 306 | 1211 | 100 |  |  |  | 3451 | next if !defined $name; | 
| 307 | 1207 | 100 |  | 3045 |  | 7100 | next if none { $name eq $_ } @params; | 
|  | 3045 |  |  |  |  | 6401 |  | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | ## CGI wants you to use $query->multi_param($foo). | 
| 310 |  |  |  |  |  |  | ## doing so breaks CGI::Simple. So shoosh it up for now. | 
| 311 | 1010 |  |  |  |  | 3244 | local $CGI::LIST_CONTEXT_WARN = 0; | 
| 312 |  |  |  |  |  |  |  | 
| 313 | 1010 | 100 |  |  |  | 3896 | if ( $field->nested ) { | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | # call in list context so we know if there's more than 1 value | 
| 316 | 255 |  |  |  |  | 1155 | my @values = $query->param($name); | 
| 317 |  |  |  |  |  |  |  | 
| 318 | 255 | 100 |  |  |  | 855 | my $value | 
| 319 |  |  |  |  |  |  | = @values > 1 | 
| 320 |  |  |  |  |  |  | ? \@values | 
| 321 |  |  |  |  |  |  | : $values[0]; | 
| 322 |  |  |  |  |  |  |  | 
| 323 | 255 |  |  |  |  | 1148 | $self->set_nested_hash_value( \%input, $name, $value ); | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  | else { | 
| 326 | 755 |  |  |  |  | 4312 | my @values = $query->param($name); | 
| 327 |  |  |  |  |  |  |  | 
| 328 | 755 | 100 |  |  |  | 4011 | $input{$name} | 
| 329 |  |  |  |  |  |  | = @values > 1 | 
| 330 |  |  |  |  |  |  | ? \@values | 
| 331 |  |  |  |  |  |  | : $values[0]; | 
| 332 |  |  |  |  |  |  | } | 
| 333 |  |  |  |  |  |  | } | 
| 334 |  |  |  |  |  |  |  | 
| 335 | 409 | 50 |  |  |  | 2056 | DEBUG && debug( INPUT => \%input ); | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | # run all field process_input methods | 
| 338 | 409 |  |  |  |  | 1218 | for my $field ( @{ $self->get_fields } ) { | 
|  | 409 |  |  |  |  | 1783 |  | 
| 339 | 1211 |  |  |  |  | 4595 | $field->process_input( \%input ); | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  |  | 
| 342 | 409 |  |  |  |  | 11509 | $self->input( \%input ); | 
| 343 |  |  |  |  |  |  |  | 
| 344 | 409 |  |  |  |  | 1893 | $self->_process_input; | 
| 345 |  |  |  |  |  |  | } | 
| 346 |  |  |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | # run all plugins post_process methods | 
| 348 | 459 |  |  |  |  | 1026 | for my $elem ( @{ $self->get_elements } ) { | 
|  | 459 |  |  |  |  | 2201 |  | 
| 349 | 926 |  |  |  |  | 5699 | $elem->post_process; | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 | 459 |  |  |  |  | 2314 | for my $plugin ( @{ $self->get_plugins } ) { | 
|  | 459 |  |  |  |  | 2228 |  | 
| 353 | 0 |  |  |  |  | 0 | $plugin->post_process; | 
| 354 |  |  |  |  |  |  | } | 
| 355 |  |  |  |  |  |  |  | 
| 356 | 459 |  |  |  |  | 1805 | return; | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  | sub _submitted { | 
| 360 | 413 |  |  | 413 |  | 1333 | my ( $self, $query ) = @_; | 
| 361 |  |  |  |  |  |  |  | 
| 362 | 413 |  |  |  |  | 12071 | my $indicator = $self->indicator; | 
| 363 | 413 |  |  |  |  | 922 | my $code; | 
| 364 |  |  |  |  |  |  |  | 
| 365 | 413 | 100 | 100 |  |  | 3178 | if ( defined($indicator) && ref $indicator ne 'CODE' ) { | 
|  |  | 100 |  |  |  |  |  | 
| 366 | 7 | 50 |  |  |  | 27 | DEBUG_PROCESS && debug( INDICATOR => $indicator ); | 
| 367 |  |  |  |  |  |  |  | 
| 368 | 7 |  |  | 7 |  | 40 | $code = sub { return defined $query->param($indicator) }; | 
|  | 7 |  |  |  |  | 24 |  | 
| 369 |  |  |  |  |  |  | } | 
| 370 |  |  |  |  |  |  | elsif ( !defined $indicator ) { | 
| 371 |  |  |  |  |  |  | my @names = uniq | 
| 372 | 1145 |  |  |  |  | 4783 | grep {defined} | 
| 373 | 393 |  |  |  |  | 979 | map  { $_->nested_name } @{ $self->get_fields }; | 
|  | 1147 |  |  |  |  | 3614 |  | 
|  | 393 |  |  |  |  | 1781 |  | 
| 374 |  |  |  |  |  |  |  | 
| 375 | 393 | 50 |  |  |  | 2288 | DEBUG_PROCESS && debug( 'no indicator, checking fields...' => \@names ); | 
| 376 |  |  |  |  |  |  |  | 
| 377 |  |  |  |  |  |  | $code = sub { | 
| 378 | 393 |  |  | 393 |  | 1101 | grep { defined $query->param($_) } @names; | 
|  | 1124 |  |  |  |  | 3715 |  | 
| 379 | 393 |  |  |  |  | 3002 | }; | 
| 380 |  |  |  |  |  |  | } | 
| 381 |  |  |  |  |  |  | else { | 
| 382 | 13 |  |  |  |  | 41 | $code = $indicator; | 
| 383 |  |  |  |  |  |  | } | 
| 384 |  |  |  |  |  |  |  | 
| 385 | 413 |  |  |  |  | 1762 | return $code->( $self, $query ); | 
| 386 |  |  |  |  |  |  | } | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | sub _process_input { | 
| 389 | 409 |  |  | 409 |  | 2067 | my ($self) = @_; | 
| 390 |  |  |  |  |  |  |  | 
| 391 | 409 |  |  |  |  | 1886 | $self->_build_params; | 
| 392 |  |  |  |  |  |  |  | 
| 393 | 409 |  |  |  |  | 1949 | $self->_process_file_uploads; | 
| 394 |  |  |  |  |  |  |  | 
| 395 | 409 |  |  |  |  | 1746 | $self->_filter_input; | 
| 396 | 409 |  |  |  |  | 2097 | $self->_constrain_input; | 
| 397 | 409 | 100 |  |  |  | 1599 | $self->_inflate_input   if !@{ $self->get_errors }; | 
|  | 409 |  |  |  |  | 2270 |  | 
| 398 | 409 | 100 |  |  |  | 1174 | $self->_validate_input  if !@{ $self->get_errors }; | 
|  | 409 |  |  |  |  | 1653 |  | 
| 399 | 409 | 100 |  |  |  | 1027 | $self->_transform_input if !@{ $self->get_errors }; | 
|  | 409 |  |  |  |  | 2656 |  | 
| 400 |  |  |  |  |  |  |  | 
| 401 | 409 |  |  |  |  | 1885 | $self->_build_valid_names; | 
| 402 |  |  |  |  |  |  |  | 
| 403 | 409 |  |  |  |  | 1215 | return; | 
| 404 |  |  |  |  |  |  | } | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | sub _build_params { | 
| 407 | 409 |  |  | 409 |  | 1081 | my ($self) = @_; | 
| 408 |  |  |  |  |  |  |  | 
| 409 | 409 |  |  |  |  | 10110 | my $input = $self->input; | 
| 410 | 409 |  |  |  |  | 899 | my %params; | 
| 411 |  |  |  |  |  |  |  | 
| 412 | 409 |  |  |  |  | 1207 | for my $field ( @{ $self->get_fields } ) { | 
|  | 409 |  |  |  |  | 1811 |  | 
| 413 | 1211 |  |  |  |  | 4066 | my $name = $field->nested_name; | 
| 414 |  |  |  |  |  |  |  | 
| 415 | 1211 | 100 |  |  |  | 3576 | next if !defined $name; | 
| 416 | 1207 | 100 |  |  |  | 3220 | next if exists $params{$name}; | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | next | 
| 419 | 1188 | 100 | 100 |  |  | 27794 | if !$self->nested_hash_key_exists( $self->input, $name ) | 
| 420 |  |  |  |  |  |  | && !$field->default_empty_value; | 
| 421 |  |  |  |  |  |  |  | 
| 422 | 1057 |  |  |  |  | 25916 | my $input = $self->get_nested_hash_value( $self->input, $name ); | 
| 423 |  |  |  |  |  |  |  | 
| 424 | 1057 | 100 | 100 |  |  | 7114 | if ( ref $input eq 'ARRAY' ) { | 
|  |  | 100 |  |  |  |  |  | 
| 425 |  |  |  |  |  |  |  | 
| 426 |  |  |  |  |  |  | # can't clone upload filehandles | 
| 427 |  |  |  |  |  |  | # so create new arrayref of values | 
| 428 | 62 |  |  |  |  | 1066 | $input = [@$input]; | 
| 429 |  |  |  |  |  |  | } | 
| 430 |  |  |  |  |  |  | elsif ( !defined $input && $field->default_empty_value ) { | 
| 431 | 6 |  |  |  |  | 13 | $input = ''; | 
| 432 |  |  |  |  |  |  | } | 
| 433 |  |  |  |  |  |  |  | 
| 434 | 1057 |  |  |  |  | 4133 | $self->set_nested_hash_value( \%params, $name, $input, $name ); | 
| 435 |  |  |  |  |  |  | } | 
| 436 |  |  |  |  |  |  |  | 
| 437 | 409 |  |  |  |  | 13844 | $self->_processed_params( \%params ); | 
| 438 |  |  |  |  |  |  |  | 
| 439 | 409 | 50 |  |  |  | 1690 | DEBUG_PROCESS && debug( 'PROCESSED PARAMS' => \%params ); | 
| 440 |  |  |  |  |  |  |  | 
| 441 | 409 |  |  |  |  | 1451 | return; | 
| 442 |  |  |  |  |  |  | } | 
| 443 |  |  |  |  |  |  |  | 
| 444 |  |  |  |  |  |  | sub _process_file_uploads { | 
| 445 | 409 |  |  | 409 |  | 1512 | my ($self) = @_; | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | my @names = uniq | 
| 448 | 25 |  |  |  |  | 105 | grep {defined} | 
| 449 | 25 |  |  |  |  | 75 | map  { $_->nested_name } | 
| 450 | 409 |  |  |  |  | 1089 | grep { $_->isa('HTML::FormFu::Element::File') } @{ $self->get_fields }; | 
|  | 1211 |  |  |  |  | 8213 |  | 
|  | 409 |  |  |  |  | 2269 |  | 
| 451 |  |  |  |  |  |  |  | 
| 452 | 409 | 100 |  |  |  | 1775 | if (@names) { | 
| 453 | 13 |  |  |  |  | 344 | my $query_class = $self->query_type; | 
| 454 | 13 | 50 |  |  |  | 62 | if ( $query_class !~ /^\+/ ) { | 
| 455 | 13 |  |  |  |  | 50 | $query_class = "HTML::FormFu::QueryType::$query_class"; | 
| 456 |  |  |  |  |  |  | } | 
| 457 | 13 |  |  |  |  | 77 | require_class($query_class); | 
| 458 |  |  |  |  |  |  |  | 
| 459 | 13 |  |  |  |  | 385 | my $params = $self->_processed_params; | 
| 460 | 13 |  |  |  |  | 309 | my $input  = $self->input; | 
| 461 |  |  |  |  |  |  |  | 
| 462 | 13 |  |  |  |  | 45 | for my $name (@names) { | 
| 463 | 24 | 100 |  |  |  | 103 | next if !$self->nested_hash_key_exists( $input, $name ); | 
| 464 |  |  |  |  |  |  |  | 
| 465 | 21 |  |  |  |  | 96 | my $values = $query_class->parse_uploads( $self, $name ); | 
| 466 |  |  |  |  |  |  |  | 
| 467 | 21 |  |  |  |  | 89 | $self->set_nested_hash_value( $params, $name, $values ); | 
| 468 |  |  |  |  |  |  | } | 
| 469 |  |  |  |  |  |  | } | 
| 470 |  |  |  |  |  |  |  | 
| 471 | 409 |  |  |  |  | 1202 | return; | 
| 472 |  |  |  |  |  |  | } | 
| 473 |  |  |  |  |  |  |  | 
| 474 |  |  |  |  |  |  | sub _filter_input { | 
| 475 | 409 |  |  | 409 |  | 1150 | my ($self) = @_; | 
| 476 |  |  |  |  |  |  |  | 
| 477 | 409 |  |  |  |  | 11640 | my $params = $self->_processed_params; | 
| 478 |  |  |  |  |  |  |  | 
| 479 | 409 |  |  |  |  | 988 | for my $filter ( @{ $self->get_filters } ) { | 
|  | 409 |  |  |  |  | 2274 |  | 
| 480 | 62 |  |  |  |  | 439 | my $name = $filter->nested_name; | 
| 481 |  |  |  |  |  |  |  | 
| 482 | 62 | 50 |  |  |  | 219 | next if !defined $name; | 
| 483 | 62 | 100 |  |  |  | 232 | next if !$self->nested_hash_key_exists( $params, $name ); | 
| 484 |  |  |  |  |  |  |  | 
| 485 | 59 |  |  |  |  | 428 | $filter->process( $self, $params ); | 
| 486 |  |  |  |  |  |  | } | 
| 487 |  |  |  |  |  |  |  | 
| 488 | 409 |  |  |  |  | 1183 | return; | 
| 489 |  |  |  |  |  |  | } | 
| 490 |  |  |  |  |  |  |  | 
| 491 |  |  |  |  |  |  | sub _constrain_input { | 
| 492 | 409 |  |  | 409 |  | 1241 | my ($self) = @_; | 
| 493 |  |  |  |  |  |  |  | 
| 494 | 409 |  |  |  |  | 11818 | my $params = $self->_processed_params; | 
| 495 |  |  |  |  |  |  |  | 
| 496 | 409 |  |  |  |  | 1100 | for my $constraint ( @{ $self->get_constraints } ) { | 
|  | 409 |  |  |  |  | 1955 |  | 
| 497 |  |  |  |  |  |  |  | 
| 498 | 538 | 50 |  |  |  | 1622 | DEBUG_CONSTRAINTS && debug( | 
| 499 |  |  |  |  |  |  | 'FIELD NAME'      => $constraint->field->nested_name, | 
| 500 |  |  |  |  |  |  | 'CONSTRAINT TYPE' => $constraint->type, | 
| 501 |  |  |  |  |  |  | ); | 
| 502 |  |  |  |  |  |  |  | 
| 503 | 538 |  |  |  |  | 3195 | $constraint->pre_process; | 
| 504 |  |  |  |  |  |  |  | 
| 505 | 538 |  |  |  |  | 980 | my @errors = eval { $constraint->process($params) }; | 
|  | 538 |  |  |  |  | 2059 |  | 
| 506 |  |  |  |  |  |  |  | 
| 507 | 538 | 50 |  |  |  | 1655 | DEBUG_CONSTRAINTS && debug( ERRORS => \@errors ); | 
| 508 | 538 | 50 |  |  |  | 1730 | DEBUG_CONSTRAINTS && debug( '$@'   => $@ ); | 
| 509 |  |  |  |  |  |  |  | 
| 510 | 538 | 50 | 33 |  |  | 3003 | if ( blessed $@ && $@->isa('HTML::FormFu::Exception::Constraint') ) { | 
|  |  | 50 |  |  |  |  |  | 
| 511 | 0 |  |  |  |  | 0 | push @errors, $@; | 
| 512 |  |  |  |  |  |  | } | 
| 513 |  |  |  |  |  |  | elsif ($@) { | 
| 514 | 0 |  |  |  |  | 0 | push @errors, HTML::FormFu::Exception::Constraint->new; | 
| 515 |  |  |  |  |  |  | } | 
| 516 |  |  |  |  |  |  |  | 
| 517 | 538 |  |  |  |  | 1935 | for my $error (@errors) { | 
| 518 | 198 | 100 |  |  |  | 1304 | if ( !$error->parent ) { | 
| 519 | 130 |  |  |  |  | 688 | $error->parent( $constraint->parent ); | 
| 520 |  |  |  |  |  |  | } | 
| 521 | 198 | 50 |  |  |  | 1002 | if ( !$error->constraint ) { | 
| 522 | 198 |  |  |  |  | 964 | $error->constraint($constraint); | 
| 523 |  |  |  |  |  |  | } | 
| 524 |  |  |  |  |  |  |  | 
| 525 | 198 |  |  |  |  | 905 | $error->parent->add_error($error); | 
| 526 |  |  |  |  |  |  | } | 
| 527 |  |  |  |  |  |  | } | 
| 528 |  |  |  |  |  |  |  | 
| 529 | 409 |  |  |  |  | 1326 | return; | 
| 530 |  |  |  |  |  |  | } | 
| 531 |  |  |  |  |  |  |  | 
| 532 |  |  |  |  |  |  | sub _inflate_input { | 
| 533 | 279 |  |  | 279 |  | 1100 | my ($self) = @_; | 
| 534 |  |  |  |  |  |  |  | 
| 535 | 279 |  |  |  |  | 8826 | my $params = $self->_processed_params; | 
| 536 |  |  |  |  |  |  |  | 
| 537 | 279 |  |  |  |  | 1020 | for my $inflator ( @{ $self->get_inflators } ) { | 
|  | 279 |  |  |  |  | 1696 |  | 
| 538 | 27 |  |  |  |  | 310 | my $name = $inflator->nested_name; | 
| 539 |  |  |  |  |  |  |  | 
| 540 | 27 | 50 |  |  |  | 139 | next if !defined $name; | 
| 541 | 27 | 100 |  |  |  | 131 | next if !$self->nested_hash_key_exists( $params, $name ); | 
| 542 | 26 | 50 |  | 0 |  | 166 | next if any {defined} @{ $inflator->parent->get_errors }; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 26 |  |  |  |  | 142 |  | 
| 543 |  |  |  |  |  |  |  | 
| 544 | 26 |  |  |  |  | 184 | my $value = $self->get_nested_hash_value( $params, $name ); | 
| 545 |  |  |  |  |  |  |  | 
| 546 | 26 |  |  |  |  | 70 | my @errors; | 
| 547 |  |  |  |  |  |  |  | 
| 548 | 26 |  |  |  |  | 66 | ( $value, @errors ) = eval { $inflator->process($value) }; | 
|  | 26 |  |  |  |  | 255 |  | 
| 549 |  |  |  |  |  |  |  | 
| 550 | 26 | 50 | 33 |  |  | 260 | if ( blessed $@ && $@->isa('HTML::FormFu::Exception::Inflator') ) { | 
|  |  | 50 |  |  |  |  |  | 
| 551 | 0 |  |  |  |  | 0 | push @errors, $@; | 
| 552 |  |  |  |  |  |  | } | 
| 553 |  |  |  |  |  |  | elsif ($@) { | 
| 554 | 0 |  |  |  |  | 0 | push @errors, HTML::FormFu::Exception::Inflator->new; | 
| 555 |  |  |  |  |  |  | } | 
| 556 |  |  |  |  |  |  |  | 
| 557 | 26 |  |  |  |  | 93 | for my $error (@errors) { | 
| 558 | 3 | 50 |  |  |  | 26 | $error->parent( $inflator->parent ) if !$error->parent; | 
| 559 | 3 | 50 |  |  |  | 17 | $error->inflator($inflator) if !$error->inflator; | 
| 560 |  |  |  |  |  |  |  | 
| 561 | 3 |  |  |  |  | 13 | $error->parent->add_error($error); | 
| 562 |  |  |  |  |  |  | } | 
| 563 |  |  |  |  |  |  |  | 
| 564 | 26 |  |  |  |  | 183 | $self->set_nested_hash_value( $params, $name, $value ); | 
| 565 |  |  |  |  |  |  | } | 
| 566 |  |  |  |  |  |  |  | 
| 567 | 279 |  |  |  |  | 781 | return; | 
| 568 |  |  |  |  |  |  | } | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | sub _validate_input { | 
| 571 | 276 |  |  | 276 |  | 782 | my ($self) = @_; | 
| 572 |  |  |  |  |  |  |  | 
| 573 | 276 |  |  |  |  | 7901 | my $params = $self->_processed_params; | 
| 574 |  |  |  |  |  |  |  | 
| 575 | 276 |  |  |  |  | 1409 | for my $validator ( @{ $self->get_validators } ) { | 
|  | 276 |  |  |  |  | 1516 |  | 
| 576 | 8 |  |  |  |  | 47 | my $name = $validator->nested_name; | 
| 577 |  |  |  |  |  |  |  | 
| 578 | 8 | 50 |  |  |  | 25 | next if !defined $name; | 
| 579 | 8 | 50 |  |  |  | 30 | next if !$self->nested_hash_key_exists( $params, $name ); | 
| 580 | 8 | 50 |  | 0 |  | 37 | next if any {defined} @{ $validator->parent->get_errors }; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 8 |  |  |  |  | 27 |  | 
| 581 |  |  |  |  |  |  |  | 
| 582 | 8 |  |  |  |  | 34 | my @errors = eval { $validator->process($params) }; | 
|  | 8 |  |  |  |  | 43 |  | 
| 583 |  |  |  |  |  |  |  | 
| 584 | 8 | 50 | 33 |  |  | 55 | if ( blessed $@ && $@->isa('HTML::FormFu::Exception::Validator') ) { | 
|  |  | 50 |  |  |  |  |  | 
| 585 | 0 |  |  |  |  | 0 | push @errors, $@; | 
| 586 |  |  |  |  |  |  | } | 
| 587 |  |  |  |  |  |  | elsif ($@) { | 
| 588 | 0 |  |  |  |  | 0 | push @errors, HTML::FormFu::Exception::Validator->new; | 
| 589 |  |  |  |  |  |  | } | 
| 590 |  |  |  |  |  |  |  | 
| 591 | 8 |  |  |  |  | 24 | for my $error (@errors) { | 
| 592 | 1 | 50 |  |  |  | 7 | $error->parent( $validator->parent ) if !$error->parent; | 
| 593 | 1 | 50 |  |  |  | 5 | $error->validator($validator) if !$error->validator; | 
| 594 |  |  |  |  |  |  |  | 
| 595 | 1 |  |  |  |  | 4 | $error->parent->add_error($error); | 
| 596 |  |  |  |  |  |  | } | 
| 597 |  |  |  |  |  |  | } | 
| 598 |  |  |  |  |  |  |  | 
| 599 | 276 |  |  |  |  | 865 | return; | 
| 600 |  |  |  |  |  |  | } | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  | sub _transform_input { | 
| 603 | 275 |  |  | 275 |  | 2945 | my ($self) = @_; | 
| 604 |  |  |  |  |  |  |  | 
| 605 | 275 |  |  |  |  | 8620 | my $params = $self->_processed_params; | 
| 606 |  |  |  |  |  |  |  | 
| 607 | 275 |  |  |  |  | 1541 | for my $transformer ( @{ $self->get_transformers } ) { | 
|  | 275 |  |  |  |  | 1611 |  | 
| 608 | 5 |  |  |  |  | 33 | my $name = $transformer->nested_name; | 
| 609 |  |  |  |  |  |  |  | 
| 610 | 5 | 50 |  |  |  | 16 | next if !defined $name; | 
| 611 | 5 | 50 |  |  |  | 20 | next if !$self->nested_hash_key_exists( $params, $name ); | 
| 612 | 5 | 50 |  | 0 |  | 23 | next if any {defined} @{ $transformer->parent->get_errors }; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 5 |  |  |  |  | 20 |  | 
| 613 |  |  |  |  |  |  |  | 
| 614 | 5 |  |  |  |  | 29 | my $value = $self->get_nested_hash_value( $params, $name ); | 
| 615 |  |  |  |  |  |  |  | 
| 616 | 5 |  |  |  |  | 13 | my (@errors) = eval { $transformer->process( $value, $params ) }; | 
|  | 5 |  |  |  |  | 28 |  | 
| 617 |  |  |  |  |  |  |  | 
| 618 | 5 | 50 | 33 |  |  | 35 | if ( blessed $@ && $@->isa('HTML::FormFu::Exception::Transformer') ) { | 
|  |  | 50 |  |  |  |  |  | 
| 619 | 0 |  |  |  |  | 0 | push @errors, $@; | 
| 620 |  |  |  |  |  |  | } | 
| 621 |  |  |  |  |  |  | elsif ($@) { | 
| 622 | 0 |  |  |  |  | 0 | push @errors, HTML::FormFu::Exception::Transformer->new; | 
| 623 |  |  |  |  |  |  | } | 
| 624 |  |  |  |  |  |  |  | 
| 625 | 5 |  |  |  |  | 16 | for my $error (@errors) { | 
| 626 | 0 | 0 |  |  |  | 0 | $error->parent( $transformer->parent ) if !$error->parent; | 
| 627 | 0 | 0 |  |  |  | 0 | $error->transformer($transformer) if !$error->transformer; | 
| 628 |  |  |  |  |  |  |  | 
| 629 | 0 |  |  |  |  | 0 | $error->parent->add_error($error); | 
| 630 |  |  |  |  |  |  | } | 
| 631 |  |  |  |  |  |  | } | 
| 632 |  |  |  |  |  |  |  | 
| 633 | 275 |  |  |  |  | 699 | return; | 
| 634 |  |  |  |  |  |  | } | 
| 635 |  |  |  |  |  |  |  | 
| 636 |  |  |  |  |  |  | sub _build_valid_names { | 
| 637 | 409 |  |  | 409 |  | 1712 | my ($self) = @_; | 
| 638 |  |  |  |  |  |  |  | 
| 639 | 409 |  |  |  |  | 11117 | my $params       = $self->_processed_params; | 
| 640 | 409 |  |  |  |  | 11687 | my $skip_private = $self->params_ignore_underscore; | 
| 641 | 409 |  |  |  |  | 2363 | my @errors       = $self->has_errors; | 
| 642 | 409 |  |  |  |  | 1039 | my @names; | 
| 643 |  |  |  |  |  |  | my %non_param; | 
| 644 |  |  |  |  |  |  |  | 
| 645 | 409 |  |  |  |  | 1050 | for my $field ( @{ $self->get_fields } ) { | 
|  | 409 |  |  |  |  | 1793 |  | 
| 646 | 1211 |  |  |  |  | 4070 | my $name = $field->nested_name; | 
| 647 |  |  |  |  |  |  |  | 
| 648 | 1211 | 100 |  |  |  | 3558 | next if !defined $name; | 
| 649 | 1207 | 100 | 100 |  |  | 3625 | next if $skip_private && $field->name =~ /^_/; | 
| 650 |  |  |  |  |  |  |  | 
| 651 | 1206 | 100 |  |  |  | 36635 | if ( $field->non_param ) { | 
|  |  | 100 |  |  |  |  |  | 
| 652 | 6 |  |  |  |  | 22 | $non_param{$name} = 1; | 
| 653 |  |  |  |  |  |  | } | 
| 654 |  |  |  |  |  |  | elsif ( $self->nested_hash_key_exists( $params, $name ) ) { | 
| 655 | 1049 |  |  |  |  | 3750 | push @names, $name; | 
| 656 |  |  |  |  |  |  | } | 
| 657 |  |  |  |  |  |  | } | 
| 658 |  |  |  |  |  |  |  | 
| 659 |  |  |  |  |  |  | push @names, uniq | 
| 660 | 910 |  |  |  |  | 6051 | grep { ref $params->{$_} ne 'HASH' } | 
| 661 | 911 |  | 100 |  |  | 4583 | grep { !( $skip_private && /^_/ ) } | 
| 662 | 409 |  |  |  |  | 2215 | grep { !exists $non_param{$_} } | 
|  | 914 |  |  |  |  | 2862 |  | 
| 663 |  |  |  |  |  |  | keys %$params; | 
| 664 |  |  |  |  |  |  |  | 
| 665 | 409 |  |  |  |  | 1502 | my %valid; | 
| 666 |  |  |  |  |  |  |  | 
| 667 |  |  |  |  |  |  | CHECK: | 
| 668 | 409 |  |  |  |  | 1145 | for my $name (@names) { | 
| 669 | 1886 |  |  |  |  | 3130 | for my $error (@errors) { | 
| 670 | 790 | 100 |  |  |  | 1919 | next CHECK if $name eq $error; | 
| 671 |  |  |  |  |  |  | } | 
| 672 | 1620 |  |  |  |  | 3210 | $valid{$name}++; | 
| 673 |  |  |  |  |  |  | } | 
| 674 | 409 |  |  |  |  | 4007 | my @valid = keys %valid; | 
| 675 |  |  |  |  |  |  |  | 
| 676 | 409 |  |  |  |  | 12723 | $self->_valid_names( \@valid ); | 
| 677 |  |  |  |  |  |  |  | 
| 678 | 409 |  |  |  |  | 1488 | return; | 
| 679 |  |  |  |  |  |  | } | 
| 680 |  |  |  |  |  |  |  | 
| 681 |  |  |  |  |  |  | sub _hash_keys { | 
| 682 | 4 |  |  | 4 |  | 1104 | my ( $hash, $subscript ) = @_; | 
| 683 | 4 |  |  |  |  | 6 | my @names; | 
| 684 |  |  |  |  |  |  |  | 
| 685 | 4 |  |  |  |  | 14 | for my $key ( keys %$hash ) { | 
| 686 | 10 | 100 |  |  |  | 29 | if ( ref $hash->{$key} eq 'HASH' ) { | 
|  |  | 100 |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | push @names, | 
| 688 | 4 | 100 |  |  |  | 16 | map { $subscript ? "${key}[${_}]" : "$key.$_" } | 
| 689 | 2 |  |  |  |  | 8 | _hash_keys( $hash->{$key}, $subscript ); | 
| 690 |  |  |  |  |  |  | } | 
| 691 |  |  |  |  |  |  | elsif ( ref $hash->{$key} eq 'ARRAY' ) { | 
| 692 |  |  |  |  |  |  | push @names, | 
| 693 | 4 | 100 |  |  |  | 19 | map { $subscript ? "${key}[${_}]" : "$key.$_" } | 
| 694 | 2 |  |  |  |  | 8 | _array_indices( $hash->{$key}, $subscript ); | 
| 695 |  |  |  |  |  |  | } | 
| 696 |  |  |  |  |  |  | else { | 
| 697 | 6 |  |  |  |  | 12 | push @names, $key; | 
| 698 |  |  |  |  |  |  | } | 
| 699 |  |  |  |  |  |  | } | 
| 700 |  |  |  |  |  |  |  | 
| 701 | 4 |  |  |  |  | 16 | return @names; | 
| 702 |  |  |  |  |  |  | } | 
| 703 |  |  |  |  |  |  |  | 
| 704 |  |  |  |  |  |  | sub _array_indices { | 
| 705 | 2 |  |  | 2 |  | 6 | my ( $array, $subscript ) = @_; | 
| 706 |  |  |  |  |  |  |  | 
| 707 | 2 |  |  |  |  | 3 | my @names; | 
| 708 |  |  |  |  |  |  |  | 
| 709 | 2 |  |  |  |  | 4 | for my $i ( 0 .. $#{$array} ) { | 
|  | 2 |  |  |  |  | 9 |  | 
| 710 | 4 | 50 |  |  |  | 14 | if ( ref $array->[$i] eq 'HASH' ) { | 
|  |  | 50 |  |  |  |  |  | 
| 711 |  |  |  |  |  |  | push @names, | 
| 712 | 0 | 0 |  |  |  | 0 | map { $subscript ? "${i}[${_}]" : "$i.$_" } | 
|  | 0 |  |  |  |  | 0 |  | 
| 713 |  |  |  |  |  |  | _hash_keys( $array->[$i], $subscript ); | 
| 714 |  |  |  |  |  |  | } | 
| 715 |  |  |  |  |  |  | elsif ( ref $array->[$i] eq 'ARRAY' ) { | 
| 716 |  |  |  |  |  |  | push @names, | 
| 717 | 0 | 0 |  |  |  | 0 | map { $subscript ? "${i}[${_}]" : "$i.$_" } | 
|  | 0 |  |  |  |  | 0 |  | 
| 718 |  |  |  |  |  |  | _array_indices( $array->[$i], $subscript ); | 
| 719 |  |  |  |  |  |  | } | 
| 720 |  |  |  |  |  |  | else { | 
| 721 | 4 |  |  |  |  | 9 | push @names, $i; | 
| 722 |  |  |  |  |  |  | } | 
| 723 |  |  |  |  |  |  | } | 
| 724 |  |  |  |  |  |  |  | 
| 725 | 2 |  |  |  |  | 7 | return @names; | 
| 726 |  |  |  |  |  |  | } | 
| 727 |  |  |  |  |  |  |  | 
| 728 |  |  |  |  |  |  | sub submitted_and_valid { | 
| 729 | 112 |  |  | 112 | 1 | 606 | my ($self) = @_; | 
| 730 |  |  |  |  |  |  |  | 
| 731 | 112 |  | 100 |  |  | 2919 | return $self->submitted && !$self->has_errors; | 
| 732 |  |  |  |  |  |  | } | 
| 733 |  |  |  |  |  |  |  | 
| 734 |  |  |  |  |  |  | sub params { | 
| 735 | 77 |  |  | 77 | 1 | 4091 | my ($self) = @_; | 
| 736 |  |  |  |  |  |  |  | 
| 737 | 77 | 50 |  |  |  | 2345 | return {} if !$self->submitted; | 
| 738 |  |  |  |  |  |  |  | 
| 739 | 77 |  |  |  |  | 312 | my @names = $self->valid; | 
| 740 | 77 |  |  |  |  | 146 | my %params; | 
| 741 |  |  |  |  |  |  |  | 
| 742 | 77 |  |  |  |  | 223 | for my $name (@names) { | 
| 743 | 188 |  |  |  |  | 511 | my @values = $self->param($name); | 
| 744 |  |  |  |  |  |  |  | 
| 745 | 188 | 100 |  |  |  | 483 | if ( @values > 1 ) { | 
| 746 | 13 |  |  |  |  | 46 | $self->set_nested_hash_value( \%params, $name, \@values ); | 
| 747 |  |  |  |  |  |  | } | 
| 748 |  |  |  |  |  |  | else { | 
| 749 | 175 |  |  |  |  | 549 | $self->set_nested_hash_value( \%params, $name, $values[0] ); | 
| 750 |  |  |  |  |  |  | } | 
| 751 |  |  |  |  |  |  | } | 
| 752 |  |  |  |  |  |  |  | 
| 753 | 77 |  |  |  |  | 581 | return \%params; | 
| 754 |  |  |  |  |  |  | } | 
| 755 |  |  |  |  |  |  |  | 
| 756 |  |  |  |  |  |  | sub param { | 
| 757 | 336 |  |  | 336 | 1 | 8497 | my ( $self, $name ) = @_; | 
| 758 |  |  |  |  |  |  |  | 
| 759 | 336 | 50 |  |  |  | 1217 | croak 'param method is readonly' if @_ > 2; | 
| 760 |  |  |  |  |  |  |  | 
| 761 | 336 | 50 |  |  |  | 11256 | return if !$self->submitted; | 
| 762 |  |  |  |  |  |  |  | 
| 763 | 336 | 100 |  |  |  | 1379 | if ( @_ == 2 ) { | 
| 764 | 331 | 100 |  |  |  | 2669 | return if !$self->valid($name); | 
| 765 |  |  |  |  |  |  |  | 
| 766 | 312 |  |  |  |  | 8349 | my $value | 
| 767 |  |  |  |  |  |  | = $self->get_nested_hash_value( $self->_processed_params, $name ); | 
| 768 |  |  |  |  |  |  |  | 
| 769 | 312 | 100 |  |  |  | 919 | return if !defined $value; | 
| 770 |  |  |  |  |  |  |  | 
| 771 | 304 | 100 |  |  |  | 899 | if ( ref $value eq 'ARRAY' ) { | 
| 772 | 20 | 100 |  |  |  | 124 | return wantarray ? @$value : $value->[0]; | 
| 773 |  |  |  |  |  |  | } | 
| 774 |  |  |  |  |  |  | else { | 
| 775 | 284 |  |  |  |  | 1182 | return $value; | 
| 776 |  |  |  |  |  |  | } | 
| 777 |  |  |  |  |  |  | } | 
| 778 |  |  |  |  |  |  |  | 
| 779 |  |  |  |  |  |  | # return a list of valid names, if no $name arg | 
| 780 | 5 |  |  |  |  | 18 | return $self->valid; | 
| 781 |  |  |  |  |  |  | } | 
| 782 |  |  |  |  |  |  |  | 
| 783 |  |  |  |  |  |  | sub param_value { | 
| 784 | 38 |  |  | 38 | 1 | 160 | my ( $self, $name ) = @_; | 
| 785 |  |  |  |  |  |  |  | 
| 786 | 38 | 50 |  |  |  | 146 | croak 'name parameter required' if @_ != 2; | 
| 787 |  |  |  |  |  |  |  | 
| 788 |  |  |  |  |  |  | return undef    ## no critic (ProhibitExplicitReturnUndef); | 
| 789 | 38 | 100 |  |  |  | 160 | if !$self->valid($name); | 
| 790 |  |  |  |  |  |  |  | 
| 791 |  |  |  |  |  |  | # this is guaranteed to always return a single value | 
| 792 |  |  |  |  |  |  |  | 
| 793 | 37 |  |  |  |  | 1078 | my $value = $self->get_nested_hash_value( $self->_processed_params, $name ); | 
| 794 |  |  |  |  |  |  |  | 
| 795 | 37 | 100 |  |  |  | 260 | return ref $value eq 'ARRAY' | 
| 796 |  |  |  |  |  |  | ? $value->[0] | 
| 797 |  |  |  |  |  |  | : $value; | 
| 798 |  |  |  |  |  |  | } | 
| 799 |  |  |  |  |  |  |  | 
| 800 |  |  |  |  |  |  | sub param_array { | 
| 801 | 7 |  |  | 7 | 1 | 25 | my ( $self, $name ) = @_; | 
| 802 |  |  |  |  |  |  |  | 
| 803 | 7 | 50 |  |  |  | 32 | croak 'name parameter required' if @_ != 2; | 
| 804 |  |  |  |  |  |  |  | 
| 805 |  |  |  |  |  |  | # guaranteed to always return an arrayref | 
| 806 |  |  |  |  |  |  |  | 
| 807 | 7 | 100 |  |  |  | 27 | return [] if !$self->valid($name); | 
| 808 |  |  |  |  |  |  |  | 
| 809 | 6 |  |  |  |  | 155 | my $value = $self->get_nested_hash_value( $self->_processed_params, $name ); | 
| 810 |  |  |  |  |  |  |  | 
| 811 | 6 | 50 |  |  |  | 21 | return [] if !defined $value; | 
| 812 |  |  |  |  |  |  |  | 
| 813 | 6 | 100 |  |  |  | 54 | return ref $value eq 'ARRAY' | 
| 814 |  |  |  |  |  |  | ? $value | 
| 815 |  |  |  |  |  |  | : [$value]; | 
| 816 |  |  |  |  |  |  | } | 
| 817 |  |  |  |  |  |  |  | 
| 818 |  |  |  |  |  |  | sub param_list { | 
| 819 | 3 |  |  | 3 | 1 | 9 | my ( $self, $name ) = @_; | 
| 820 |  |  |  |  |  |  |  | 
| 821 | 3 | 50 |  |  |  | 11 | croak 'name parameter required' if @_ != 2; | 
| 822 |  |  |  |  |  |  |  | 
| 823 |  |  |  |  |  |  | # guaranteed to always return an arrayref | 
| 824 |  |  |  |  |  |  |  | 
| 825 | 3 | 100 |  |  |  | 9 | return if !$self->valid($name); | 
| 826 |  |  |  |  |  |  |  | 
| 827 | 2 |  |  |  |  | 55 | my $value = $self->get_nested_hash_value( $self->_processed_params, $name ); | 
| 828 |  |  |  |  |  |  |  | 
| 829 | 2 | 50 |  |  |  | 7 | return if !defined $value; | 
| 830 |  |  |  |  |  |  |  | 
| 831 | 2 | 100 |  |  |  | 20 | return ref $value eq 'ARRAY' | 
| 832 |  |  |  |  |  |  | ? @$value | 
| 833 |  |  |  |  |  |  | : $value; | 
| 834 |  |  |  |  |  |  | } | 
| 835 |  |  |  |  |  |  |  | 
| 836 |  |  |  |  |  |  | sub valid { | 
| 837 | 991 |  |  | 991 | 1 | 21856 | my $self = shift; | 
| 838 |  |  |  |  |  |  |  | 
| 839 | 991 | 50 |  |  |  | 27346 | return if !$self->submitted; | 
| 840 |  |  |  |  |  |  |  | 
| 841 | 991 |  |  |  |  | 1891 | my @valid = @{ $self->_valid_names }; | 
|  | 991 |  |  |  |  | 23674 |  | 
| 842 |  |  |  |  |  |  |  | 
| 843 | 991 | 100 |  |  |  | 2714 | if (@_) { | 
| 844 | 815 |  |  |  |  | 1908 | my $name = shift; | 
| 845 |  |  |  |  |  |  |  | 
| 846 | 815 | 100 |  | 1670 |  | 4832 | return 1 if any { $name eq $_ } @valid; | 
|  | 1670 |  |  |  |  | 8995 |  | 
| 847 |  |  |  |  |  |  |  | 
| 848 |  |  |  |  |  |  | # not found - see if it's the name of a nested block | 
| 849 | 106 |  |  |  |  | 416 | my $parent; | 
| 850 |  |  |  |  |  |  |  | 
| 851 | 106 | 50 | 33 |  |  | 2856 | if ( defined $self->nested_name && $self->nested_name eq $name ) { | 
| 852 | 0 |  |  |  |  | 0 | $parent = $self; | 
| 853 |  |  |  |  |  |  | } | 
| 854 |  |  |  |  |  |  | else { | 
| 855 |  |  |  |  |  |  | ($parent) | 
| 856 | 102 |  |  | 102 |  | 924 | = first { $_->isa('HTML::FormFu::Element::Block') } | 
| 857 | 106 |  |  |  |  | 490 | @{ $self->get_all_elements( { nested_name => $name, } ) }; | 
|  | 106 |  |  |  |  | 709 |  | 
| 858 |  |  |  |  |  |  | } | 
| 859 |  |  |  |  |  |  |  | 
| 860 | 106 | 100 |  |  |  | 854 | if ( defined $parent ) { | 
| 861 | 3 |  |  | 3 |  | 10 | my $fail = any {defined} | 
| 862 | 5 |  |  |  |  | 33 | map { @{ $_->get_errors } } @{ $parent->get_fields }; | 
|  | 16 |  |  |  |  | 32 |  | 
|  | 16 |  |  |  |  | 46 |  | 
|  | 5 |  |  |  |  | 29 |  | 
| 863 |  |  |  |  |  |  |  | 
| 864 | 5 | 100 |  |  |  | 46 | return 1 if !$fail; | 
| 865 |  |  |  |  |  |  | } | 
| 866 |  |  |  |  |  |  |  | 
| 867 | 104 |  |  |  |  | 634 | return; | 
| 868 |  |  |  |  |  |  | } | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | # return a list of valid names, if no $name arg | 
| 871 | 176 |  |  |  |  | 619 | return @valid; | 
| 872 |  |  |  |  |  |  | } | 
| 873 |  |  |  |  |  |  |  | 
| 874 |  |  |  |  |  |  | sub has_errors { | 
| 875 | 900 |  |  | 900 | 1 | 3342 | my $self = shift; | 
| 876 |  |  |  |  |  |  |  | 
| 877 | 900 | 100 |  |  |  | 23723 | return if !$self->submitted; | 
| 878 |  |  |  |  |  |  |  | 
| 879 | 375 |  |  |  |  | 1207 | my @names = map { $_->nested_name } | 
| 880 | 2459 |  |  |  |  | 4460 | grep { @{ $_->get_errors } } | 
|  | 2459 |  |  |  |  | 5859 |  | 
| 881 | 756 |  |  |  |  | 3834 | grep { defined $_->nested_name } @{ $self->get_fields }; | 
|  | 2465 |  |  |  |  | 6962 |  | 
|  | 756 |  |  |  |  | 2980 |  | 
| 882 |  |  |  |  |  |  |  | 
| 883 | 756 | 100 |  |  |  | 2775 | if (@_) { | 
| 884 | 143 |  |  |  |  | 340 | my $name = shift; | 
| 885 | 143 | 100 |  | 113 |  | 984 | return 1 if any {/\Q$name/} @names; | 
|  | 113 |  |  |  |  | 2272 |  | 
| 886 | 89 |  |  |  |  | 700 | return; | 
| 887 |  |  |  |  |  |  | } | 
| 888 |  |  |  |  |  |  |  | 
| 889 |  |  |  |  |  |  | # return list of names with errors, if no $name arg | 
| 890 | 613 |  |  |  |  | 4978 | return @names; | 
| 891 |  |  |  |  |  |  | } | 
| 892 |  |  |  |  |  |  |  | 
| 893 |  |  |  |  |  |  | sub add_valid { | 
| 894 | 4 |  |  | 4 | 1 | 15 | my ( $self, $key, $value ) = @_; | 
| 895 |  |  |  |  |  |  |  | 
| 896 | 4 | 50 |  |  |  | 15 | croak 'add_valid requires arguments ($key, $value)' if @_ != 3; | 
| 897 |  |  |  |  |  |  |  | 
| 898 | 4 |  |  |  |  | 132 | $self->set_nested_hash_value( $self->input, $key, $value ); | 
| 899 |  |  |  |  |  |  |  | 
| 900 | 4 |  |  |  |  | 109 | $self->set_nested_hash_value( $self->_processed_params, $key, $value ); | 
| 901 |  |  |  |  |  |  |  | 
| 902 | 4 | 50 |  | 7 |  | 19 | if ( none { $_ eq $key } @{ $self->_valid_names } ) { | 
|  | 7 |  |  |  |  | 17 |  | 
|  | 4 |  |  |  |  | 103 |  | 
| 903 | 4 |  |  |  |  | 27 | push @{ $self->_valid_names }, $key; | 
|  | 4 |  |  |  |  | 102 |  | 
| 904 |  |  |  |  |  |  | } | 
| 905 |  |  |  |  |  |  |  | 
| 906 | 4 |  |  |  |  | 18 | return $value; | 
| 907 |  |  |  |  |  |  | } | 
| 908 |  |  |  |  |  |  |  | 
| 909 |  |  |  |  |  |  | sub _single_plugin { | 
| 910 | 1 |  |  | 1 |  | 3 | my ( $self, $arg_ref ) = @_; | 
| 911 |  |  |  |  |  |  |  | 
| 912 | 1 | 50 |  |  |  | 7 | if ( !ref $arg_ref ) { | 
|  |  | 50 |  |  |  |  |  | 
| 913 | 0 |  |  |  |  | 0 | $arg_ref = { type => $arg_ref }; | 
| 914 |  |  |  |  |  |  | } | 
| 915 |  |  |  |  |  |  | elsif ( ref $arg_ref eq 'HASH' ) { | 
| 916 |  |  |  |  |  |  |  | 
| 917 |  |  |  |  |  |  | # shallow clone | 
| 918 | 1 |  |  |  |  | 6 | $arg_ref = {%$arg_ref}; | 
| 919 |  |  |  |  |  |  | } | 
| 920 |  |  |  |  |  |  | else { | 
| 921 | 0 |  |  |  |  | 0 | croak 'invalid args'; | 
| 922 |  |  |  |  |  |  | } | 
| 923 |  |  |  |  |  |  |  | 
| 924 | 1 |  |  |  |  | 4 | my $type = delete $arg_ref->{type}; | 
| 925 | 1 |  |  |  |  | 3 | my @return; | 
| 926 |  |  |  |  |  |  |  | 
| 927 | 1 | 50 |  |  |  | 7 | my @names = map { ref $_ ? @$_ : $_ } | 
| 928 | 1 |  |  |  |  | 3 | grep {defined} ( delete $arg_ref->{name}, delete $arg_ref->{names} ); | 
|  | 2 |  |  |  |  | 18 |  | 
| 929 |  |  |  |  |  |  |  | 
| 930 | 1 | 50 |  |  |  | 3 | if (@names) { | 
| 931 |  |  |  |  |  |  |  | 
| 932 |  |  |  |  |  |  | # add plugins to appropriate fields | 
| 933 | 1 |  |  |  |  | 4 | for my $x (@names) { | 
| 934 | 1 |  |  |  |  | 7 | for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) { | 
|  | 1 |  |  |  |  | 12 |  | 
| 935 | 1 |  |  |  |  | 14 | my $new = $field->_require_plugin( $type, $arg_ref ); | 
| 936 | 1 |  |  |  |  | 4 | push @{ $field->_plugins }, $new; | 
|  | 1 |  |  |  |  | 37 |  | 
| 937 | 1 |  |  |  |  | 8 | push @return, $new; | 
| 938 |  |  |  |  |  |  | } | 
| 939 |  |  |  |  |  |  | } | 
| 940 |  |  |  |  |  |  | } | 
| 941 |  |  |  |  |  |  | else { | 
| 942 |  |  |  |  |  |  |  | 
| 943 |  |  |  |  |  |  | # add plugin directly to form | 
| 944 | 0 |  |  |  |  | 0 | my $new = $self->_require_plugin( $type, $arg_ref ); | 
| 945 |  |  |  |  |  |  |  | 
| 946 | 0 |  |  |  |  | 0 | push @{ $self->_plugins }, $new; | 
|  | 0 |  |  |  |  | 0 |  | 
| 947 | 0 |  |  |  |  | 0 | push @return, $new; | 
| 948 |  |  |  |  |  |  | } | 
| 949 |  |  |  |  |  |  |  | 
| 950 | 1 |  |  |  |  | 9 | return @return; | 
| 951 |  |  |  |  |  |  | } | 
| 952 |  |  |  |  |  |  |  | 
| 953 |  |  |  |  |  |  | around render => sub { | 
| 954 |  |  |  |  |  |  | my $orig = shift; | 
| 955 |  |  |  |  |  |  | my $self = shift; | 
| 956 |  |  |  |  |  |  |  | 
| 957 |  |  |  |  |  |  | my $plugins = $self->get_plugins; | 
| 958 |  |  |  |  |  |  |  | 
| 959 |  |  |  |  |  |  | for my $plugin (@$plugins) { | 
| 960 |  |  |  |  |  |  | $plugin->render; | 
| 961 |  |  |  |  |  |  | } | 
| 962 |  |  |  |  |  |  |  | 
| 963 |  |  |  |  |  |  | my $output = $self->$orig; | 
| 964 |  |  |  |  |  |  |  | 
| 965 |  |  |  |  |  |  | for my $plugin (@$plugins) { | 
| 966 |  |  |  |  |  |  | $plugin->post_render( \$output ); | 
| 967 |  |  |  |  |  |  | } | 
| 968 |  |  |  |  |  |  |  | 
| 969 |  |  |  |  |  |  | return $output; | 
| 970 |  |  |  |  |  |  | }; | 
| 971 |  |  |  |  |  |  |  | 
| 972 |  |  |  |  |  |  | sub render_data { | 
| 973 | 11 |  |  | 11 | 1 | 47 | my ( $self, $args ) = @_; | 
| 974 |  |  |  |  |  |  |  | 
| 975 |  |  |  |  |  |  | my $render = $self->render_data_non_recursive( | 
| 976 | 11 | 50 |  |  |  | 44 | {   elements => [ map { $_->render_data } @{ $self->_elements } ], | 
|  | 28 |  |  |  |  | 243 |  | 
|  | 11 |  |  |  |  | 307 |  | 
| 977 |  |  |  |  |  |  | $args ? %$args : (), | 
| 978 |  |  |  |  |  |  | } ); | 
| 979 |  |  |  |  |  |  |  | 
| 980 | 11 |  |  |  |  | 2153 | return $render; | 
| 981 |  |  |  |  |  |  | } | 
| 982 |  |  |  |  |  |  |  | 
| 983 |  |  |  |  |  |  | sub render_data_non_recursive { | 
| 984 | 187 |  |  | 187 | 1 | 656 | my ( $self, $args ) = @_; | 
| 985 |  |  |  |  |  |  |  | 
| 986 | 187 | 100 |  |  |  | 5869 | my %render = ( | 
| 987 |  |  |  |  |  |  | filename       => $self->filename, | 
| 988 |  |  |  |  |  |  | javascript     => $self->javascript, | 
| 989 |  |  |  |  |  |  | javascript_src => $self->javascript_src, | 
| 990 |  |  |  |  |  |  | attributes     => xml_escape( $self->attributes ), | 
| 991 |  |  |  |  |  |  | stash          => $self->stash, | 
| 992 |  |  |  |  |  |  | $args ? %$args : (), | 
| 993 |  |  |  |  |  |  | ); | 
| 994 |  |  |  |  |  |  |  | 
| 995 | 187 |  |  |  |  | 857 | $render{form} = \%render; | 
| 996 | 187 |  |  |  |  | 1122 | weaken( $render{form} ); | 
| 997 |  |  |  |  |  |  |  | 
| 998 | 187 |  |  |  |  | 597 | $render{object} = $self; | 
| 999 |  |  |  |  |  |  |  | 
| 1000 | 187 | 100 | 100 |  |  | 6413 | if ($self->force_error_message | 
|  |  |  | 100 |  |  |  |  | 
| 1001 |  |  |  |  |  |  | || ( $self->has_errors | 
| 1002 |  |  |  |  |  |  | && defined $self->form_error_message ) ) | 
| 1003 |  |  |  |  |  |  | { | 
| 1004 | 3 |  |  |  |  | 12 | $render{form_error_message} = xml_escape( $self->form_error_message ); | 
| 1005 | 3 |  |  |  |  | 99 | $render{form_error_message_class} = $self->form_error_message_class; | 
| 1006 |  |  |  |  |  |  | } | 
| 1007 |  |  |  |  |  |  |  | 
| 1008 | 187 |  |  |  |  | 699 | return \%render; | 
| 1009 |  |  |  |  |  |  | } | 
| 1010 |  |  |  |  |  |  |  | 
| 1011 |  |  |  |  |  |  | sub string { | 
| 1012 | 170 |  |  | 170 | 0 | 533 | my ( $self, $args_ref ) = @_; | 
| 1013 |  |  |  |  |  |  |  | 
| 1014 | 170 |  | 50 |  |  | 1561 | $args_ref ||= {}; | 
| 1015 |  |  |  |  |  |  |  | 
| 1016 | 170 |  |  |  |  | 853 | my $html = $self->_string_form_start($args_ref); | 
| 1017 |  |  |  |  |  |  |  | 
| 1018 |  |  |  |  |  |  | # form template | 
| 1019 |  |  |  |  |  |  |  | 
| 1020 | 170 |  |  |  |  | 558 | $html .= "\n"; | 
| 1021 |  |  |  |  |  |  |  | 
| 1022 | 170 |  |  |  |  | 357 | for my $element ( @{ $self->get_elements } ) { | 
|  | 170 |  |  |  |  | 880 |  | 
| 1023 |  |  |  |  |  |  |  | 
| 1024 |  |  |  |  |  |  | # call render, so that child elements can use a different renderer | 
| 1025 | 230 |  |  |  |  | 2264 | my $element_html = $element->render; | 
| 1026 |  |  |  |  |  |  |  | 
| 1027 |  |  |  |  |  |  | # skip Blank fields | 
| 1028 | 230 | 100 |  |  |  | 1050 | if ( length $element_html ) { | 
| 1029 | 229 |  |  |  |  | 1583 | $html .= $element_html . "\n"; | 
| 1030 |  |  |  |  |  |  | } | 
| 1031 |  |  |  |  |  |  | } | 
| 1032 |  |  |  |  |  |  |  | 
| 1033 | 170 |  |  |  |  | 905 | $html .= $self->_string_form_end($args_ref); | 
| 1034 | 170 |  |  |  |  | 431 | $html .= "\n"; | 
| 1035 |  |  |  |  |  |  |  | 
| 1036 | 170 |  |  |  |  | 793 | return $html; | 
| 1037 |  |  |  |  |  |  | } | 
| 1038 |  |  |  |  |  |  |  | 
| 1039 |  |  |  |  |  |  | sub _string_form_start { | 
| 1040 | 176 |  |  | 176 |  | 521 | my ( $self, $args_ref ) = @_; | 
| 1041 |  |  |  |  |  |  |  | 
| 1042 |  |  |  |  |  |  | # start_form template | 
| 1043 |  |  |  |  |  |  |  | 
| 1044 |  |  |  |  |  |  | my $render_ref | 
| 1045 |  |  |  |  |  |  | = exists $args_ref->{render_data} | 
| 1046 |  |  |  |  |  |  | ? $args_ref->{render_data} | 
| 1047 | 176 | 50 |  |  |  | 1153 | : $self->render_data_non_recursive; | 
| 1048 |  |  |  |  |  |  |  | 
| 1049 | 176 |  |  |  |  | 956 | my $html = sprintf "<form%s>", process_attrs( $render_ref->{attributes} ); | 
| 1050 |  |  |  |  |  |  |  | 
| 1051 | 176 | 100 |  |  |  | 946 | if ( defined $render_ref->{form_error_message} ) { | 
| 1052 |  |  |  |  |  |  | $html .= sprintf qq{\n<div class="%s">%s</div>}, | 
| 1053 |  |  |  |  |  |  | $render_ref->{form_error_message_class}, | 
| 1054 |  |  |  |  |  |  | $render_ref->{form_error_message}, | 
| 1055 | 3 |  |  |  |  | 26 | ; | 
| 1056 |  |  |  |  |  |  | } | 
| 1057 |  |  |  |  |  |  |  | 
| 1058 | 176 | 100 |  |  |  | 839 | if ( defined $render_ref->{javascript_src} ) { | 
| 1059 | 2 |  |  |  |  | 6 | my $uri = $render_ref->{javascript_src}; | 
| 1060 |  |  |  |  |  |  |  | 
| 1061 | 2 | 100 |  |  |  | 10 | my @uris = ref $uri eq 'ARRAY' ? @$uri : ($uri); | 
| 1062 |  |  |  |  |  |  |  | 
| 1063 | 2 |  |  |  |  | 5 | for my $uri (@uris) { | 
| 1064 | 3 |  |  |  |  | 12 | $html .= sprintf | 
| 1065 |  |  |  |  |  |  | qq{\n<script type="text/javascript" src="%s">\n</script>}, | 
| 1066 |  |  |  |  |  |  | $uri, | 
| 1067 |  |  |  |  |  |  | ; | 
| 1068 |  |  |  |  |  |  | } | 
| 1069 |  |  |  |  |  |  | } | 
| 1070 |  |  |  |  |  |  |  | 
| 1071 | 176 | 100 |  |  |  | 897 | if ( defined $render_ref->{javascript} ) { | 
| 1072 |  |  |  |  |  |  | $html .= sprintf | 
| 1073 |  |  |  |  |  |  | qq{\n<script type="text/javascript">\n%s\n</script>}, | 
| 1074 |  |  |  |  |  |  | $render_ref->{javascript}, | 
| 1075 | 3 |  |  |  |  | 13 | ; | 
| 1076 |  |  |  |  |  |  | } | 
| 1077 |  |  |  |  |  |  |  | 
| 1078 | 176 |  |  |  |  | 995 | return $html; | 
| 1079 |  |  |  |  |  |  | } | 
| 1080 |  |  |  |  |  |  |  | 
| 1081 |  |  |  |  |  |  | sub _string_form_end { | 
| 1082 | 176 |  |  | 176 |  | 661 | my ($self) = @_; | 
| 1083 |  |  |  |  |  |  |  | 
| 1084 |  |  |  |  |  |  | # end_form template | 
| 1085 |  |  |  |  |  |  |  | 
| 1086 | 176 |  |  |  |  | 783 | return "</form>"; | 
| 1087 |  |  |  |  |  |  | } | 
| 1088 |  |  |  |  |  |  |  | 
| 1089 |  |  |  |  |  |  | sub start { | 
| 1090 | 6 |  |  | 6 | 1 | 284618 | my $self = shift; | 
| 1091 |  |  |  |  |  |  |  | 
| 1092 | 6 | 50 |  |  |  | 38 | if ( 'tt' eq $self->render_method ) { | 
| 1093 | 0 |  |  |  |  | 0 | return $self->tt( | 
| 1094 |  |  |  |  |  |  | {   filename    => 'start_form', | 
| 1095 |  |  |  |  |  |  | render_data => $self->render_data_non_recursive, | 
| 1096 |  |  |  |  |  |  | } ); | 
| 1097 |  |  |  |  |  |  | } | 
| 1098 |  |  |  |  |  |  | else { | 
| 1099 | 6 |  |  |  |  | 28 | return $self->_string_form_start(@_); | 
| 1100 |  |  |  |  |  |  | } | 
| 1101 |  |  |  |  |  |  | } | 
| 1102 |  |  |  |  |  |  |  | 
| 1103 |  |  |  |  |  |  | sub end { | 
| 1104 | 6 |  |  | 6 | 1 | 391 | my $self = shift; | 
| 1105 |  |  |  |  |  |  |  | 
| 1106 | 6 | 50 |  |  |  | 30 | if ( 'tt' eq $self->render_method ) { | 
| 1107 | 0 |  |  |  |  | 0 | return $self->tt( | 
| 1108 |  |  |  |  |  |  | {   filename    => 'end_form', | 
| 1109 |  |  |  |  |  |  | render_data => $self->render_data_non_recursive, | 
| 1110 |  |  |  |  |  |  | } ); | 
| 1111 |  |  |  |  |  |  | } | 
| 1112 |  |  |  |  |  |  | else { | 
| 1113 | 6 |  |  |  |  | 28 | return $self->_string_form_end(@_); | 
| 1114 |  |  |  |  |  |  | } | 
| 1115 |  |  |  |  |  |  | } | 
| 1116 |  |  |  |  |  |  |  | 
| 1117 |  |  |  |  |  |  | sub hidden_fields { | 
| 1118 | 1 |  |  | 1 | 1 | 4 | my ($self) = @_; | 
| 1119 |  |  |  |  |  |  |  | 
| 1120 |  |  |  |  |  |  | return join $EMPTY_STR, | 
| 1121 | 1 |  |  |  |  | 3 | map { $_->render } @{ $self->get_fields( { type => 'Hidden' } ) }; | 
|  | 2 |  |  |  |  | 17 |  | 
|  | 1 |  |  |  |  | 8 |  | 
| 1122 |  |  |  |  |  |  | } | 
| 1123 |  |  |  |  |  |  |  | 
| 1124 |  |  |  |  |  |  | sub output_processor { | 
| 1125 | 3 |  |  | 3 | 0 | 1930 | my ( $self, $arg ) = @_; | 
| 1126 | 3 |  |  |  |  | 10 | my @return; | 
| 1127 |  |  |  |  |  |  |  | 
| 1128 | 3 | 50 |  |  |  | 16 | if ( ref $arg eq 'ARRAY' ) { | 
| 1129 | 0 |  |  |  |  | 0 | push @return, map { $self->_single_output_processor($_) } @$arg; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1130 |  |  |  |  |  |  | } | 
| 1131 |  |  |  |  |  |  | else { | 
| 1132 | 3 |  |  |  |  | 14 | push @return, $self->_single_output_processor($arg); | 
| 1133 |  |  |  |  |  |  | } | 
| 1134 |  |  |  |  |  |  |  | 
| 1135 | 3 | 50 |  |  |  | 22 | return @return == 1 ? $return[0] : @return; | 
| 1136 |  |  |  |  |  |  | } | 
| 1137 |  |  |  |  |  |  |  | 
| 1138 |  |  |  |  |  |  | sub _single_output_processor { | 
| 1139 | 3 |  |  | 3 |  | 9 | my ( $self, $arg ) = @_; | 
| 1140 |  |  |  |  |  |  |  | 
| 1141 | 3 | 100 |  |  |  | 15 | if ( !ref $arg ) { | 
|  |  | 50 |  |  |  |  |  | 
| 1142 | 2 |  |  |  |  | 7 | $arg = { type => $arg }; | 
| 1143 |  |  |  |  |  |  | } | 
| 1144 |  |  |  |  |  |  | elsif ( ref $arg eq 'HASH' ) { | 
| 1145 | 1 |  |  |  |  | 12 | $arg = Clone::clone($arg); | 
| 1146 |  |  |  |  |  |  | } | 
| 1147 |  |  |  |  |  |  | else { | 
| 1148 | 0 |  |  |  |  | 0 | croak 'invalid args'; | 
| 1149 |  |  |  |  |  |  | } | 
| 1150 |  |  |  |  |  |  |  | 
| 1151 | 3 |  |  |  |  | 11 | my $type = delete $arg->{type}; | 
| 1152 |  |  |  |  |  |  |  | 
| 1153 | 3 |  |  |  |  | 15 | my $new = $self->_require_output_processor( $type, $arg ); | 
| 1154 |  |  |  |  |  |  |  | 
| 1155 | 3 |  |  |  |  | 8 | push @{ $self->_output_processors }, $new; | 
|  | 3 |  |  |  |  | 109 |  | 
| 1156 |  |  |  |  |  |  |  | 
| 1157 | 3 |  |  |  |  | 14 | return $new; | 
| 1158 |  |  |  |  |  |  | } | 
| 1159 |  |  |  |  |  |  |  | 
| 1160 |  |  |  |  |  |  | sub _require_output_processor { | 
| 1161 | 3 |  |  | 3 |  | 10 | my ( $self, $type, $opt ) = @_; | 
| 1162 |  |  |  |  |  |  |  | 
| 1163 | 3 | 50 |  |  |  | 18 | croak 'required arguments: $self, $type, \%options' if @_ != 3; | 
| 1164 |  |  |  |  |  |  |  | 
| 1165 | 3 | 50 |  |  |  | 18 | croak "options argument must be hash-ref" | 
| 1166 |  |  |  |  |  |  | if reftype($opt) ne 'HASH'; | 
| 1167 |  |  |  |  |  |  |  | 
| 1168 | 3 |  |  |  |  | 6 | my $class = $type; | 
| 1169 | 3 | 50 |  |  |  | 14 | if ( not $class =~ s/^\+// ) { | 
| 1170 | 3 |  |  |  |  | 11 | $class = "HTML::FormFu::OutputProcessor::$class"; | 
| 1171 |  |  |  |  |  |  | } | 
| 1172 |  |  |  |  |  |  |  | 
| 1173 | 3 |  |  |  |  | 10 | $type =~ s/^\+//; | 
| 1174 |  |  |  |  |  |  |  | 
| 1175 | 3 |  |  |  |  | 16 | require_class($class); | 
| 1176 |  |  |  |  |  |  |  | 
| 1177 | 3 |  |  |  |  | 123 | my $object = $class->new( | 
| 1178 |  |  |  |  |  |  | {   type   => $type, | 
| 1179 |  |  |  |  |  |  | parent => $self, | 
| 1180 |  |  |  |  |  |  | } ); | 
| 1181 |  |  |  |  |  |  |  | 
| 1182 |  |  |  |  |  |  | # handle default_args | 
| 1183 | 3 |  |  |  |  | 18 | my $parent = $self->parent; | 
| 1184 |  |  |  |  |  |  |  | 
| 1185 | 3 | 0 | 33 |  |  | 14 | if ( $parent && exists $parent->default_args->{output_processor}{$type} ) { | 
| 1186 |  |  |  |  |  |  | %$opt | 
| 1187 | 0 |  |  |  |  | 0 | = ( %{ $parent->default_args->{output_processer}{$type} }, %$opt ); | 
|  | 0 |  |  |  |  | 0 |  | 
| 1188 |  |  |  |  |  |  | } | 
| 1189 |  |  |  |  |  |  |  | 
| 1190 | 3 |  |  |  |  | 16 | $object->populate($opt); | 
| 1191 |  |  |  |  |  |  |  | 
| 1192 | 3 |  |  |  |  | 10 | return $object; | 
| 1193 |  |  |  |  |  |  | } | 
| 1194 |  |  |  |  |  |  |  | 
| 1195 |  |  |  |  |  |  | sub get_output_processors { | 
| 1196 | 1127 |  |  | 1127 | 0 | 2240 | my $self = shift; | 
| 1197 | 1127 |  |  |  |  | 3729 | my %args = _parse_args(@_); | 
| 1198 |  |  |  |  |  |  |  | 
| 1199 | 1127 |  |  |  |  | 2043 | my @x = @{ $self->_output_processors }; | 
|  | 1127 |  |  |  |  | 34555 |  | 
| 1200 |  |  |  |  |  |  |  | 
| 1201 | 1127 | 50 |  |  |  | 3381 | if ( exists $args{type} ) { | 
| 1202 | 0 |  |  |  |  | 0 | @x = grep { $_->type eq $args{type} } @x; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1203 |  |  |  |  |  |  | } | 
| 1204 |  |  |  |  |  |  |  | 
| 1205 | 1127 |  |  |  |  | 4362 | return \@x; | 
| 1206 |  |  |  |  |  |  | } | 
| 1207 |  |  |  |  |  |  |  | 
| 1208 |  |  |  |  |  |  | sub get_output_processor { | 
| 1209 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1210 |  |  |  |  |  |  |  | 
| 1211 | 0 |  |  |  |  |  | my $x = $self->get_output_processors(@_); | 
| 1212 |  |  |  |  |  |  |  | 
| 1213 | 0 | 0 |  |  |  |  | return @$x ? $x->[0] : (); | 
| 1214 |  |  |  |  |  |  | } | 
| 1215 |  |  |  |  |  |  |  | 
| 1216 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 1217 |  |  |  |  |  |  |  | 
| 1218 |  |  |  |  |  |  | 1; | 
| 1219 |  |  |  |  |  |  |  | 
| 1220 |  |  |  |  |  |  | __END__ | 
| 1221 |  |  |  |  |  |  |  | 
| 1222 |  |  |  |  |  |  | =pod | 
| 1223 |  |  |  |  |  |  |  | 
| 1224 |  |  |  |  |  |  | =encoding UTF-8 | 
| 1225 |  |  |  |  |  |  |  | 
| 1226 |  |  |  |  |  |  | =head1 NAME | 
| 1227 |  |  |  |  |  |  |  | 
| 1228 |  |  |  |  |  |  | HTML::FormFu - HTML Form Creation, Rendering and Validation Framework | 
| 1229 |  |  |  |  |  |  |  | 
| 1230 |  |  |  |  |  |  | =head1 VERSION | 
| 1231 |  |  |  |  |  |  |  | 
| 1232 |  |  |  |  |  |  | version 2.07 | 
| 1233 |  |  |  |  |  |  |  | 
| 1234 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 1235 |  |  |  |  |  |  |  | 
| 1236 |  |  |  |  |  |  | Note: These examples make use of L<HTML::FormFu::Model::DBIC>. As of | 
| 1237 |  |  |  |  |  |  | C<HTML::FormFu> v02.005, the L<HTML::FormFu::Model::DBIC> module is | 
| 1238 |  |  |  |  |  |  | not bundled with C<HTML::FormFu> and is available in a stand-alone | 
| 1239 |  |  |  |  |  |  | distribution. | 
| 1240 |  |  |  |  |  |  |  | 
| 1241 |  |  |  |  |  |  | use HTML::FormFu; | 
| 1242 |  |  |  |  |  |  |  | 
| 1243 |  |  |  |  |  |  | my $form = HTML::FormFu->new; | 
| 1244 |  |  |  |  |  |  |  | 
| 1245 |  |  |  |  |  |  | $form->load_config_file('form.yml'); | 
| 1246 |  |  |  |  |  |  |  | 
| 1247 |  |  |  |  |  |  | $form->process( $cgi_query ); | 
| 1248 |  |  |  |  |  |  |  | 
| 1249 |  |  |  |  |  |  | if ( $form->submitted_and_valid ) { | 
| 1250 |  |  |  |  |  |  | # do something with $form->params | 
| 1251 |  |  |  |  |  |  | } | 
| 1252 |  |  |  |  |  |  | else { | 
| 1253 |  |  |  |  |  |  | # display the form | 
| 1254 |  |  |  |  |  |  | $template->param( form => $form ); | 
| 1255 |  |  |  |  |  |  | } | 
| 1256 |  |  |  |  |  |  |  | 
| 1257 |  |  |  |  |  |  | If you're using L<Catalyst>, a more suitable example might be: | 
| 1258 |  |  |  |  |  |  |  | 
| 1259 |  |  |  |  |  |  | package MyApp::Controller::User; | 
| 1260 |  |  |  |  |  |  | use Moose; | 
| 1261 |  |  |  |  |  |  | extends 'Catalyst::Controller::HTML::FormFu'; | 
| 1262 |  |  |  |  |  |  |  | 
| 1263 |  |  |  |  |  |  | sub user : Chained CaptureArgs(1) { | 
| 1264 |  |  |  |  |  |  | my ( $self, $c, $id ) = @_; | 
| 1265 |  |  |  |  |  |  |  | 
| 1266 |  |  |  |  |  |  | my $rs = $c->model('Schema')->resultset('User'); | 
| 1267 |  |  |  |  |  |  |  | 
| 1268 |  |  |  |  |  |  | $c->stash->{user} = $rs->find( $id ); | 
| 1269 |  |  |  |  |  |  |  | 
| 1270 |  |  |  |  |  |  | return; | 
| 1271 |  |  |  |  |  |  | } | 
| 1272 |  |  |  |  |  |  |  | 
| 1273 |  |  |  |  |  |  | sub edit : Chained('user') Args(0) FormConfig { | 
| 1274 |  |  |  |  |  |  | my ( $self, $c ) = @_; | 
| 1275 |  |  |  |  |  |  |  | 
| 1276 |  |  |  |  |  |  | my $form = $c->stash->{form}; | 
| 1277 |  |  |  |  |  |  | my $user = $c->stash->{user}; | 
| 1278 |  |  |  |  |  |  |  | 
| 1279 |  |  |  |  |  |  | if ( $form->submitted_and_valid ) { | 
| 1280 |  |  |  |  |  |  |  | 
| 1281 |  |  |  |  |  |  | $form->model->update( $user ); | 
| 1282 |  |  |  |  |  |  |  | 
| 1283 |  |  |  |  |  |  | $c->res->redirect( $c->uri_for( "/user/$id" ) ); | 
| 1284 |  |  |  |  |  |  | return; | 
| 1285 |  |  |  |  |  |  | } | 
| 1286 |  |  |  |  |  |  |  | 
| 1287 |  |  |  |  |  |  | $form->model->default_values( $user ) | 
| 1288 |  |  |  |  |  |  | if ! $form->submitted; | 
| 1289 |  |  |  |  |  |  |  | 
| 1290 |  |  |  |  |  |  | } | 
| 1291 |  |  |  |  |  |  |  | 
| 1292 |  |  |  |  |  |  | Note: Because L</process> is automatically called for you by the Catalyst | 
| 1293 |  |  |  |  |  |  | controller; if you make any modifications to the form within your action | 
| 1294 |  |  |  |  |  |  | method, such as adding or changing elements, adding constraints, etc; | 
| 1295 |  |  |  |  |  |  | you must call L</process> again yourself before using L</submitted_and_valid>, | 
| 1296 |  |  |  |  |  |  | any of the methods listed under L</"SUBMITTED FORM VALUES AND ERRORS"> or | 
| 1297 |  |  |  |  |  |  | L</"MODIFYING A SUBMITTED FORM">, or rendering the form. | 
| 1298 |  |  |  |  |  |  |  | 
| 1299 |  |  |  |  |  |  | Here's an example of a config file to create a basic login form (all examples | 
| 1300 |  |  |  |  |  |  | here are L<YAML>, but you can use any format supported by L<Config::Any>), | 
| 1301 |  |  |  |  |  |  | you can also create forms directly in your perl code, rather than using an | 
| 1302 |  |  |  |  |  |  | external config file. | 
| 1303 |  |  |  |  |  |  |  | 
| 1304 |  |  |  |  |  |  | --- | 
| 1305 |  |  |  |  |  |  | action: /login | 
| 1306 |  |  |  |  |  |  | indicator: submit | 
| 1307 |  |  |  |  |  |  | auto_fieldset: 1 | 
| 1308 |  |  |  |  |  |  |  | 
| 1309 |  |  |  |  |  |  | elements: | 
| 1310 |  |  |  |  |  |  | - type: Text | 
| 1311 |  |  |  |  |  |  | name: user | 
| 1312 |  |  |  |  |  |  | constraints: | 
| 1313 |  |  |  |  |  |  | - Required | 
| 1314 |  |  |  |  |  |  |  | 
| 1315 |  |  |  |  |  |  | - type: Password | 
| 1316 |  |  |  |  |  |  | name: pass | 
| 1317 |  |  |  |  |  |  | constraints: | 
| 1318 |  |  |  |  |  |  | - Required | 
| 1319 |  |  |  |  |  |  |  | 
| 1320 |  |  |  |  |  |  | - type: Submit | 
| 1321 |  |  |  |  |  |  | name: submit | 
| 1322 |  |  |  |  |  |  |  | 
| 1323 |  |  |  |  |  |  | constraints: | 
| 1324 |  |  |  |  |  |  | - SingleValue | 
| 1325 |  |  |  |  |  |  |  | 
| 1326 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 1327 |  |  |  |  |  |  |  | 
| 1328 |  |  |  |  |  |  | L<HTML::FormFu> is a HTML form framework which aims to be as easy as | 
| 1329 |  |  |  |  |  |  | possible to use for basic web forms, but with the power and flexibility to | 
| 1330 |  |  |  |  |  |  | do anything else you might want to do (as long as it involves forms). | 
| 1331 |  |  |  |  |  |  |  | 
| 1332 |  |  |  |  |  |  | You can configure almost any part of formfu's behaviour and output. By | 
| 1333 |  |  |  |  |  |  | default formfu renders "XHTML 1.0 Strict" compliant markup, with as little | 
| 1334 |  |  |  |  |  |  | extra markup as possible, but with sufficient CSS class names to allow for a | 
| 1335 |  |  |  |  |  |  | wide-range of output styles to be generated by changing only the CSS. | 
| 1336 |  |  |  |  |  |  |  | 
| 1337 |  |  |  |  |  |  | All methods listed below (except L</new>) can either be called as a normal | 
| 1338 |  |  |  |  |  |  | method on your C<$form> object, or as an option in your config file. Examples | 
| 1339 |  |  |  |  |  |  | will mainly be shown in L<YAML> config syntax. | 
| 1340 |  |  |  |  |  |  |  | 
| 1341 |  |  |  |  |  |  | This documentation follows the convention that method arguments surrounded | 
| 1342 |  |  |  |  |  |  | by square brackets C<[]> are I<optional>, and all other arguments are | 
| 1343 |  |  |  |  |  |  | required. | 
| 1344 |  |  |  |  |  |  |  | 
| 1345 |  |  |  |  |  |  | =head1 BUILDING A FORM | 
| 1346 |  |  |  |  |  |  |  | 
| 1347 |  |  |  |  |  |  | =head2 new | 
| 1348 |  |  |  |  |  |  |  | 
| 1349 |  |  |  |  |  |  | Arguments: [\%options] | 
| 1350 |  |  |  |  |  |  |  | 
| 1351 |  |  |  |  |  |  | Return Value: $form | 
| 1352 |  |  |  |  |  |  |  | 
| 1353 |  |  |  |  |  |  | Create a new L<HTML::FormFu|HTML::FormFu> object. | 
| 1354 |  |  |  |  |  |  |  | 
| 1355 |  |  |  |  |  |  | Any method which can be called on the L<HTML::FormFu|HTML::FormFu> object may | 
| 1356 |  |  |  |  |  |  | instead be passed as an argument to L</new>. | 
| 1357 |  |  |  |  |  |  |  | 
| 1358 |  |  |  |  |  |  | my $form = HTML::FormFu->new({ | 
| 1359 |  |  |  |  |  |  | action        => '/search', | 
| 1360 |  |  |  |  |  |  | method        => 'GET', | 
| 1361 |  |  |  |  |  |  | auto_fieldset => 1, | 
| 1362 |  |  |  |  |  |  | }); | 
| 1363 |  |  |  |  |  |  |  | 
| 1364 |  |  |  |  |  |  | =head2 load_config_file | 
| 1365 |  |  |  |  |  |  |  | 
| 1366 |  |  |  |  |  |  | Arguments: $filename | 
| 1367 |  |  |  |  |  |  |  | 
| 1368 |  |  |  |  |  |  | Arguments: \@filenames | 
| 1369 |  |  |  |  |  |  |  | 
| 1370 |  |  |  |  |  |  | Return Value: $form | 
| 1371 |  |  |  |  |  |  |  | 
| 1372 |  |  |  |  |  |  | Accepts a filename or list of file names, whose filetypes should be of any | 
| 1373 |  |  |  |  |  |  | format recognized by L<Config::Any>. | 
| 1374 |  |  |  |  |  |  |  | 
| 1375 |  |  |  |  |  |  | The content of each config file is passed to L</populate>, and so are added | 
| 1376 |  |  |  |  |  |  | to the form. | 
| 1377 |  |  |  |  |  |  |  | 
| 1378 |  |  |  |  |  |  | L</load_config_file> may be called in a config file itself, so as to allow | 
| 1379 |  |  |  |  |  |  | common settings to be kept in a single config file which may be loaded | 
| 1380 |  |  |  |  |  |  | by any form. | 
| 1381 |  |  |  |  |  |  |  | 
| 1382 |  |  |  |  |  |  | --- | 
| 1383 |  |  |  |  |  |  | load_config_file: | 
| 1384 |  |  |  |  |  |  | - file1 | 
| 1385 |  |  |  |  |  |  | - file2 | 
| 1386 |  |  |  |  |  |  |  | 
| 1387 |  |  |  |  |  |  | YAML multiple documents within a single file. The document start marker is | 
| 1388 |  |  |  |  |  |  | a line containing 3 dashes. Multiple documents will be applied in order, | 
| 1389 |  |  |  |  |  |  | just as if multiple filenames had been given. | 
| 1390 |  |  |  |  |  |  |  | 
| 1391 |  |  |  |  |  |  | In the following example, multiple documents are taken advantage of to | 
| 1392 |  |  |  |  |  |  | load another config file after the elements are added. (If this were | 
| 1393 |  |  |  |  |  |  | a single document, the C<load_config_file> would be called before | 
| 1394 |  |  |  |  |  |  | C<elements>, regardless of its position in the file). | 
| 1395 |  |  |  |  |  |  |  | 
| 1396 |  |  |  |  |  |  | --- | 
| 1397 |  |  |  |  |  |  | elements: | 
| 1398 |  |  |  |  |  |  | - name: one | 
| 1399 |  |  |  |  |  |  | - name: two | 
| 1400 |  |  |  |  |  |  |  | 
| 1401 |  |  |  |  |  |  | --- | 
| 1402 |  |  |  |  |  |  | load_config_file: ext.yml | 
| 1403 |  |  |  |  |  |  |  | 
| 1404 |  |  |  |  |  |  | Relative paths are resolved from the L</config_file_path> directory if | 
| 1405 |  |  |  |  |  |  | it is set, otherwise from the current working directory. | 
| 1406 |  |  |  |  |  |  |  | 
| 1407 |  |  |  |  |  |  | See L</BEST PRACTICES> for advice on organising config files. | 
| 1408 |  |  |  |  |  |  |  | 
| 1409 |  |  |  |  |  |  | =head2 config_callback | 
| 1410 |  |  |  |  |  |  |  | 
| 1411 |  |  |  |  |  |  | Arguments: \%options | 
| 1412 |  |  |  |  |  |  |  | 
| 1413 |  |  |  |  |  |  | If defined, the arguments are used to create a L<Data::Visitor::Callback> | 
| 1414 |  |  |  |  |  |  | object during L</load_config_file> which may be used to pre-process the | 
| 1415 |  |  |  |  |  |  | config before it is sent to L</populate>. | 
| 1416 |  |  |  |  |  |  |  | 
| 1417 |  |  |  |  |  |  | For example, the code below adds a callback to a form that will dynamically | 
| 1418 |  |  |  |  |  |  | alter any config value ending in ".yml" to end in ".yaml" when you call | 
| 1419 |  |  |  |  |  |  | L</load_config_file>: | 
| 1420 |  |  |  |  |  |  |  | 
| 1421 |  |  |  |  |  |  | $form->config_callback({ | 
| 1422 |  |  |  |  |  |  | plain_value => sub { | 
| 1423 |  |  |  |  |  |  | my( $visitor, $data ) = @_; | 
| 1424 |  |  |  |  |  |  | s/\.yml/.yaml/; | 
| 1425 |  |  |  |  |  |  | } | 
| 1426 |  |  |  |  |  |  | }); | 
| 1427 |  |  |  |  |  |  |  | 
| 1428 |  |  |  |  |  |  | Default Value: not defined | 
| 1429 |  |  |  |  |  |  |  | 
| 1430 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 1431 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 1432 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 1433 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 1434 |  |  |  |  |  |  | defined value. | 
| 1435 |  |  |  |  |  |  |  | 
| 1436 |  |  |  |  |  |  | =head2 populate | 
| 1437 |  |  |  |  |  |  |  | 
| 1438 |  |  |  |  |  |  | Arguments: \%options | 
| 1439 |  |  |  |  |  |  |  | 
| 1440 |  |  |  |  |  |  | Return Value: $form | 
| 1441 |  |  |  |  |  |  |  | 
| 1442 |  |  |  |  |  |  | Each option key/value passed may be any L<HTML::FormFu|HTML::FormFu> | 
| 1443 |  |  |  |  |  |  | method-name and arguments. | 
| 1444 |  |  |  |  |  |  |  | 
| 1445 |  |  |  |  |  |  | Provides a simple way to set multiple values, or add multiple elements to | 
| 1446 |  |  |  |  |  |  | a form with a single method-call. | 
| 1447 |  |  |  |  |  |  |  | 
| 1448 |  |  |  |  |  |  | Attempts to call the method-names in a semi-intelligent order (see | 
| 1449 |  |  |  |  |  |  | the source of populate() in C<HTML::FormFu::ObjectUtil> for details). | 
| 1450 |  |  |  |  |  |  |  | 
| 1451 |  |  |  |  |  |  | =head2 default_values | 
| 1452 |  |  |  |  |  |  |  | 
| 1453 |  |  |  |  |  |  | Arguments: \%defaults | 
| 1454 |  |  |  |  |  |  |  | 
| 1455 |  |  |  |  |  |  | Return Value: $form | 
| 1456 |  |  |  |  |  |  |  | 
| 1457 |  |  |  |  |  |  | Set multiple field's default values from a single hash-ref. | 
| 1458 |  |  |  |  |  |  |  | 
| 1459 |  |  |  |  |  |  | The hash-ref's keys correspond to a form field's name, and the value is | 
| 1460 |  |  |  |  |  |  | passed to the field's L<default method|HTML::FormFu::_Field/default>. | 
| 1461 |  |  |  |  |  |  |  | 
| 1462 |  |  |  |  |  |  | This should be called after all fields have been added to the form, and | 
| 1463 |  |  |  |  |  |  | before L</process> is called (otherwise, call L</process> again before | 
| 1464 |  |  |  |  |  |  | rendering the form). | 
| 1465 |  |  |  |  |  |  |  | 
| 1466 |  |  |  |  |  |  | =head2 config_file_path | 
| 1467 |  |  |  |  |  |  |  | 
| 1468 |  |  |  |  |  |  | Arguments: $directory_name | 
| 1469 |  |  |  |  |  |  |  | 
| 1470 |  |  |  |  |  |  | L</config_file_path> defines where configuration files will be | 
| 1471 |  |  |  |  |  |  | searched for, if an absolute path is not given to | 
| 1472 |  |  |  |  |  |  | L</load_config_file>. | 
| 1473 |  |  |  |  |  |  |  | 
| 1474 |  |  |  |  |  |  | Default Value: not defined | 
| 1475 |  |  |  |  |  |  |  | 
| 1476 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 1477 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 1478 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 1479 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 1480 |  |  |  |  |  |  | defined value. | 
| 1481 |  |  |  |  |  |  |  | 
| 1482 |  |  |  |  |  |  | Is an L<inheriting accessor|/INHERITING ACCESSORS>. | 
| 1483 |  |  |  |  |  |  |  | 
| 1484 |  |  |  |  |  |  | =head2 indicator | 
| 1485 |  |  |  |  |  |  |  | 
| 1486 |  |  |  |  |  |  | Arguments: $field_name | 
| 1487 |  |  |  |  |  |  |  | 
| 1488 |  |  |  |  |  |  | Arguments: \&coderef | 
| 1489 |  |  |  |  |  |  |  | 
| 1490 |  |  |  |  |  |  | If L</indicator> is set to a fieldname, L</submitted> will return true if | 
| 1491 |  |  |  |  |  |  | a value for that fieldname was submitted. | 
| 1492 |  |  |  |  |  |  |  | 
| 1493 |  |  |  |  |  |  | If L</indicator> is set to a code-ref, it will be called as a subroutine | 
| 1494 |  |  |  |  |  |  | with the two arguments C<$form> and C<$query>, and its return value will be | 
| 1495 |  |  |  |  |  |  | used as the return value for L</submitted>. | 
| 1496 |  |  |  |  |  |  |  | 
| 1497 |  |  |  |  |  |  | If L</indicator> is not set, L</submitted> will return true if a value for | 
| 1498 |  |  |  |  |  |  | any known fieldname was submitted. | 
| 1499 |  |  |  |  |  |  |  | 
| 1500 |  |  |  |  |  |  | =head2 auto_fieldset | 
| 1501 |  |  |  |  |  |  |  | 
| 1502 |  |  |  |  |  |  | Arguments: 1 | 
| 1503 |  |  |  |  |  |  |  | 
| 1504 |  |  |  |  |  |  | Arguments: \%options | 
| 1505 |  |  |  |  |  |  |  | 
| 1506 |  |  |  |  |  |  | Return Value: $fieldset | 
| 1507 |  |  |  |  |  |  |  | 
| 1508 |  |  |  |  |  |  | This setting is suitable for most basic forms, and means you can generally | 
| 1509 |  |  |  |  |  |  | ignore adding fieldsets yourself. | 
| 1510 |  |  |  |  |  |  |  | 
| 1511 |  |  |  |  |  |  | Calling C<< $form->auto_fieldset(1) >> immediately adds a fieldset element to | 
| 1512 |  |  |  |  |  |  | the form. Thereafter, C<< $form->elements() >> will add all elements (except | 
| 1513 |  |  |  |  |  |  | fieldsets) to that fieldset, rather than directly to the form. | 
| 1514 |  |  |  |  |  |  |  | 
| 1515 |  |  |  |  |  |  | To be specific, the elements are added to the I<last> fieldset on the form, | 
| 1516 |  |  |  |  |  |  | so if you add another fieldset, any further elements will be added to that | 
| 1517 |  |  |  |  |  |  | fieldset. | 
| 1518 |  |  |  |  |  |  |  | 
| 1519 |  |  |  |  |  |  | Also, you may pass a hashref to auto_fieldset(), and this will be used | 
| 1520 |  |  |  |  |  |  | to set defaults for the first fieldset created. | 
| 1521 |  |  |  |  |  |  |  | 
| 1522 |  |  |  |  |  |  | A few examples and their output, to demonstrate: | 
| 1523 |  |  |  |  |  |  |  | 
| 1524 |  |  |  |  |  |  | 2 elements with no fieldset. | 
| 1525 |  |  |  |  |  |  |  | 
| 1526 |  |  |  |  |  |  | --- | 
| 1527 |  |  |  |  |  |  | elements: | 
| 1528 |  |  |  |  |  |  | - type: Text | 
| 1529 |  |  |  |  |  |  | name: foo | 
| 1530 |  |  |  |  |  |  | - type: Text | 
| 1531 |  |  |  |  |  |  | name: bar | 
| 1532 |  |  |  |  |  |  |  | 
| 1533 |  |  |  |  |  |  | <form action="" method="post"> | 
| 1534 |  |  |  |  |  |  | <div class="text"> | 
| 1535 |  |  |  |  |  |  | <input name="foo" type="text" /> | 
| 1536 |  |  |  |  |  |  | </div> | 
| 1537 |  |  |  |  |  |  | <div class="text"> | 
| 1538 |  |  |  |  |  |  | <input name="bar" type="text" /> | 
| 1539 |  |  |  |  |  |  | </div> | 
| 1540 |  |  |  |  |  |  | </form> | 
| 1541 |  |  |  |  |  |  |  | 
| 1542 |  |  |  |  |  |  | 2 elements with an L</auto_fieldset>. | 
| 1543 |  |  |  |  |  |  |  | 
| 1544 |  |  |  |  |  |  | --- | 
| 1545 |  |  |  |  |  |  | auto_fieldset: 1 | 
| 1546 |  |  |  |  |  |  | elements: | 
| 1547 |  |  |  |  |  |  | - type: Text | 
| 1548 |  |  |  |  |  |  | name: foo | 
| 1549 |  |  |  |  |  |  | - type: Text | 
| 1550 |  |  |  |  |  |  | name: bar | 
| 1551 |  |  |  |  |  |  |  | 
| 1552 |  |  |  |  |  |  | <form action="" method="post"> | 
| 1553 |  |  |  |  |  |  | <fieldset> | 
| 1554 |  |  |  |  |  |  | <div class="text"> | 
| 1555 |  |  |  |  |  |  | <input name="foo" type="text" /> | 
| 1556 |  |  |  |  |  |  | </div> | 
| 1557 |  |  |  |  |  |  | <div class="text"> | 
| 1558 |  |  |  |  |  |  | <input name="bar" type="text" /> | 
| 1559 |  |  |  |  |  |  | </div> | 
| 1560 |  |  |  |  |  |  | </fieldset> | 
| 1561 |  |  |  |  |  |  | </form> | 
| 1562 |  |  |  |  |  |  |  | 
| 1563 |  |  |  |  |  |  | The 3rd element is within a new fieldset | 
| 1564 |  |  |  |  |  |  |  | 
| 1565 |  |  |  |  |  |  | --- | 
| 1566 |  |  |  |  |  |  | auto_fieldset: { id: fs } | 
| 1567 |  |  |  |  |  |  | elements: | 
| 1568 |  |  |  |  |  |  | - type: Text | 
| 1569 |  |  |  |  |  |  | name: foo | 
| 1570 |  |  |  |  |  |  | - type: Text | 
| 1571 |  |  |  |  |  |  | name: bar | 
| 1572 |  |  |  |  |  |  | - type: Fieldset | 
| 1573 |  |  |  |  |  |  | - type: Text | 
| 1574 |  |  |  |  |  |  | name: baz | 
| 1575 |  |  |  |  |  |  |  | 
| 1576 |  |  |  |  |  |  | <form action="" method="post"> | 
| 1577 |  |  |  |  |  |  | <fieldset id="fs"> | 
| 1578 |  |  |  |  |  |  | <div class="text"> | 
| 1579 |  |  |  |  |  |  | <input name="foo" type="text" /> | 
| 1580 |  |  |  |  |  |  | </div> | 
| 1581 |  |  |  |  |  |  | <div class="text"> | 
| 1582 |  |  |  |  |  |  | <input name="bar" type="text" /> | 
| 1583 |  |  |  |  |  |  | </div> | 
| 1584 |  |  |  |  |  |  | </fieldset> | 
| 1585 |  |  |  |  |  |  | <fieldset> | 
| 1586 |  |  |  |  |  |  | <div class="text"> | 
| 1587 |  |  |  |  |  |  | <input name="baz" type="text" /> | 
| 1588 |  |  |  |  |  |  | </div> | 
| 1589 |  |  |  |  |  |  | </fieldset> | 
| 1590 |  |  |  |  |  |  | </form> | 
| 1591 |  |  |  |  |  |  |  | 
| 1592 |  |  |  |  |  |  | Because of this behaviour, if you want nested fieldsets you will have to add | 
| 1593 |  |  |  |  |  |  | each nested fieldset directly to its intended parent. | 
| 1594 |  |  |  |  |  |  |  | 
| 1595 |  |  |  |  |  |  | my $parent = $form->get_element({ type => 'Fieldset' }); | 
| 1596 |  |  |  |  |  |  |  | 
| 1597 |  |  |  |  |  |  | $parent->element('fieldset'); | 
| 1598 |  |  |  |  |  |  |  | 
| 1599 |  |  |  |  |  |  | =head2 form_error_message | 
| 1600 |  |  |  |  |  |  |  | 
| 1601 |  |  |  |  |  |  | Arguments: $string | 
| 1602 |  |  |  |  |  |  |  | 
| 1603 |  |  |  |  |  |  | Normally, input errors cause an error message to be displayed alongside the | 
| 1604 |  |  |  |  |  |  | appropriate form field. If you'd also like a general error message to be | 
| 1605 |  |  |  |  |  |  | displayed at the top of the form, you can set the message with | 
| 1606 |  |  |  |  |  |  | L</form_error_message>. | 
| 1607 |  |  |  |  |  |  |  | 
| 1608 |  |  |  |  |  |  | To set the CSS class for the message, see L</form_error_message_class>. | 
| 1609 |  |  |  |  |  |  |  | 
| 1610 |  |  |  |  |  |  | To change the markup used to display the message, edit the | 
| 1611 |  |  |  |  |  |  | C<form_error_message> template file. See L</render_method>. | 
| 1612 |  |  |  |  |  |  |  | 
| 1613 |  |  |  |  |  |  | Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>. | 
| 1614 |  |  |  |  |  |  |  | 
| 1615 |  |  |  |  |  |  | =head2 force_error_message | 
| 1616 |  |  |  |  |  |  |  | 
| 1617 |  |  |  |  |  |  | If true, forces the L</form_error_message> to be displayed even if there are | 
| 1618 |  |  |  |  |  |  | no field errors. | 
| 1619 |  |  |  |  |  |  |  | 
| 1620 |  |  |  |  |  |  | =head2 default_args | 
| 1621 |  |  |  |  |  |  |  | 
| 1622 |  |  |  |  |  |  | Arguments: \%defaults | 
| 1623 |  |  |  |  |  |  |  | 
| 1624 |  |  |  |  |  |  | Set defaults which will be added to every element, constraint, etc. of the | 
| 1625 |  |  |  |  |  |  | given type which is subsequently added to the form. | 
| 1626 |  |  |  |  |  |  |  | 
| 1627 |  |  |  |  |  |  | For example, to make every C<Text> element automatically have a size of | 
| 1628 |  |  |  |  |  |  | C<10>, and make every C<Strftime> deflator automatically get its strftime | 
| 1629 |  |  |  |  |  |  | set to C<%d/%m/%Y>: | 
| 1630 |  |  |  |  |  |  |  | 
| 1631 |  |  |  |  |  |  | default_args: | 
| 1632 |  |  |  |  |  |  | elements: | 
| 1633 |  |  |  |  |  |  | Text: | 
| 1634 |  |  |  |  |  |  | size: 10 | 
| 1635 |  |  |  |  |  |  | deflators: | 
| 1636 |  |  |  |  |  |  | Strftime: | 
| 1637 |  |  |  |  |  |  | strftime: '%d/%m/%Y' | 
| 1638 |  |  |  |  |  |  |  | 
| 1639 |  |  |  |  |  |  | An example to make all DateTime elements automatically get an appropriate | 
| 1640 |  |  |  |  |  |  | Strftime deflator and a DateTime inflator: | 
| 1641 |  |  |  |  |  |  |  | 
| 1642 |  |  |  |  |  |  | default_args: | 
| 1643 |  |  |  |  |  |  | elements: | 
| 1644 |  |  |  |  |  |  | DateTime: | 
| 1645 |  |  |  |  |  |  | deflators: | 
| 1646 |  |  |  |  |  |  | type: Strftime | 
| 1647 |  |  |  |  |  |  | strftime: '%d-%m-%Y' | 
| 1648 |  |  |  |  |  |  | inflators: | 
| 1649 |  |  |  |  |  |  | type: DateTime | 
| 1650 |  |  |  |  |  |  | parser: | 
| 1651 |  |  |  |  |  |  | strptime: '%d-%m-%Y' | 
| 1652 |  |  |  |  |  |  |  | 
| 1653 |  |  |  |  |  |  | =head3 Pseudo types | 
| 1654 |  |  |  |  |  |  |  | 
| 1655 |  |  |  |  |  |  | As a special case, you can also use the C<elements> keys C<Block>, C<Field> | 
| 1656 |  |  |  |  |  |  | and C<Input> to match any element which inherits from | 
| 1657 |  |  |  |  |  |  | L<HTML::FormFu::Element::Block> or which C<does> | 
| 1658 |  |  |  |  |  |  | L<HTML::FormFu::Role::Element::Field> or | 
| 1659 |  |  |  |  |  |  | L<HTML::FormFu::Role::Element::Input>. | 
| 1660 |  |  |  |  |  |  |  | 
| 1661 |  |  |  |  |  |  | =head3 Alternatives | 
| 1662 |  |  |  |  |  |  |  | 
| 1663 |  |  |  |  |  |  | Each C<elements> key can contain an C<any> list using the C<|> divider: e.g. | 
| 1664 |  |  |  |  |  |  |  | 
| 1665 |  |  |  |  |  |  | # apply the given class to any Element of type Password or Button | 
| 1666 |  |  |  |  |  |  | default_args: | 
| 1667 |  |  |  |  |  |  | elements: | 
| 1668 |  |  |  |  |  |  | 'Password|Button': | 
| 1669 |  |  |  |  |  |  | attrs: | 
| 1670 |  |  |  |  |  |  | class: novalidate | 
| 1671 |  |  |  |  |  |  |  | 
| 1672 |  |  |  |  |  |  | =head3 Match ancestor | 
| 1673 |  |  |  |  |  |  |  | 
| 1674 |  |  |  |  |  |  | Each C<elements> key list can contain a type starting with C<+> to only | 
| 1675 |  |  |  |  |  |  | match elements with an ancestor of the given type: e.g. | 
| 1676 |  |  |  |  |  |  |  | 
| 1677 |  |  |  |  |  |  | # only apple the given class to an Input field within a Multi block | 
| 1678 |  |  |  |  |  |  | default_args: | 
| 1679 |  |  |  |  |  |  | elements: | 
| 1680 |  |  |  |  |  |  | 'Input|+Multi': | 
| 1681 |  |  |  |  |  |  | attrs: | 
| 1682 |  |  |  |  |  |  | class: novalidate | 
| 1683 |  |  |  |  |  |  |  | 
| 1684 |  |  |  |  |  |  | =head3 Don't match ancestor | 
| 1685 |  |  |  |  |  |  |  | 
| 1686 |  |  |  |  |  |  | Each C<elements> key list can contain a type starting with C<-> to only | 
| 1687 |  |  |  |  |  |  | match elements who do not have an ancestor of the given type: e.g. | 
| 1688 |  |  |  |  |  |  |  | 
| 1689 |  |  |  |  |  |  | # apply the given class only to Input fields that are not in a Multi block | 
| 1690 |  |  |  |  |  |  | default_args: | 
| 1691 |  |  |  |  |  |  | elements: | 
| 1692 |  |  |  |  |  |  | 'Input|-Multi': | 
| 1693 |  |  |  |  |  |  | attrs: | 
| 1694 |  |  |  |  |  |  | clasS: validate | 
| 1695 |  |  |  |  |  |  |  | 
| 1696 |  |  |  |  |  |  | =head3 Order | 
| 1697 |  |  |  |  |  |  |  | 
| 1698 |  |  |  |  |  |  | The arguments are applied in least- to most-specific order: | 
| 1699 |  |  |  |  |  |  | C<Block>, C<Field>, C<Input>, C<$type>. Within each of these, arguments are | 
| 1700 |  |  |  |  |  |  | applied in order of shortest-first to longest-last. | 
| 1701 |  |  |  |  |  |  |  | 
| 1702 |  |  |  |  |  |  | The C<type> key must match the value returned by C<type>, e.g. | 
| 1703 |  |  |  |  |  |  | L<HTML::FormFu::Element/type>. If, for example, you have a custom element | 
| 1704 |  |  |  |  |  |  | outside of the C<HTML::FormFu::Element::*> namespace, which you load via | 
| 1705 |  |  |  |  |  |  | C<< $form->element({ type => '+My::Custom::Element' }) >>, the key given to | 
| 1706 |  |  |  |  |  |  | L</default_args> should B<not> include the leading C<+>, as that is | 
| 1707 |  |  |  |  |  |  | stripped-out of the returned C<type()> value. Example: | 
| 1708 |  |  |  |  |  |  |  | 
| 1709 |  |  |  |  |  |  | # don't include the leading '+' here | 
| 1710 |  |  |  |  |  |  | default_args: | 
| 1711 |  |  |  |  |  |  | elements: | 
| 1712 |  |  |  |  |  |  | 'My::Custom::Element': | 
| 1713 |  |  |  |  |  |  | attrs: | 
| 1714 |  |  |  |  |  |  | class: whatever | 
| 1715 |  |  |  |  |  |  |  | 
| 1716 |  |  |  |  |  |  | # do include the leading '+' here | 
| 1717 |  |  |  |  |  |  | elements: | 
| 1718 |  |  |  |  |  |  | - type: +My::Custom::Element | 
| 1719 |  |  |  |  |  |  |  | 
| 1720 |  |  |  |  |  |  | =head3 Clashes | 
| 1721 |  |  |  |  |  |  |  | 
| 1722 |  |  |  |  |  |  | L</default_args> generates a single hashref to pass to L</populate>, merging | 
| 1723 |  |  |  |  |  |  | arguments for each type in turn - meaning L</populate> is only called once | 
| 1724 |  |  |  |  |  |  | in total - not once for each type. | 
| 1725 |  |  |  |  |  |  | Because scalar values are B<not> merged - this means later values will | 
| 1726 |  |  |  |  |  |  | override earlier values: e.g. | 
| 1727 |  |  |  |  |  |  |  | 
| 1728 |  |  |  |  |  |  | # Normally, calling $field->add_attrs({ class => 'input' }) | 
| 1729 |  |  |  |  |  |  | # then calling      $field->add_attrs({ class => 'not-in-multi' }) | 
| 1730 |  |  |  |  |  |  | # would result in both values being retained: | 
| 1731 |  |  |  |  |  |  | #           class="input not-in-multi" | 
| 1732 |  |  |  |  |  |  | # | 
| 1733 |  |  |  |  |  |  | # However, default_args() creates a single data-structure to pass once | 
| 1734 |  |  |  |  |  |  | # to populate(), so any scalar values will overwrite earlier ones | 
| 1735 |  |  |  |  |  |  | # before they reach populate(). | 
| 1736 |  |  |  |  |  |  | # | 
| 1737 |  |  |  |  |  |  | # The below example would result in the longest-matching key | 
| 1738 |  |  |  |  |  |  | # overwriting any others: | 
| 1739 |  |  |  |  |  |  | #           class="not-in-multi" | 
| 1740 |  |  |  |  |  |  | # | 
| 1741 |  |  |  |  |  |  | default_args: | 
| 1742 |  |  |  |  |  |  | elements: | 
| 1743 |  |  |  |  |  |  | Input: | 
| 1744 |  |  |  |  |  |  | add_attrs: | 
| 1745 |  |  |  |  |  |  | class: input | 
| 1746 |  |  |  |  |  |  | 'Input:-Multi': | 
| 1747 |  |  |  |  |  |  | add_attrs: | 
| 1748 |  |  |  |  |  |  | class: not-in-multi | 
| 1749 |  |  |  |  |  |  |  | 
| 1750 |  |  |  |  |  |  | =head3 Strictness | 
| 1751 |  |  |  |  |  |  |  | 
| 1752 |  |  |  |  |  |  | Note: Unlike the proper methods which have aliases, for example L</elements> | 
| 1753 |  |  |  |  |  |  | which is an alias for L</element> - the keys given to C<default_args> must | 
| 1754 |  |  |  |  |  |  | be of the plural form, e.g.: | 
| 1755 |  |  |  |  |  |  |  | 
| 1756 |  |  |  |  |  |  | default_args: | 
| 1757 |  |  |  |  |  |  | elements:          {} | 
| 1758 |  |  |  |  |  |  | deflators:         {} | 
| 1759 |  |  |  |  |  |  | filters:           {} | 
| 1760 |  |  |  |  |  |  | constraints:       {} | 
| 1761 |  |  |  |  |  |  | inflators:         {} | 
| 1762 |  |  |  |  |  |  | validators:        {} | 
| 1763 |  |  |  |  |  |  | transformers:      {} | 
| 1764 |  |  |  |  |  |  | output_processors: {} | 
| 1765 |  |  |  |  |  |  |  | 
| 1766 |  |  |  |  |  |  | =head2 javascript | 
| 1767 |  |  |  |  |  |  |  | 
| 1768 |  |  |  |  |  |  | If set, the contents will be rendered within a C<script> tag, inside the top | 
| 1769 |  |  |  |  |  |  | of the form. | 
| 1770 |  |  |  |  |  |  |  | 
| 1771 |  |  |  |  |  |  | =head2 javascript_src | 
| 1772 |  |  |  |  |  |  |  | 
| 1773 |  |  |  |  |  |  | Arguments: $url | 
| 1774 |  |  |  |  |  |  |  | 
| 1775 |  |  |  |  |  |  | Arguments: \@urls | 
| 1776 |  |  |  |  |  |  |  | 
| 1777 |  |  |  |  |  |  | Adds a C<script> tag for each URL, immediately before any L</javascript> | 
| 1778 |  |  |  |  |  |  | section. | 
| 1779 |  |  |  |  |  |  |  | 
| 1780 |  |  |  |  |  |  | =head2 stash | 
| 1781 |  |  |  |  |  |  |  | 
| 1782 |  |  |  |  |  |  | Arguments: [\%private_stash] | 
| 1783 |  |  |  |  |  |  |  | 
| 1784 |  |  |  |  |  |  | Return Value: \%stash | 
| 1785 |  |  |  |  |  |  |  | 
| 1786 |  |  |  |  |  |  | Provides a hash-ref in which you can store any data you might want to | 
| 1787 |  |  |  |  |  |  | associate with the form. | 
| 1788 |  |  |  |  |  |  |  | 
| 1789 |  |  |  |  |  |  | --- | 
| 1790 |  |  |  |  |  |  | stash: | 
| 1791 |  |  |  |  |  |  | foo: value | 
| 1792 |  |  |  |  |  |  | bar: value | 
| 1793 |  |  |  |  |  |  |  | 
| 1794 |  |  |  |  |  |  | =head2 elements | 
| 1795 |  |  |  |  |  |  |  | 
| 1796 |  |  |  |  |  |  | =head2 element | 
| 1797 |  |  |  |  |  |  |  | 
| 1798 |  |  |  |  |  |  | Arguments: $type | 
| 1799 |  |  |  |  |  |  |  | 
| 1800 |  |  |  |  |  |  | Arguments: \%options | 
| 1801 |  |  |  |  |  |  |  | 
| 1802 |  |  |  |  |  |  | Return Value: $element | 
| 1803 |  |  |  |  |  |  |  | 
| 1804 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 1805 |  |  |  |  |  |  |  | 
| 1806 |  |  |  |  |  |  | Return Value: @elements | 
| 1807 |  |  |  |  |  |  |  | 
| 1808 |  |  |  |  |  |  | Adds a new element to the form. See | 
| 1809 |  |  |  |  |  |  | L<HTML::FormFu::Element/"CORE FORM FIELDS"> and | 
| 1810 |  |  |  |  |  |  | L<HTML::FormFu::Element/"OTHER CORE ELEMENTS"> | 
| 1811 |  |  |  |  |  |  | for a list of core elements. | 
| 1812 |  |  |  |  |  |  |  | 
| 1813 |  |  |  |  |  |  | If you want to load an element from a namespace other than | 
| 1814 |  |  |  |  |  |  | C<HTML::FormFu::Element::>, you can use a fully qualified package-name by | 
| 1815 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 1816 |  |  |  |  |  |  |  | 
| 1817 |  |  |  |  |  |  | --- | 
| 1818 |  |  |  |  |  |  | elements: | 
| 1819 |  |  |  |  |  |  | - type: +MyApp::CustomElement | 
| 1820 |  |  |  |  |  |  | name: foo | 
| 1821 |  |  |  |  |  |  |  | 
| 1822 |  |  |  |  |  |  | If a C<type> is not provided in the C<\%options>, the default C<Text> will | 
| 1823 |  |  |  |  |  |  | be used. | 
| 1824 |  |  |  |  |  |  |  | 
| 1825 |  |  |  |  |  |  | L</element> is an alias for L</elements>. | 
| 1826 |  |  |  |  |  |  |  | 
| 1827 |  |  |  |  |  |  | =head2 deflators | 
| 1828 |  |  |  |  |  |  |  | 
| 1829 |  |  |  |  |  |  | =head2 deflator | 
| 1830 |  |  |  |  |  |  |  | 
| 1831 |  |  |  |  |  |  | Arguments: $type | 
| 1832 |  |  |  |  |  |  |  | 
| 1833 |  |  |  |  |  |  | Arguments: \%options | 
| 1834 |  |  |  |  |  |  |  | 
| 1835 |  |  |  |  |  |  | Return Value: $deflator | 
| 1836 |  |  |  |  |  |  |  | 
| 1837 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 1838 |  |  |  |  |  |  |  | 
| 1839 |  |  |  |  |  |  | Return Value: @deflators | 
| 1840 |  |  |  |  |  |  |  | 
| 1841 |  |  |  |  |  |  | A L<deflator|HTML::FormFu::Deflator> may be associated with any form field, | 
| 1842 |  |  |  |  |  |  | and allows you to provide | 
| 1843 |  |  |  |  |  |  | L<< $field->default|HTML::FormFu::Role::Element::Field/default >> with a value | 
| 1844 |  |  |  |  |  |  | which may be an object. | 
| 1845 |  |  |  |  |  |  |  | 
| 1846 |  |  |  |  |  |  | If an object doesn't stringify to a suitable value for display, the | 
| 1847 |  |  |  |  |  |  | L<deflator|HTML::FormFu::Deflator> can ensure that the form field | 
| 1848 |  |  |  |  |  |  | receives a suitable string value instead. | 
| 1849 |  |  |  |  |  |  |  | 
| 1850 |  |  |  |  |  |  | See L<HTML::FormFu::Deflator/"CORE DEFLATORS"> for a list of core deflators. | 
| 1851 |  |  |  |  |  |  |  | 
| 1852 |  |  |  |  |  |  | If a C<name> attribute isn't provided, a new deflator is created for and | 
| 1853 |  |  |  |  |  |  | added to every field on the form. | 
| 1854 |  |  |  |  |  |  |  | 
| 1855 |  |  |  |  |  |  | If you want to load a deflator in a namespace other than | 
| 1856 |  |  |  |  |  |  | C<HTML::FormFu::Deflator::>, you can use a fully qualified package-name by | 
| 1857 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 1858 |  |  |  |  |  |  |  | 
| 1859 |  |  |  |  |  |  | L</deflator> is an alias for L</deflators>. | 
| 1860 |  |  |  |  |  |  |  | 
| 1861 |  |  |  |  |  |  | =head2 insert_before | 
| 1862 |  |  |  |  |  |  |  | 
| 1863 |  |  |  |  |  |  | Arguments: $new_element, $existing_element | 
| 1864 |  |  |  |  |  |  |  | 
| 1865 |  |  |  |  |  |  | Return Value: $new_element | 
| 1866 |  |  |  |  |  |  |  | 
| 1867 |  |  |  |  |  |  | The 1st argument must be the element you want added, the 2nd argument | 
| 1868 |  |  |  |  |  |  | must be the existing element that the new element should be placed before. | 
| 1869 |  |  |  |  |  |  |  | 
| 1870 |  |  |  |  |  |  | my $new = $form->element(\%specs); | 
| 1871 |  |  |  |  |  |  |  | 
| 1872 |  |  |  |  |  |  | my $position = $form->get_element({ type => $type, name => $name }); | 
| 1873 |  |  |  |  |  |  |  | 
| 1874 |  |  |  |  |  |  | $form->insert_before( $new, $position ); | 
| 1875 |  |  |  |  |  |  |  | 
| 1876 |  |  |  |  |  |  | In the first line of the above example, the C<$new> element is initially | 
| 1877 |  |  |  |  |  |  | added to the end of the form. However, the C<insert_before> method | 
| 1878 |  |  |  |  |  |  | reparents the C<$new> element, so it will no longer be on the end of the | 
| 1879 |  |  |  |  |  |  | form. Because of this, if you try to copy an element from one form to | 
| 1880 |  |  |  |  |  |  | another, it will 'steal' the element, instead of copying it. In this case, | 
| 1881 |  |  |  |  |  |  | you must use C<clone>: | 
| 1882 |  |  |  |  |  |  |  | 
| 1883 |  |  |  |  |  |  | my $new = $form1->get_element({ type => $type1, name => $name1 }) | 
| 1884 |  |  |  |  |  |  | ->clone; | 
| 1885 |  |  |  |  |  |  |  | 
| 1886 |  |  |  |  |  |  | my $position = $form2->get_element({ type => $type2, name => $name2 }); | 
| 1887 |  |  |  |  |  |  |  | 
| 1888 |  |  |  |  |  |  | $form2->insert_before( $new, $position ); | 
| 1889 |  |  |  |  |  |  |  | 
| 1890 |  |  |  |  |  |  | =head2 insert_after | 
| 1891 |  |  |  |  |  |  |  | 
| 1892 |  |  |  |  |  |  | Arguments: $new_element, $existing_element | 
| 1893 |  |  |  |  |  |  |  | 
| 1894 |  |  |  |  |  |  | Return Value: $new_element | 
| 1895 |  |  |  |  |  |  |  | 
| 1896 |  |  |  |  |  |  | The 1st argument must be the element you want added, the 2nd argument | 
| 1897 |  |  |  |  |  |  | must be the existing element that the new element should be placed after. | 
| 1898 |  |  |  |  |  |  |  | 
| 1899 |  |  |  |  |  |  | my $new = $form->element(\%specs); | 
| 1900 |  |  |  |  |  |  |  | 
| 1901 |  |  |  |  |  |  | my $position = $form->get_element({ type => $type, name => $name }); | 
| 1902 |  |  |  |  |  |  |  | 
| 1903 |  |  |  |  |  |  | $form->insert_after( $new, $position ); | 
| 1904 |  |  |  |  |  |  |  | 
| 1905 |  |  |  |  |  |  | In the first line of the above example, the C<$new> element is initially | 
| 1906 |  |  |  |  |  |  | added to the end of the form. However, the C<insert_after> method | 
| 1907 |  |  |  |  |  |  | reparents the C<$new> element, so it will no longer be on the end of the | 
| 1908 |  |  |  |  |  |  | form. Because of this, if you try to copy an element from one form to | 
| 1909 |  |  |  |  |  |  | another, it will 'steal' the element, instead of copying it. In this case, | 
| 1910 |  |  |  |  |  |  | you must use C<clone>: | 
| 1911 |  |  |  |  |  |  |  | 
| 1912 |  |  |  |  |  |  | my $new = $form1->get_element({ type => $type1, name => $name1 }) | 
| 1913 |  |  |  |  |  |  | ->clone; | 
| 1914 |  |  |  |  |  |  |  | 
| 1915 |  |  |  |  |  |  | my $position = $form2->get_element({ type => $type2, name => $name2 }); | 
| 1916 |  |  |  |  |  |  |  | 
| 1917 |  |  |  |  |  |  | $form2->insert_after( $new, $position ); | 
| 1918 |  |  |  |  |  |  |  | 
| 1919 |  |  |  |  |  |  | =head2 remove_element | 
| 1920 |  |  |  |  |  |  |  | 
| 1921 |  |  |  |  |  |  | Arguments: $element | 
| 1922 |  |  |  |  |  |  |  | 
| 1923 |  |  |  |  |  |  | Return Value: $element | 
| 1924 |  |  |  |  |  |  |  | 
| 1925 |  |  |  |  |  |  | Removes the C<$element> from the form or block's array of children. | 
| 1926 |  |  |  |  |  |  |  | 
| 1927 |  |  |  |  |  |  | $form->remove_element( $element ); | 
| 1928 |  |  |  |  |  |  |  | 
| 1929 |  |  |  |  |  |  | The orphaned element cannot be usefully used for anything until it is | 
| 1930 |  |  |  |  |  |  | re-attached to a form or block with L</insert_before> or L</insert_after>. | 
| 1931 |  |  |  |  |  |  |  | 
| 1932 |  |  |  |  |  |  | =head1 FORM LOGIC AND VALIDATION | 
| 1933 |  |  |  |  |  |  |  | 
| 1934 |  |  |  |  |  |  | L<HTML::FormFu|HTML::FormFu> provides several stages for what is | 
| 1935 |  |  |  |  |  |  | traditionally described as I<validation>. These are: | 
| 1936 |  |  |  |  |  |  |  | 
| 1937 |  |  |  |  |  |  | =over | 
| 1938 |  |  |  |  |  |  |  | 
| 1939 |  |  |  |  |  |  | =item L<HTML::FormFu::Filter|HTML::FormFu::Filter> | 
| 1940 |  |  |  |  |  |  |  | 
| 1941 |  |  |  |  |  |  | =item L<HTML::FormFu::Constraint|HTML::FormFu::Constraint> | 
| 1942 |  |  |  |  |  |  |  | 
| 1943 |  |  |  |  |  |  | =item L<HTML::FormFu::Inflator|HTML::FormFu::Inflator> | 
| 1944 |  |  |  |  |  |  |  | 
| 1945 |  |  |  |  |  |  | =item L<HTML::FormFu::Validator|HTML::FormFu::Validator> | 
| 1946 |  |  |  |  |  |  |  | 
| 1947 |  |  |  |  |  |  | =item L<HTML::FormFu::Transformer|HTML::FormFu::Transformer> | 
| 1948 |  |  |  |  |  |  |  | 
| 1949 |  |  |  |  |  |  | =back | 
| 1950 |  |  |  |  |  |  |  | 
| 1951 |  |  |  |  |  |  | The first stage, the filters, allow for cleanup of user-input, such as | 
| 1952 |  |  |  |  |  |  | encoding, or removing leading/trailing whitespace, or removing non-digit | 
| 1953 |  |  |  |  |  |  | characters from a creditcard number. | 
| 1954 |  |  |  |  |  |  |  | 
| 1955 |  |  |  |  |  |  | All of the following stages allow for more complex processing, and each of | 
| 1956 |  |  |  |  |  |  | them have a mechanism to allow exceptions to be thrown, to represent input | 
| 1957 |  |  |  |  |  |  | errors. In each stage, all form fields must be processed without error for | 
| 1958 |  |  |  |  |  |  | the next stage to proceed. If there were any errors, the form should be | 
| 1959 |  |  |  |  |  |  | re-displayed to the user, to allow them to input correct values. | 
| 1960 |  |  |  |  |  |  |  | 
| 1961 |  |  |  |  |  |  | Constraints are intended for low-level validation of values, such as | 
| 1962 |  |  |  |  |  |  | "is this an integer?", "is this value within bounds?" or | 
| 1963 |  |  |  |  |  |  | "is this a valid email address?". | 
| 1964 |  |  |  |  |  |  |  | 
| 1965 |  |  |  |  |  |  | Inflators are intended to allow a value to be turned into an appropriate | 
| 1966 |  |  |  |  |  |  | object. The resulting object will be passed to subsequent Validators and | 
| 1967 |  |  |  |  |  |  | Transformers, and will also be returned by L</params> and L</param>. | 
| 1968 |  |  |  |  |  |  |  | 
| 1969 |  |  |  |  |  |  | Validators are intended for higher-level validation, such as | 
| 1970 |  |  |  |  |  |  | business-logic and database constraints such as "is this username unique?". | 
| 1971 |  |  |  |  |  |  | Validators are only run if all Constraints and Inflators have run | 
| 1972 |  |  |  |  |  |  | without errors. It is expected that most Validators will be | 
| 1973 |  |  |  |  |  |  | application-specific, and so each will be implemented as a separate class | 
| 1974 |  |  |  |  |  |  | written by the HTML::FormFu user. | 
| 1975 |  |  |  |  |  |  |  | 
| 1976 |  |  |  |  |  |  | =head2 filters | 
| 1977 |  |  |  |  |  |  |  | 
| 1978 |  |  |  |  |  |  | =head2 filter | 
| 1979 |  |  |  |  |  |  |  | 
| 1980 |  |  |  |  |  |  | Arguments: $type | 
| 1981 |  |  |  |  |  |  |  | 
| 1982 |  |  |  |  |  |  | Arguments: \%options | 
| 1983 |  |  |  |  |  |  |  | 
| 1984 |  |  |  |  |  |  | Return Value: $filter | 
| 1985 |  |  |  |  |  |  |  | 
| 1986 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 1987 |  |  |  |  |  |  |  | 
| 1988 |  |  |  |  |  |  | Return Value: @filters | 
| 1989 |  |  |  |  |  |  |  | 
| 1990 |  |  |  |  |  |  | If you provide a C<name> or C<names> value, the filter will be added to | 
| 1991 |  |  |  |  |  |  | just that named field. | 
| 1992 |  |  |  |  |  |  | If you do not provide a C<name> or C<names> value, the filter will be added | 
| 1993 |  |  |  |  |  |  | to all L<fields|HTML::FormFu::Role::Element::Field> already attached to the form. | 
| 1994 |  |  |  |  |  |  |  | 
| 1995 |  |  |  |  |  |  | See L<HTML::FormFu::Filter/"CORE FILTERS"> for a list of core filters. | 
| 1996 |  |  |  |  |  |  |  | 
| 1997 |  |  |  |  |  |  | If you want to load a filter in a namespace other than | 
| 1998 |  |  |  |  |  |  | C<HTML::FormFu::Filter::>, you can use a fully qualified package-name by | 
| 1999 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 2000 |  |  |  |  |  |  |  | 
| 2001 |  |  |  |  |  |  | L</filter> is an alias for L</filters>. | 
| 2002 |  |  |  |  |  |  |  | 
| 2003 |  |  |  |  |  |  | =head2 constraints | 
| 2004 |  |  |  |  |  |  |  | 
| 2005 |  |  |  |  |  |  | =head2 constraint | 
| 2006 |  |  |  |  |  |  |  | 
| 2007 |  |  |  |  |  |  | Arguments: $type | 
| 2008 |  |  |  |  |  |  |  | 
| 2009 |  |  |  |  |  |  | Arguments: \%options | 
| 2010 |  |  |  |  |  |  |  | 
| 2011 |  |  |  |  |  |  | Return Value: $constraint | 
| 2012 |  |  |  |  |  |  |  | 
| 2013 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 2014 |  |  |  |  |  |  |  | 
| 2015 |  |  |  |  |  |  | Return Value: @constraints | 
| 2016 |  |  |  |  |  |  |  | 
| 2017 |  |  |  |  |  |  | See L<HTML::FormFu::Constraint/"CORE CONSTRAINTS"> for a list of core | 
| 2018 |  |  |  |  |  |  | constraints. | 
| 2019 |  |  |  |  |  |  |  | 
| 2020 |  |  |  |  |  |  | If a C<name> attribute isn't provided, a new constraint is created for and | 
| 2021 |  |  |  |  |  |  | added to every field on the form. | 
| 2022 |  |  |  |  |  |  |  | 
| 2023 |  |  |  |  |  |  | If you want to load a constraint in a namespace other than | 
| 2024 |  |  |  |  |  |  | C<HTML::FormFu::Constraint::>, you can use a fully qualified package-name by | 
| 2025 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 2026 |  |  |  |  |  |  |  | 
| 2027 |  |  |  |  |  |  | L</constraint> is an alias for L</constraints>. | 
| 2028 |  |  |  |  |  |  |  | 
| 2029 |  |  |  |  |  |  | =head2 inflators | 
| 2030 |  |  |  |  |  |  |  | 
| 2031 |  |  |  |  |  |  | =head2 inflator | 
| 2032 |  |  |  |  |  |  |  | 
| 2033 |  |  |  |  |  |  | Arguments: $type | 
| 2034 |  |  |  |  |  |  |  | 
| 2035 |  |  |  |  |  |  | Arguments: \%options | 
| 2036 |  |  |  |  |  |  |  | 
| 2037 |  |  |  |  |  |  | Return Value: $inflator | 
| 2038 |  |  |  |  |  |  |  | 
| 2039 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 2040 |  |  |  |  |  |  |  | 
| 2041 |  |  |  |  |  |  | Return Value: @inflators | 
| 2042 |  |  |  |  |  |  |  | 
| 2043 |  |  |  |  |  |  | See L<HTML::FormFu::Inflator/"CORE INFLATORS"> for a list of core inflators. | 
| 2044 |  |  |  |  |  |  |  | 
| 2045 |  |  |  |  |  |  | If a C<name> attribute isn't provided, a new inflator is created for and | 
| 2046 |  |  |  |  |  |  | added to every field on the form. | 
| 2047 |  |  |  |  |  |  |  | 
| 2048 |  |  |  |  |  |  | If you want to load an inflator in a namespace other than | 
| 2049 |  |  |  |  |  |  | C<HTML::FormFu::Inflator::>, you can use a fully qualified package-name by | 
| 2050 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 2051 |  |  |  |  |  |  |  | 
| 2052 |  |  |  |  |  |  | L</inflator> is an alias for L</inflators>. | 
| 2053 |  |  |  |  |  |  |  | 
| 2054 |  |  |  |  |  |  | =head2 validators | 
| 2055 |  |  |  |  |  |  |  | 
| 2056 |  |  |  |  |  |  | =head2 validator | 
| 2057 |  |  |  |  |  |  |  | 
| 2058 |  |  |  |  |  |  | Arguments: $type | 
| 2059 |  |  |  |  |  |  |  | 
| 2060 |  |  |  |  |  |  | Arguments: \%options | 
| 2061 |  |  |  |  |  |  |  | 
| 2062 |  |  |  |  |  |  | Return Value: $validator | 
| 2063 |  |  |  |  |  |  |  | 
| 2064 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 2065 |  |  |  |  |  |  |  | 
| 2066 |  |  |  |  |  |  | Return Value: @validators | 
| 2067 |  |  |  |  |  |  |  | 
| 2068 |  |  |  |  |  |  | See L<HTML::FormFu::Validator/"CORE VALIDATORS"> for a list of core | 
| 2069 |  |  |  |  |  |  | validators. | 
| 2070 |  |  |  |  |  |  |  | 
| 2071 |  |  |  |  |  |  | If a C<name> attribute isn't provided, a new validator is created for and | 
| 2072 |  |  |  |  |  |  | added to every field on the form. | 
| 2073 |  |  |  |  |  |  |  | 
| 2074 |  |  |  |  |  |  | If you want to load a validator in a namespace other than | 
| 2075 |  |  |  |  |  |  | C<HTML::FormFu::Validator::>, you can use a fully qualified package-name by | 
| 2076 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 2077 |  |  |  |  |  |  |  | 
| 2078 |  |  |  |  |  |  | L</validator> is an alias for L</validators>. | 
| 2079 |  |  |  |  |  |  |  | 
| 2080 |  |  |  |  |  |  | =head2 transformers | 
| 2081 |  |  |  |  |  |  |  | 
| 2082 |  |  |  |  |  |  | =head2 transformer | 
| 2083 |  |  |  |  |  |  |  | 
| 2084 |  |  |  |  |  |  | Arguments: $type | 
| 2085 |  |  |  |  |  |  |  | 
| 2086 |  |  |  |  |  |  | Arguments: \%options | 
| 2087 |  |  |  |  |  |  |  | 
| 2088 |  |  |  |  |  |  | Return Value: $transformer | 
| 2089 |  |  |  |  |  |  |  | 
| 2090 |  |  |  |  |  |  | Arguments: \@arrayref_of_types_or_options | 
| 2091 |  |  |  |  |  |  |  | 
| 2092 |  |  |  |  |  |  | Return Value: @transformers | 
| 2093 |  |  |  |  |  |  |  | 
| 2094 |  |  |  |  |  |  | See L<HTML::FormFu::Transformer/"CORE TRANSFORMERS"> for a list of core | 
| 2095 |  |  |  |  |  |  | transformers. | 
| 2096 |  |  |  |  |  |  |  | 
| 2097 |  |  |  |  |  |  | If a C<name> attribute isn't provided, a new transformer is created for and | 
| 2098 |  |  |  |  |  |  | added to every field on the form. | 
| 2099 |  |  |  |  |  |  |  | 
| 2100 |  |  |  |  |  |  | If you want to load a transformer in a namespace other than | 
| 2101 |  |  |  |  |  |  | C<HTML::FormFu::Transformer::>, you can use a fully qualified package-name by | 
| 2102 |  |  |  |  |  |  | prefixing it with C<+>. | 
| 2103 |  |  |  |  |  |  |  | 
| 2104 |  |  |  |  |  |  | L</transformer> is an alias for L</transformers>. | 
| 2105 |  |  |  |  |  |  |  | 
| 2106 |  |  |  |  |  |  | =head1 CHANGING DEFAULT BEHAVIOUR | 
| 2107 |  |  |  |  |  |  |  | 
| 2108 |  |  |  |  |  |  | =head2 render_processed_value | 
| 2109 |  |  |  |  |  |  |  | 
| 2110 |  |  |  |  |  |  | The default behaviour when re-displaying a form after a submission, is that | 
| 2111 |  |  |  |  |  |  | the field contains the original unchanged user-submitted value. | 
| 2112 |  |  |  |  |  |  |  | 
| 2113 |  |  |  |  |  |  | If L</render_processed_value> is true, the field value will be the final | 
| 2114 |  |  |  |  |  |  | result after all Filters, Inflators and Transformers have been run. | 
| 2115 |  |  |  |  |  |  | Deflators will also be run on the value. | 
| 2116 |  |  |  |  |  |  |  | 
| 2117 |  |  |  |  |  |  | If you set this on a field with an Inflator, but without an equivalent | 
| 2118 |  |  |  |  |  |  | Deflator, you should ensure that the Inflators stringify back to a usable | 
| 2119 |  |  |  |  |  |  | value, so as not to confuse / annoy the user. | 
| 2120 |  |  |  |  |  |  |  | 
| 2121 |  |  |  |  |  |  | Default Value: false | 
| 2122 |  |  |  |  |  |  |  | 
| 2123 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2124 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 2125 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 2126 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 2127 |  |  |  |  |  |  | defined value. | 
| 2128 |  |  |  |  |  |  |  | 
| 2129 |  |  |  |  |  |  | Is an L<inheriting accessor|/INHERITING ACCESSORS>. | 
| 2130 |  |  |  |  |  |  |  | 
| 2131 |  |  |  |  |  |  | =head2 force_errors | 
| 2132 |  |  |  |  |  |  |  | 
| 2133 |  |  |  |  |  |  | Force a constraint to fail, regardless of user input. | 
| 2134 |  |  |  |  |  |  |  | 
| 2135 |  |  |  |  |  |  | If this is called at runtime, after the form has already been processed, | 
| 2136 |  |  |  |  |  |  | you must called L<HTML::FormFu/process> again before redisplaying the | 
| 2137 |  |  |  |  |  |  | form to the user. | 
| 2138 |  |  |  |  |  |  |  | 
| 2139 |  |  |  |  |  |  | Default Value: false | 
| 2140 |  |  |  |  |  |  |  | 
| 2141 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2142 |  |  |  |  |  |  | the form, a block element, an element or a single constraint. When the value | 
| 2143 |  |  |  |  |  |  | is read, if no value is defined it automatically traverses the element's | 
| 2144 |  |  |  |  |  |  | hierarchy of parents, through any block elements and up to the form, | 
| 2145 |  |  |  |  |  |  | searching for a defined value. | 
| 2146 |  |  |  |  |  |  |  | 
| 2147 |  |  |  |  |  |  | Is an L<inheriting accessor|/INHERITING ACCESSORS>. | 
| 2148 |  |  |  |  |  |  |  | 
| 2149 |  |  |  |  |  |  | =head2 params_ignore_underscore | 
| 2150 |  |  |  |  |  |  |  | 
| 2151 |  |  |  |  |  |  | If true, causes L</params>, L</param> and L</valid> to ignore any fields | 
| 2152 |  |  |  |  |  |  | whose name starts with an underscore C<_>. | 
| 2153 |  |  |  |  |  |  |  | 
| 2154 |  |  |  |  |  |  | The field is still processed as normal, and errors will cause | 
| 2155 |  |  |  |  |  |  | L</submitted_and_valid> to return false. | 
| 2156 |  |  |  |  |  |  |  | 
| 2157 |  |  |  |  |  |  | Default Value: false | 
| 2158 |  |  |  |  |  |  |  | 
| 2159 |  |  |  |  |  |  | =head1 FORM ATTRIBUTES | 
| 2160 |  |  |  |  |  |  |  | 
| 2161 |  |  |  |  |  |  | All attributes are added to the rendered form's start tag. | 
| 2162 |  |  |  |  |  |  |  | 
| 2163 |  |  |  |  |  |  | =head2 attributes | 
| 2164 |  |  |  |  |  |  |  | 
| 2165 |  |  |  |  |  |  | # Example | 
| 2166 |  |  |  |  |  |  | --- | 
| 2167 |  |  |  |  |  |  | attributes: | 
| 2168 |  |  |  |  |  |  | id: form | 
| 2169 |  |  |  |  |  |  | class: fancy_form | 
| 2170 |  |  |  |  |  |  |  | 
| 2171 |  |  |  |  |  |  | Is an L<attribute accessor|HTML::FormFu/ATTRIBUTE ACCESSOR>. | 
| 2172 |  |  |  |  |  |  |  | 
| 2173 |  |  |  |  |  |  | =head2 id | 
| 2174 |  |  |  |  |  |  |  | 
| 2175 |  |  |  |  |  |  | Is an L<attribute short-cut|HTML::FormFu/ATTRIBUTE SHORT-CUTS>. | 
| 2176 |  |  |  |  |  |  |  | 
| 2177 |  |  |  |  |  |  | =head2 action | 
| 2178 |  |  |  |  |  |  |  | 
| 2179 |  |  |  |  |  |  | Default Value: "" | 
| 2180 |  |  |  |  |  |  |  | 
| 2181 |  |  |  |  |  |  | Get or set the action associated with the form. The default is no action, | 
| 2182 |  |  |  |  |  |  | which causes most browsers to submit to the current URI. | 
| 2183 |  |  |  |  |  |  |  | 
| 2184 |  |  |  |  |  |  | Is an L<attribute short-cut|HTML::FormFu/ATTRIBUTE SHORT-CUTS>. | 
| 2185 |  |  |  |  |  |  |  | 
| 2186 |  |  |  |  |  |  | =head2 enctype | 
| 2187 |  |  |  |  |  |  |  | 
| 2188 |  |  |  |  |  |  | Get or set the encoding type of the form. Valid values are | 
| 2189 |  |  |  |  |  |  | C<application/x-www-form-urlencoded> and C<multipart/form-data>. | 
| 2190 |  |  |  |  |  |  |  | 
| 2191 |  |  |  |  |  |  | If the form contains a File element, the enctype is automatically set to | 
| 2192 |  |  |  |  |  |  | C<multipart/form-data>. | 
| 2193 |  |  |  |  |  |  |  | 
| 2194 |  |  |  |  |  |  | Is an L<attribute short-cut|HTML::FormFu/ATTRIBUTE SHORT-CUTS>. | 
| 2195 |  |  |  |  |  |  |  | 
| 2196 |  |  |  |  |  |  | =head2 method | 
| 2197 |  |  |  |  |  |  |  | 
| 2198 |  |  |  |  |  |  | Default Value: "post" | 
| 2199 |  |  |  |  |  |  |  | 
| 2200 |  |  |  |  |  |  | Get or set the method used to submit the form. Can be set to either "post" | 
| 2201 |  |  |  |  |  |  | or "get". | 
| 2202 |  |  |  |  |  |  |  | 
| 2203 |  |  |  |  |  |  | Is an L<attribute short-cut|HTML::FormFu/ATTRIBUTE SHORT-CUTS>. | 
| 2204 |  |  |  |  |  |  |  | 
| 2205 |  |  |  |  |  |  | =head2 title | 
| 2206 |  |  |  |  |  |  |  | 
| 2207 |  |  |  |  |  |  | Get or set the form's title attribute. | 
| 2208 |  |  |  |  |  |  |  | 
| 2209 |  |  |  |  |  |  | Is an L<attribute short-cut|HTML::FormFu/ATTRIBUTE SHORT-CUTS>. | 
| 2210 |  |  |  |  |  |  |  | 
| 2211 |  |  |  |  |  |  | =head1 CSS CLASSES | 
| 2212 |  |  |  |  |  |  |  | 
| 2213 |  |  |  |  |  |  | =head2 form_error_message_class | 
| 2214 |  |  |  |  |  |  |  | 
| 2215 |  |  |  |  |  |  | Class attribute for the error message displayed at the top of the form. | 
| 2216 |  |  |  |  |  |  |  | 
| 2217 |  |  |  |  |  |  | See L</"form_error_message"> | 
| 2218 |  |  |  |  |  |  |  | 
| 2219 |  |  |  |  |  |  | =head1 LOCALIZATION | 
| 2220 |  |  |  |  |  |  |  | 
| 2221 |  |  |  |  |  |  | =head2 languages | 
| 2222 |  |  |  |  |  |  |  | 
| 2223 |  |  |  |  |  |  | Arguments: [\@languages] | 
| 2224 |  |  |  |  |  |  |  | 
| 2225 |  |  |  |  |  |  | A list of languages which will be passed to the localization object. | 
| 2226 |  |  |  |  |  |  |  | 
| 2227 |  |  |  |  |  |  | Default Value: ['en'] | 
| 2228 |  |  |  |  |  |  |  | 
| 2229 |  |  |  |  |  |  | =head2 localize_class | 
| 2230 |  |  |  |  |  |  |  | 
| 2231 |  |  |  |  |  |  | Arguments: [$class_name] | 
| 2232 |  |  |  |  |  |  |  | 
| 2233 |  |  |  |  |  |  | Classname to be used for the default localization object. | 
| 2234 |  |  |  |  |  |  |  | 
| 2235 |  |  |  |  |  |  | Default Value: 'HTML::FormFu::I18N' | 
| 2236 |  |  |  |  |  |  |  | 
| 2237 |  |  |  |  |  |  | =head2 localize | 
| 2238 |  |  |  |  |  |  |  | 
| 2239 |  |  |  |  |  |  | =head2 loc | 
| 2240 |  |  |  |  |  |  |  | 
| 2241 |  |  |  |  |  |  | Arguments: [$key, @arguments] | 
| 2242 |  |  |  |  |  |  |  | 
| 2243 |  |  |  |  |  |  | Compatible with the C<maketext> method in L<Locale::Maketext>. | 
| 2244 |  |  |  |  |  |  |  | 
| 2245 |  |  |  |  |  |  | =head2 locale | 
| 2246 |  |  |  |  |  |  |  | 
| 2247 |  |  |  |  |  |  | Arguments: $locale | 
| 2248 |  |  |  |  |  |  |  | 
| 2249 |  |  |  |  |  |  | Currently only used by L<HTML::FormFu::Deflator::FormatNumber> and | 
| 2250 |  |  |  |  |  |  | L<HTML::FormFu::Filter::FormatNumber>. | 
| 2251 |  |  |  |  |  |  |  | 
| 2252 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2253 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 2254 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 2255 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 2256 |  |  |  |  |  |  | defined value. | 
| 2257 |  |  |  |  |  |  |  | 
| 2258 |  |  |  |  |  |  | Is an L<inheriting accessor|/INHERITING ACCESSORS>. | 
| 2259 |  |  |  |  |  |  |  | 
| 2260 |  |  |  |  |  |  | =head1 PROCESSING A FORM | 
| 2261 |  |  |  |  |  |  |  | 
| 2262 |  |  |  |  |  |  | =head2 query | 
| 2263 |  |  |  |  |  |  |  | 
| 2264 |  |  |  |  |  |  | Arguments: [$query_object] | 
| 2265 |  |  |  |  |  |  |  | 
| 2266 |  |  |  |  |  |  | Arguments: \%params | 
| 2267 |  |  |  |  |  |  |  | 
| 2268 |  |  |  |  |  |  | Provide a L<CGI> compatible query object or a hash-ref of submitted | 
| 2269 |  |  |  |  |  |  | names/values. Alternatively, the query object can be passed directly to the | 
| 2270 |  |  |  |  |  |  | L</process> object. | 
| 2271 |  |  |  |  |  |  |  | 
| 2272 |  |  |  |  |  |  | =head2 query_type | 
| 2273 |  |  |  |  |  |  |  | 
| 2274 |  |  |  |  |  |  | Arguments: [$query_type] | 
| 2275 |  |  |  |  |  |  |  | 
| 2276 |  |  |  |  |  |  | Set which module is being used to provide the L</query>. | 
| 2277 |  |  |  |  |  |  |  | 
| 2278 |  |  |  |  |  |  | The L<Catalyst::Controller::HTML::FormFu> automatically sets this to | 
| 2279 |  |  |  |  |  |  | C<Catalyst>. | 
| 2280 |  |  |  |  |  |  |  | 
| 2281 |  |  |  |  |  |  | Valid values are C<CGI>, C<Catalyst> and C<CGI::Simple>. | 
| 2282 |  |  |  |  |  |  |  | 
| 2283 |  |  |  |  |  |  | Default Value: 'CGI' | 
| 2284 |  |  |  |  |  |  |  | 
| 2285 |  |  |  |  |  |  | =head2 process | 
| 2286 |  |  |  |  |  |  |  | 
| 2287 |  |  |  |  |  |  | Arguments: [$query_object] | 
| 2288 |  |  |  |  |  |  |  | 
| 2289 |  |  |  |  |  |  | Arguments: [\%params] | 
| 2290 |  |  |  |  |  |  |  | 
| 2291 |  |  |  |  |  |  | Process the provided query object or input values. C<process> must be called | 
| 2292 |  |  |  |  |  |  | before calling any of the methods listed under | 
| 2293 |  |  |  |  |  |  | L</"SUBMITTED FORM VALUES AND ERRORS"> and L</"MODIFYING A SUBMITTED FORM">. | 
| 2294 |  |  |  |  |  |  |  | 
| 2295 |  |  |  |  |  |  | C<process> must also be called at least once before printing the form or | 
| 2296 |  |  |  |  |  |  | calling L</render> or L</render_data>. | 
| 2297 |  |  |  |  |  |  |  | 
| 2298 |  |  |  |  |  |  | Note to users of L<Catalyst::Controller::HTML::FormFu>: Because L</process> | 
| 2299 |  |  |  |  |  |  | is automatically called for you by the Catalyst controller; if you make any | 
| 2300 |  |  |  |  |  |  | modifications to the form within your action method, such as adding or changing | 
| 2301 |  |  |  |  |  |  | elements, adding constraints, etc; you must call L</process> again yourself | 
| 2302 |  |  |  |  |  |  | before using L</submitted_and_valid>, any of the methods listed under | 
| 2303 |  |  |  |  |  |  | L</"SUBMITTED FORM VALUES AND ERRORS"> or | 
| 2304 |  |  |  |  |  |  | L</"MODIFYING A SUBMITTED FORM">, or rendering the form. | 
| 2305 |  |  |  |  |  |  |  | 
| 2306 |  |  |  |  |  |  | =head1 SUBMITTED FORM VALUES AND ERRORS | 
| 2307 |  |  |  |  |  |  |  | 
| 2308 |  |  |  |  |  |  | =head2 submitted | 
| 2309 |  |  |  |  |  |  |  | 
| 2310 |  |  |  |  |  |  | Returns true if the form has been submitted. See L</indicator> for details | 
| 2311 |  |  |  |  |  |  | on how this is computed. | 
| 2312 |  |  |  |  |  |  |  | 
| 2313 |  |  |  |  |  |  | =head2 submitted_and_valid | 
| 2314 |  |  |  |  |  |  |  | 
| 2315 |  |  |  |  |  |  | Shorthand for C<< $form->submitted && !$form->has_errors >> | 
| 2316 |  |  |  |  |  |  |  | 
| 2317 |  |  |  |  |  |  | =head2 params | 
| 2318 |  |  |  |  |  |  |  | 
| 2319 |  |  |  |  |  |  | Return Value: \%params | 
| 2320 |  |  |  |  |  |  |  | 
| 2321 |  |  |  |  |  |  | Returns a hash-ref of all valid input for which there were no errors. | 
| 2322 |  |  |  |  |  |  |  | 
| 2323 |  |  |  |  |  |  | =head2 param_value | 
| 2324 |  |  |  |  |  |  |  | 
| 2325 |  |  |  |  |  |  | Arguments: $field_name | 
| 2326 |  |  |  |  |  |  |  | 
| 2327 |  |  |  |  |  |  | A more reliable, recommended version of L</param>. Guaranteed to always return a | 
| 2328 |  |  |  |  |  |  | single value, regardless of whether it's called in list context or not. If | 
| 2329 |  |  |  |  |  |  | multiple values were submitted, this only returns the first value. If the value | 
| 2330 |  |  |  |  |  |  | is invalid or the form was not submitted, it returns C<undef>. This makes it | 
| 2331 |  |  |  |  |  |  | suitable for use in list context, where a single value is required. | 
| 2332 |  |  |  |  |  |  |  | 
| 2333 |  |  |  |  |  |  | $db->update({ | 
| 2334 |  |  |  |  |  |  | name    => $form->param_value('name'), | 
| 2335 |  |  |  |  |  |  | address => $form->param_value('address), | 
| 2336 |  |  |  |  |  |  | }); | 
| 2337 |  |  |  |  |  |  |  | 
| 2338 |  |  |  |  |  |  | =head2 param_array | 
| 2339 |  |  |  |  |  |  |  | 
| 2340 |  |  |  |  |  |  | Arguments: $field_name | 
| 2341 |  |  |  |  |  |  |  | 
| 2342 |  |  |  |  |  |  | Guaranteed to always return an array-ref of values, regardless of context and | 
| 2343 |  |  |  |  |  |  | regardless of whether multiple values were submitted or not. If the value is | 
| 2344 |  |  |  |  |  |  | invalid or the form was not submitted, it returns an empty array-ref. | 
| 2345 |  |  |  |  |  |  |  | 
| 2346 |  |  |  |  |  |  | =head2 param_list | 
| 2347 |  |  |  |  |  |  |  | 
| 2348 |  |  |  |  |  |  | Arguments: $field_name | 
| 2349 |  |  |  |  |  |  |  | 
| 2350 |  |  |  |  |  |  | Guaranteed to always return a list of values, regardless of context. If the value is | 
| 2351 |  |  |  |  |  |  | invalid or the form was not submitted, it returns an empty list. | 
| 2352 |  |  |  |  |  |  |  | 
| 2353 |  |  |  |  |  |  | =head2 param | 
| 2354 |  |  |  |  |  |  |  | 
| 2355 |  |  |  |  |  |  | Arguments: [$field_name] | 
| 2356 |  |  |  |  |  |  |  | 
| 2357 |  |  |  |  |  |  | Return Value: $input_value | 
| 2358 |  |  |  |  |  |  |  | 
| 2359 |  |  |  |  |  |  | Return Value: @valid_names | 
| 2360 |  |  |  |  |  |  |  | 
| 2361 |  |  |  |  |  |  | No longer recommended for use, as its behaviour is hard to predict. Use | 
| 2362 |  |  |  |  |  |  | L</param_value>, L</param_array> or L</param_list> instead. | 
| 2363 |  |  |  |  |  |  |  | 
| 2364 |  |  |  |  |  |  | A (readonly) method similar to that of L<CGI's|CGI>. | 
| 2365 |  |  |  |  |  |  |  | 
| 2366 |  |  |  |  |  |  | If a field name is given, in list-context returns any valid values submitted | 
| 2367 |  |  |  |  |  |  | for that field, and in scalar-context returns only the first of any valid | 
| 2368 |  |  |  |  |  |  | values submitted for that field. | 
| 2369 |  |  |  |  |  |  |  | 
| 2370 |  |  |  |  |  |  | If no argument is given, returns a list of all valid input field names | 
| 2371 |  |  |  |  |  |  | without errors. | 
| 2372 |  |  |  |  |  |  |  | 
| 2373 |  |  |  |  |  |  | Passing more than 1 argument is a fatal error. | 
| 2374 |  |  |  |  |  |  |  | 
| 2375 |  |  |  |  |  |  | =head2 valid | 
| 2376 |  |  |  |  |  |  |  | 
| 2377 |  |  |  |  |  |  | Arguments: [$field_name] | 
| 2378 |  |  |  |  |  |  |  | 
| 2379 |  |  |  |  |  |  | Return Value: @valid_names | 
| 2380 |  |  |  |  |  |  |  | 
| 2381 |  |  |  |  |  |  | Return Value: $bool | 
| 2382 |  |  |  |  |  |  |  | 
| 2383 |  |  |  |  |  |  | If a field name if given, returns C<true> if that field had no errors and | 
| 2384 |  |  |  |  |  |  | C<false> if there were errors. | 
| 2385 |  |  |  |  |  |  |  | 
| 2386 |  |  |  |  |  |  | If no argument is given, returns a list of all valid input field names | 
| 2387 |  |  |  |  |  |  | without errors. | 
| 2388 |  |  |  |  |  |  |  | 
| 2389 |  |  |  |  |  |  | =head2 has_errors | 
| 2390 |  |  |  |  |  |  |  | 
| 2391 |  |  |  |  |  |  | Arguments: [$field_name] | 
| 2392 |  |  |  |  |  |  |  | 
| 2393 |  |  |  |  |  |  | Return Value: @names | 
| 2394 |  |  |  |  |  |  |  | 
| 2395 |  |  |  |  |  |  | Return Value: $bool | 
| 2396 |  |  |  |  |  |  |  | 
| 2397 |  |  |  |  |  |  | If a field name if given, returns C<true> if that field had errors and | 
| 2398 |  |  |  |  |  |  | C<false> if there were no errors. | 
| 2399 |  |  |  |  |  |  |  | 
| 2400 |  |  |  |  |  |  | If no argument is given, returns a list of all input field names with errors. | 
| 2401 |  |  |  |  |  |  |  | 
| 2402 |  |  |  |  |  |  | =head2 get_errors | 
| 2403 |  |  |  |  |  |  |  | 
| 2404 |  |  |  |  |  |  | Arguments: [%options] | 
| 2405 |  |  |  |  |  |  |  | 
| 2406 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2407 |  |  |  |  |  |  |  | 
| 2408 |  |  |  |  |  |  | Return Value: \@errors | 
| 2409 |  |  |  |  |  |  |  | 
| 2410 |  |  |  |  |  |  | Returns an array-ref of exception objects from all fields in the form. | 
| 2411 |  |  |  |  |  |  |  | 
| 2412 |  |  |  |  |  |  | Accepts both C<name>, C<type> and C<stage> arguments to narrow the returned | 
| 2413 |  |  |  |  |  |  | results. | 
| 2414 |  |  |  |  |  |  |  | 
| 2415 |  |  |  |  |  |  | $form->get_errors({ | 
| 2416 |  |  |  |  |  |  | name  => 'foo', | 
| 2417 |  |  |  |  |  |  | type  => 'Regex', | 
| 2418 |  |  |  |  |  |  | stage => 'constraint' | 
| 2419 |  |  |  |  |  |  | }); | 
| 2420 |  |  |  |  |  |  |  | 
| 2421 |  |  |  |  |  |  | =head2 get_error | 
| 2422 |  |  |  |  |  |  |  | 
| 2423 |  |  |  |  |  |  | Arguments: [%options] | 
| 2424 |  |  |  |  |  |  |  | 
| 2425 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2426 |  |  |  |  |  |  |  | 
| 2427 |  |  |  |  |  |  | Return Value: $error | 
| 2428 |  |  |  |  |  |  |  | 
| 2429 |  |  |  |  |  |  | Accepts the same arguments as L</get_errors>, but only returns the first | 
| 2430 |  |  |  |  |  |  | error found. | 
| 2431 |  |  |  |  |  |  |  | 
| 2432 |  |  |  |  |  |  | =head1 MODEL / DATABASE INTERACTION | 
| 2433 |  |  |  |  |  |  |  | 
| 2434 |  |  |  |  |  |  | See L<HTML::FormFu::Model> for further details and available models. | 
| 2435 |  |  |  |  |  |  |  | 
| 2436 |  |  |  |  |  |  | =head2 default_model | 
| 2437 |  |  |  |  |  |  |  | 
| 2438 |  |  |  |  |  |  | Arguments: $model_name | 
| 2439 |  |  |  |  |  |  |  | 
| 2440 |  |  |  |  |  |  | Default Value: 'DBIC' | 
| 2441 |  |  |  |  |  |  |  | 
| 2442 |  |  |  |  |  |  | =head2 model | 
| 2443 |  |  |  |  |  |  |  | 
| 2444 |  |  |  |  |  |  | Arguments: [$model_name] | 
| 2445 |  |  |  |  |  |  |  | 
| 2446 |  |  |  |  |  |  | Return Value: $model | 
| 2447 |  |  |  |  |  |  |  | 
| 2448 |  |  |  |  |  |  | =head2 model_config | 
| 2449 |  |  |  |  |  |  |  | 
| 2450 |  |  |  |  |  |  | Arguments: \%config | 
| 2451 |  |  |  |  |  |  |  | 
| 2452 |  |  |  |  |  |  | =head1 MODIFYING A SUBMITTED FORM | 
| 2453 |  |  |  |  |  |  |  | 
| 2454 |  |  |  |  |  |  | =head2 add_valid | 
| 2455 |  |  |  |  |  |  |  | 
| 2456 |  |  |  |  |  |  | Arguments: $name, $value | 
| 2457 |  |  |  |  |  |  |  | 
| 2458 |  |  |  |  |  |  | Return Value: $value | 
| 2459 |  |  |  |  |  |  |  | 
| 2460 |  |  |  |  |  |  | The provided value replaces any current value for the named field. This | 
| 2461 |  |  |  |  |  |  | value will be returned in subsequent calls to L</params> and L</param> and | 
| 2462 |  |  |  |  |  |  | the named field will be included in calculations for L</valid>. | 
| 2463 |  |  |  |  |  |  |  | 
| 2464 |  |  |  |  |  |  | =head2 clear_errors | 
| 2465 |  |  |  |  |  |  |  | 
| 2466 |  |  |  |  |  |  | Deletes all errors from a submitted form. | 
| 2467 |  |  |  |  |  |  |  | 
| 2468 |  |  |  |  |  |  | =head1 RENDERING A FORM | 
| 2469 |  |  |  |  |  |  |  | 
| 2470 |  |  |  |  |  |  | =head2 render | 
| 2471 |  |  |  |  |  |  |  | 
| 2472 |  |  |  |  |  |  | Return Value: $string | 
| 2473 |  |  |  |  |  |  |  | 
| 2474 |  |  |  |  |  |  | You must call L</process> once after building the form, and before calling | 
| 2475 |  |  |  |  |  |  | L</render>. | 
| 2476 |  |  |  |  |  |  |  | 
| 2477 |  |  |  |  |  |  | =head2 start | 
| 2478 |  |  |  |  |  |  |  | 
| 2479 |  |  |  |  |  |  | Return Value: $string | 
| 2480 |  |  |  |  |  |  |  | 
| 2481 |  |  |  |  |  |  | Returns the form start tag, and any output of L</form_error_message> and | 
| 2482 |  |  |  |  |  |  | L</javascript>. | 
| 2483 |  |  |  |  |  |  |  | 
| 2484 |  |  |  |  |  |  | =head2 end | 
| 2485 |  |  |  |  |  |  |  | 
| 2486 |  |  |  |  |  |  | Return Value: $string | 
| 2487 |  |  |  |  |  |  |  | 
| 2488 |  |  |  |  |  |  | Returns the form end tag. | 
| 2489 |  |  |  |  |  |  |  | 
| 2490 |  |  |  |  |  |  | =head2 hidden_fields | 
| 2491 |  |  |  |  |  |  |  | 
| 2492 |  |  |  |  |  |  | Return Value: $string | 
| 2493 |  |  |  |  |  |  |  | 
| 2494 |  |  |  |  |  |  | Returns all hidden form fields. | 
| 2495 |  |  |  |  |  |  |  | 
| 2496 |  |  |  |  |  |  | =head1 PLUGIN SYSTEM | 
| 2497 |  |  |  |  |  |  |  | 
| 2498 |  |  |  |  |  |  | C<HTML::FormFu> provides a plugin-system that allows plugins to be easily | 
| 2499 |  |  |  |  |  |  | added to a form or element, to change the default behaviour or output. | 
| 2500 |  |  |  |  |  |  |  | 
| 2501 |  |  |  |  |  |  | See L<HTML::FormFu::Plugin> for details. | 
| 2502 |  |  |  |  |  |  |  | 
| 2503 |  |  |  |  |  |  | =head1 ADVANCED CUSTOMISATION | 
| 2504 |  |  |  |  |  |  |  | 
| 2505 |  |  |  |  |  |  | By default, formfu renders "XHTML 1.0 Strict" compliant markup, with as | 
| 2506 |  |  |  |  |  |  | little extra markup as possible. Many hooks are provided to add | 
| 2507 |  |  |  |  |  |  | programatically-generated CSS class names, to allow for a wide-range of | 
| 2508 |  |  |  |  |  |  | output styles to be generated by changing only the CSS. | 
| 2509 |  |  |  |  |  |  |  | 
| 2510 |  |  |  |  |  |  | Basic customisation of the markup is possible via the | 
| 2511 |  |  |  |  |  |  | L<layout|HTML::FormFu::Role::Element::Field/layout> and | 
| 2512 |  |  |  |  |  |  | L<multi_layout|HTML::FormFu::Role::Element::Field/multi_layout> methods. | 
| 2513 |  |  |  |  |  |  | This allows you to reorder the position of various parts of each field - | 
| 2514 |  |  |  |  |  |  | such as the label, comment, error messages and the input tag - as well | 
| 2515 |  |  |  |  |  |  | as inserting any other arbitrary tags you may wish. | 
| 2516 |  |  |  |  |  |  |  | 
| 2517 |  |  |  |  |  |  | If this is not sufficient, you can make completely personalise the markup | 
| 2518 |  |  |  |  |  |  | by telling HTML::FormFu to use an external rendering engine, such as | 
| 2519 |  |  |  |  |  |  | L<Template Toolkit|Template> or L<Template::Alloy>. | 
| 2520 |  |  |  |  |  |  | See L</render_method> and L</tt_module> for details. | 
| 2521 |  |  |  |  |  |  |  | 
| 2522 |  |  |  |  |  |  | Even if you set HTML::FormFu to use L<Template::Toolkit|Template> to render, | 
| 2523 |  |  |  |  |  |  | the forms, HTML::FormFu can still be used in conjunction with whichever other | 
| 2524 |  |  |  |  |  |  | templating system you prefer to use for your own page layouts, whether it's | 
| 2525 |  |  |  |  |  |  | L<HTML::Template>: C<< <TMPL_VAR form> >>, | 
| 2526 |  |  |  |  |  |  | L<Petal>: C<< <form tal:replace="form"></form> >> | 
| 2527 |  |  |  |  |  |  | or L<Template::Magic>: C<< <!-- {form} --> >>. | 
| 2528 |  |  |  |  |  |  |  | 
| 2529 |  |  |  |  |  |  | As of C<HTML::FormFu v1.00>, L<TT|Template> is no longer listed a required | 
| 2530 |  |  |  |  |  |  | prerequisite - so you'll need to install it manually if you with to use the | 
| 2531 |  |  |  |  |  |  | template files. | 
| 2532 |  |  |  |  |  |  |  | 
| 2533 |  |  |  |  |  |  | =head2 render_method | 
| 2534 |  |  |  |  |  |  |  | 
| 2535 |  |  |  |  |  |  | Default Value: C<string> | 
| 2536 |  |  |  |  |  |  |  | 
| 2537 |  |  |  |  |  |  | Can be set to C<tt> to generate the form with external template files. | 
| 2538 |  |  |  |  |  |  |  | 
| 2539 |  |  |  |  |  |  | To customise the markup, you'll need a copy of the template files, local to | 
| 2540 |  |  |  |  |  |  | your application. See | 
| 2541 |  |  |  |  |  |  | L<HTML::FormFu::Manual::Cookbook/"Installing the TT templates"> for further | 
| 2542 |  |  |  |  |  |  | details. | 
| 2543 |  |  |  |  |  |  |  | 
| 2544 |  |  |  |  |  |  | You can customise the markup for a single element by setting that element's | 
| 2545 |  |  |  |  |  |  | L</render_method> to C<tt>, while the rest of the form uses the default | 
| 2546 |  |  |  |  |  |  | C<string> render-method. Note though, that if you try setting the form or a | 
| 2547 |  |  |  |  |  |  | Block's L</render_method> to C<tt>, and then set a child element's | 
| 2548 |  |  |  |  |  |  | L</render_method> to C<string>, that setting will be ignored, and the child | 
| 2549 |  |  |  |  |  |  | elements will still use the C<tt> render-method. | 
| 2550 |  |  |  |  |  |  |  | 
| 2551 |  |  |  |  |  |  | --- | 
| 2552 |  |  |  |  |  |  | elements: | 
| 2553 |  |  |  |  |  |  | - name: foo | 
| 2554 |  |  |  |  |  |  | render_method: tt | 
| 2555 |  |  |  |  |  |  | filename: custom_field | 
| 2556 |  |  |  |  |  |  |  | 
| 2557 |  |  |  |  |  |  | - name: bar | 
| 2558 |  |  |  |  |  |  |  | 
| 2559 |  |  |  |  |  |  | # in this example, 'foo' will use a custom template, | 
| 2560 |  |  |  |  |  |  | # while bar will use the default 'string' rendering method | 
| 2561 |  |  |  |  |  |  |  | 
| 2562 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2563 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 2564 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 2565 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 2566 |  |  |  |  |  |  | defined value. | 
| 2567 |  |  |  |  |  |  |  | 
| 2568 |  |  |  |  |  |  | Is an L<inheriting accessor|/INHERITING ACCESSORS>. | 
| 2569 |  |  |  |  |  |  |  | 
| 2570 |  |  |  |  |  |  | =head2 filename | 
| 2571 |  |  |  |  |  |  |  | 
| 2572 |  |  |  |  |  |  | Change the template filename used for the form. | 
| 2573 |  |  |  |  |  |  |  | 
| 2574 |  |  |  |  |  |  | Default Value: "form" | 
| 2575 |  |  |  |  |  |  |  | 
| 2576 |  |  |  |  |  |  | =head2 tt_args | 
| 2577 |  |  |  |  |  |  |  | 
| 2578 |  |  |  |  |  |  | Arguments: [\%constructor_arguments] | 
| 2579 |  |  |  |  |  |  |  | 
| 2580 |  |  |  |  |  |  | Accepts a hash-ref of arguments passed to L</render_method>, which is called | 
| 2581 |  |  |  |  |  |  | internally by L</render>. | 
| 2582 |  |  |  |  |  |  |  | 
| 2583 |  |  |  |  |  |  | Within tt_args, the keys C<RELATIVE> and C<RECURSION> are overridden to always | 
| 2584 |  |  |  |  |  |  | be true, as these are a basic requirement for the L<Template> engine. | 
| 2585 |  |  |  |  |  |  |  | 
| 2586 |  |  |  |  |  |  | The system directory containing HTML::FormFu's template files is always | 
| 2587 |  |  |  |  |  |  | added to the end of C<INCLUDE_PATH>, so that the core template files will be | 
| 2588 |  |  |  |  |  |  | found. You only need to set this yourself if you have your own copy of the | 
| 2589 |  |  |  |  |  |  | template files for customisation purposes. | 
| 2590 |  |  |  |  |  |  |  | 
| 2591 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2592 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 2593 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 2594 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 2595 |  |  |  |  |  |  | defined value. | 
| 2596 |  |  |  |  |  |  |  | 
| 2597 |  |  |  |  |  |  | =head2 add_tt_args | 
| 2598 |  |  |  |  |  |  |  | 
| 2599 |  |  |  |  |  |  | Arguments: [\%constructor_arguments] | 
| 2600 |  |  |  |  |  |  |  | 
| 2601 |  |  |  |  |  |  | Ensures that the hash-ref argument is merged with any existing hash-ref | 
| 2602 |  |  |  |  |  |  | value of L</tt_args>. | 
| 2603 |  |  |  |  |  |  |  | 
| 2604 |  |  |  |  |  |  | =head2 tt_module | 
| 2605 |  |  |  |  |  |  |  | 
| 2606 |  |  |  |  |  |  | Default Value: Template | 
| 2607 |  |  |  |  |  |  |  | 
| 2608 |  |  |  |  |  |  | The module used when L</render_method> is set to C<tt>. Should provide an | 
| 2609 |  |  |  |  |  |  | interface compatible with L<Template>. | 
| 2610 |  |  |  |  |  |  |  | 
| 2611 |  |  |  |  |  |  | This method is a special 'inherited accessor', which means it can be set on | 
| 2612 |  |  |  |  |  |  | the form, a block element or a single element. When the value is read, if | 
| 2613 |  |  |  |  |  |  | no value is defined it automatically traverses the element's hierarchy of | 
| 2614 |  |  |  |  |  |  | parents, through any block elements and up to the form, searching for a | 
| 2615 |  |  |  |  |  |  | defined value. | 
| 2616 |  |  |  |  |  |  |  | 
| 2617 |  |  |  |  |  |  | =head2 render_data | 
| 2618 |  |  |  |  |  |  |  | 
| 2619 |  |  |  |  |  |  | Usually called implicitly by L</render>. Returns the data structure that | 
| 2620 |  |  |  |  |  |  | would normally be passed onto the C<string> or C<tt> render-methods. | 
| 2621 |  |  |  |  |  |  |  | 
| 2622 |  |  |  |  |  |  | As with L</render>, you must call L</process> once after building the form, | 
| 2623 |  |  |  |  |  |  | and before calling L</render_data>. | 
| 2624 |  |  |  |  |  |  |  | 
| 2625 |  |  |  |  |  |  | =head2 render_data_non_recursive | 
| 2626 |  |  |  |  |  |  |  | 
| 2627 |  |  |  |  |  |  | Like L</render_data>, but doesn't include the data for any child-elements. | 
| 2628 |  |  |  |  |  |  |  | 
| 2629 |  |  |  |  |  |  | =head1 INTROSPECTION | 
| 2630 |  |  |  |  |  |  |  | 
| 2631 |  |  |  |  |  |  | =head2 get_fields | 
| 2632 |  |  |  |  |  |  |  | 
| 2633 |  |  |  |  |  |  | Arguments: [%options] | 
| 2634 |  |  |  |  |  |  |  | 
| 2635 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2636 |  |  |  |  |  |  |  | 
| 2637 |  |  |  |  |  |  | Return Value: \@elements | 
| 2638 |  |  |  |  |  |  |  | 
| 2639 |  |  |  |  |  |  | Returns all fields in the form (specifically, all elements which have a true | 
| 2640 |  |  |  |  |  |  | L<HTML::FormFu::Element/is_field> value). | 
| 2641 |  |  |  |  |  |  |  | 
| 2642 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2643 |  |  |  |  |  |  |  | 
| 2644 |  |  |  |  |  |  | $form->get_fields({ | 
| 2645 |  |  |  |  |  |  | name => 'foo', | 
| 2646 |  |  |  |  |  |  | type => 'Radio', | 
| 2647 |  |  |  |  |  |  | }); | 
| 2648 |  |  |  |  |  |  |  | 
| 2649 |  |  |  |  |  |  | Accepts also an Regexp to search for results. | 
| 2650 |  |  |  |  |  |  |  | 
| 2651 |  |  |  |  |  |  | $form->get_elements({ | 
| 2652 |  |  |  |  |  |  | name => qr/oo/, | 
| 2653 |  |  |  |  |  |  | }); | 
| 2654 |  |  |  |  |  |  |  | 
| 2655 |  |  |  |  |  |  | =head2 get_field | 
| 2656 |  |  |  |  |  |  |  | 
| 2657 |  |  |  |  |  |  | Arguments: [%options] | 
| 2658 |  |  |  |  |  |  |  | 
| 2659 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2660 |  |  |  |  |  |  |  | 
| 2661 |  |  |  |  |  |  | Return Value: $element | 
| 2662 |  |  |  |  |  |  |  | 
| 2663 |  |  |  |  |  |  | Accepts the same arguments as L</get_fields>, but only returns the first | 
| 2664 |  |  |  |  |  |  | field found. | 
| 2665 |  |  |  |  |  |  |  | 
| 2666 |  |  |  |  |  |  | =head2 get_elements | 
| 2667 |  |  |  |  |  |  |  | 
| 2668 |  |  |  |  |  |  | Arguments: [%options] | 
| 2669 |  |  |  |  |  |  |  | 
| 2670 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2671 |  |  |  |  |  |  |  | 
| 2672 |  |  |  |  |  |  | Return Value: \@elements | 
| 2673 |  |  |  |  |  |  |  | 
| 2674 |  |  |  |  |  |  | Returns all top-level elements in the form (not recursive). | 
| 2675 |  |  |  |  |  |  | See L</get_all_elements> for a recursive version. | 
| 2676 |  |  |  |  |  |  |  | 
| 2677 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2678 |  |  |  |  |  |  |  | 
| 2679 |  |  |  |  |  |  | $form->get_elements({ | 
| 2680 |  |  |  |  |  |  | name => 'foo', | 
| 2681 |  |  |  |  |  |  | type => 'Radio', | 
| 2682 |  |  |  |  |  |  | }); | 
| 2683 |  |  |  |  |  |  |  | 
| 2684 |  |  |  |  |  |  | Accepts also an Regexp to search for results. | 
| 2685 |  |  |  |  |  |  |  | 
| 2686 |  |  |  |  |  |  | $form->get_elements({ | 
| 2687 |  |  |  |  |  |  | name => qr/oo/, | 
| 2688 |  |  |  |  |  |  | }); | 
| 2689 |  |  |  |  |  |  |  | 
| 2690 |  |  |  |  |  |  | =head2 get_element | 
| 2691 |  |  |  |  |  |  |  | 
| 2692 |  |  |  |  |  |  | Arguments: [%options] | 
| 2693 |  |  |  |  |  |  |  | 
| 2694 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2695 |  |  |  |  |  |  |  | 
| 2696 |  |  |  |  |  |  | Return Value: $element | 
| 2697 |  |  |  |  |  |  |  | 
| 2698 |  |  |  |  |  |  | Accepts the same arguments as L</get_elements>, but only returns the first | 
| 2699 |  |  |  |  |  |  | element found. | 
| 2700 |  |  |  |  |  |  |  | 
| 2701 |  |  |  |  |  |  | See L</get_all_element> for a recursive version. | 
| 2702 |  |  |  |  |  |  |  | 
| 2703 |  |  |  |  |  |  | =head2 get_all_elements | 
| 2704 |  |  |  |  |  |  |  | 
| 2705 |  |  |  |  |  |  | Arguments: [%options] | 
| 2706 |  |  |  |  |  |  |  | 
| 2707 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2708 |  |  |  |  |  |  |  | 
| 2709 |  |  |  |  |  |  | Return Value: \@elements | 
| 2710 |  |  |  |  |  |  |  | 
| 2711 |  |  |  |  |  |  | Returns all elements in the form recursively. | 
| 2712 |  |  |  |  |  |  |  | 
| 2713 |  |  |  |  |  |  | Optionally accepts both C<name> and C<type> arguments to narrow the returned | 
| 2714 |  |  |  |  |  |  | results. | 
| 2715 |  |  |  |  |  |  |  | 
| 2716 |  |  |  |  |  |  | # return all Text elements | 
| 2717 |  |  |  |  |  |  |  | 
| 2718 |  |  |  |  |  |  | $form->get_all_elements({ | 
| 2719 |  |  |  |  |  |  | type => 'Text', | 
| 2720 |  |  |  |  |  |  | }); | 
| 2721 |  |  |  |  |  |  |  | 
| 2722 |  |  |  |  |  |  | Accepts also an Regexp to search for results. | 
| 2723 |  |  |  |  |  |  |  | 
| 2724 |  |  |  |  |  |  | $form->get_elements({ | 
| 2725 |  |  |  |  |  |  | name => qr/oo/, | 
| 2726 |  |  |  |  |  |  | }); | 
| 2727 |  |  |  |  |  |  |  | 
| 2728 |  |  |  |  |  |  | See L</get_elements> for a non-recursive version. | 
| 2729 |  |  |  |  |  |  |  | 
| 2730 |  |  |  |  |  |  | =head2 get_all_element | 
| 2731 |  |  |  |  |  |  |  | 
| 2732 |  |  |  |  |  |  | Arguments: [%options] | 
| 2733 |  |  |  |  |  |  |  | 
| 2734 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2735 |  |  |  |  |  |  |  | 
| 2736 |  |  |  |  |  |  | Return Value: $element | 
| 2737 |  |  |  |  |  |  |  | 
| 2738 |  |  |  |  |  |  | Accepts the same arguments as L</get_all_elements>, but only returns the | 
| 2739 |  |  |  |  |  |  | first element found. | 
| 2740 |  |  |  |  |  |  |  | 
| 2741 |  |  |  |  |  |  | # return the first Text field found, regardless of whether it's | 
| 2742 |  |  |  |  |  |  | # within a fieldset or not | 
| 2743 |  |  |  |  |  |  |  | 
| 2744 |  |  |  |  |  |  | $form->get_all_element({ | 
| 2745 |  |  |  |  |  |  | type => 'Text', | 
| 2746 |  |  |  |  |  |  | }); | 
| 2747 |  |  |  |  |  |  |  | 
| 2748 |  |  |  |  |  |  | Accepts also an Regexp to search for results. | 
| 2749 |  |  |  |  |  |  |  | 
| 2750 |  |  |  |  |  |  | $form->get_elements({ | 
| 2751 |  |  |  |  |  |  | name => qr/oo/, | 
| 2752 |  |  |  |  |  |  | }); | 
| 2753 |  |  |  |  |  |  |  | 
| 2754 |  |  |  |  |  |  | See L</get_all_elements> for a non-recursive version. | 
| 2755 |  |  |  |  |  |  |  | 
| 2756 |  |  |  |  |  |  | =head2 get_deflators | 
| 2757 |  |  |  |  |  |  |  | 
| 2758 |  |  |  |  |  |  | Arguments: [%options] | 
| 2759 |  |  |  |  |  |  |  | 
| 2760 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2761 |  |  |  |  |  |  |  | 
| 2762 |  |  |  |  |  |  | Return Value: \@deflators | 
| 2763 |  |  |  |  |  |  |  | 
| 2764 |  |  |  |  |  |  | Returns all top-level deflators from all fields. | 
| 2765 |  |  |  |  |  |  |  | 
| 2766 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2767 |  |  |  |  |  |  |  | 
| 2768 |  |  |  |  |  |  | $form->get_deflators({ | 
| 2769 |  |  |  |  |  |  | name => 'foo', | 
| 2770 |  |  |  |  |  |  | type => 'Strftime', | 
| 2771 |  |  |  |  |  |  | }); | 
| 2772 |  |  |  |  |  |  |  | 
| 2773 |  |  |  |  |  |  | =head2 get_deflator | 
| 2774 |  |  |  |  |  |  |  | 
| 2775 |  |  |  |  |  |  | Arguments: [%options] | 
| 2776 |  |  |  |  |  |  |  | 
| 2777 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2778 |  |  |  |  |  |  |  | 
| 2779 |  |  |  |  |  |  | Return Value: $element | 
| 2780 |  |  |  |  |  |  |  | 
| 2781 |  |  |  |  |  |  | Accepts the same arguments as L</get_deflators>, but only returns the first | 
| 2782 |  |  |  |  |  |  | deflator found. | 
| 2783 |  |  |  |  |  |  |  | 
| 2784 |  |  |  |  |  |  | =head2 get_filters | 
| 2785 |  |  |  |  |  |  |  | 
| 2786 |  |  |  |  |  |  | Arguments: [%options] | 
| 2787 |  |  |  |  |  |  |  | 
| 2788 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2789 |  |  |  |  |  |  |  | 
| 2790 |  |  |  |  |  |  | Return Value: \@filters | 
| 2791 |  |  |  |  |  |  |  | 
| 2792 |  |  |  |  |  |  | Returns all top-level filters from all fields. | 
| 2793 |  |  |  |  |  |  |  | 
| 2794 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2795 |  |  |  |  |  |  |  | 
| 2796 |  |  |  |  |  |  | $form->get_filters({ | 
| 2797 |  |  |  |  |  |  | name => 'foo', | 
| 2798 |  |  |  |  |  |  | type => 'LowerCase', | 
| 2799 |  |  |  |  |  |  | }); | 
| 2800 |  |  |  |  |  |  |  | 
| 2801 |  |  |  |  |  |  | =head2 get_filter | 
| 2802 |  |  |  |  |  |  |  | 
| 2803 |  |  |  |  |  |  | Arguments: [%options] | 
| 2804 |  |  |  |  |  |  |  | 
| 2805 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2806 |  |  |  |  |  |  |  | 
| 2807 |  |  |  |  |  |  | Return Value: $filter | 
| 2808 |  |  |  |  |  |  |  | 
| 2809 |  |  |  |  |  |  | Accepts the same arguments as L</get_filters>, but only returns the first | 
| 2810 |  |  |  |  |  |  | filter found. | 
| 2811 |  |  |  |  |  |  |  | 
| 2812 |  |  |  |  |  |  | =head2 get_constraints | 
| 2813 |  |  |  |  |  |  |  | 
| 2814 |  |  |  |  |  |  | Arguments: [%options] | 
| 2815 |  |  |  |  |  |  |  | 
| 2816 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2817 |  |  |  |  |  |  |  | 
| 2818 |  |  |  |  |  |  | Return Value: \@constraints | 
| 2819 |  |  |  |  |  |  |  | 
| 2820 |  |  |  |  |  |  | Returns all constraints from all fields. | 
| 2821 |  |  |  |  |  |  |  | 
| 2822 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2823 |  |  |  |  |  |  |  | 
| 2824 |  |  |  |  |  |  | $form->get_constraints({ | 
| 2825 |  |  |  |  |  |  | name => 'foo', | 
| 2826 |  |  |  |  |  |  | type => 'Equal', | 
| 2827 |  |  |  |  |  |  | }); | 
| 2828 |  |  |  |  |  |  |  | 
| 2829 |  |  |  |  |  |  | =head2 get_constraint | 
| 2830 |  |  |  |  |  |  |  | 
| 2831 |  |  |  |  |  |  | Arguments: [%options] | 
| 2832 |  |  |  |  |  |  |  | 
| 2833 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2834 |  |  |  |  |  |  |  | 
| 2835 |  |  |  |  |  |  | Return Value: $constraint | 
| 2836 |  |  |  |  |  |  |  | 
| 2837 |  |  |  |  |  |  | Accepts the same arguments as L</get_constraints>, but only returns the | 
| 2838 |  |  |  |  |  |  | first constraint found. | 
| 2839 |  |  |  |  |  |  |  | 
| 2840 |  |  |  |  |  |  | =head2 get_inflators | 
| 2841 |  |  |  |  |  |  |  | 
| 2842 |  |  |  |  |  |  | Arguments: [%options] | 
| 2843 |  |  |  |  |  |  |  | 
| 2844 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2845 |  |  |  |  |  |  |  | 
| 2846 |  |  |  |  |  |  | Return Value: \@inflators | 
| 2847 |  |  |  |  |  |  |  | 
| 2848 |  |  |  |  |  |  | Returns all inflators from all fields. | 
| 2849 |  |  |  |  |  |  |  | 
| 2850 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2851 |  |  |  |  |  |  |  | 
| 2852 |  |  |  |  |  |  | $form->get_inflators({ | 
| 2853 |  |  |  |  |  |  | name => 'foo', | 
| 2854 |  |  |  |  |  |  | type => 'DateTime', | 
| 2855 |  |  |  |  |  |  | }); | 
| 2856 |  |  |  |  |  |  |  | 
| 2857 |  |  |  |  |  |  | =head2 get_inflator | 
| 2858 |  |  |  |  |  |  |  | 
| 2859 |  |  |  |  |  |  | Arguments: [%options] | 
| 2860 |  |  |  |  |  |  |  | 
| 2861 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2862 |  |  |  |  |  |  |  | 
| 2863 |  |  |  |  |  |  | Return Value: $inflator | 
| 2864 |  |  |  |  |  |  |  | 
| 2865 |  |  |  |  |  |  | Accepts the same arguments as L</get_inflators>, but only returns the | 
| 2866 |  |  |  |  |  |  | first inflator found. | 
| 2867 |  |  |  |  |  |  |  | 
| 2868 |  |  |  |  |  |  | =head2 get_validators | 
| 2869 |  |  |  |  |  |  |  | 
| 2870 |  |  |  |  |  |  | Arguments: [%options] | 
| 2871 |  |  |  |  |  |  |  | 
| 2872 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2873 |  |  |  |  |  |  |  | 
| 2874 |  |  |  |  |  |  | Return Value: \@validators | 
| 2875 |  |  |  |  |  |  |  | 
| 2876 |  |  |  |  |  |  | Returns all validators from all fields. | 
| 2877 |  |  |  |  |  |  |  | 
| 2878 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2879 |  |  |  |  |  |  |  | 
| 2880 |  |  |  |  |  |  | $form->get_validators({ | 
| 2881 |  |  |  |  |  |  | name => 'foo', | 
| 2882 |  |  |  |  |  |  | type => 'Callback', | 
| 2883 |  |  |  |  |  |  | }); | 
| 2884 |  |  |  |  |  |  |  | 
| 2885 |  |  |  |  |  |  | =head2 get_validator | 
| 2886 |  |  |  |  |  |  |  | 
| 2887 |  |  |  |  |  |  | Arguments: [%options] | 
| 2888 |  |  |  |  |  |  |  | 
| 2889 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2890 |  |  |  |  |  |  |  | 
| 2891 |  |  |  |  |  |  | Return Value: $validator | 
| 2892 |  |  |  |  |  |  |  | 
| 2893 |  |  |  |  |  |  | Accepts the same arguments as L</get_validators>, but only returns the | 
| 2894 |  |  |  |  |  |  | first validator found. | 
| 2895 |  |  |  |  |  |  |  | 
| 2896 |  |  |  |  |  |  | =head2 get_transformers | 
| 2897 |  |  |  |  |  |  |  | 
| 2898 |  |  |  |  |  |  | Arguments: [%options] | 
| 2899 |  |  |  |  |  |  |  | 
| 2900 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2901 |  |  |  |  |  |  |  | 
| 2902 |  |  |  |  |  |  | Return Value: \@transformers | 
| 2903 |  |  |  |  |  |  |  | 
| 2904 |  |  |  |  |  |  | Returns all transformers from all fields. | 
| 2905 |  |  |  |  |  |  |  | 
| 2906 |  |  |  |  |  |  | Accepts both C<name> and C<type> arguments to narrow the returned results. | 
| 2907 |  |  |  |  |  |  |  | 
| 2908 |  |  |  |  |  |  | $form->get_transformers({ | 
| 2909 |  |  |  |  |  |  | name => 'foo', | 
| 2910 |  |  |  |  |  |  | type => 'Callback', | 
| 2911 |  |  |  |  |  |  | }); | 
| 2912 |  |  |  |  |  |  |  | 
| 2913 |  |  |  |  |  |  | =head2 get_transformer | 
| 2914 |  |  |  |  |  |  |  | 
| 2915 |  |  |  |  |  |  | Arguments: [%options] | 
| 2916 |  |  |  |  |  |  |  | 
| 2917 |  |  |  |  |  |  | Arguments: [\%options] | 
| 2918 |  |  |  |  |  |  |  | 
| 2919 |  |  |  |  |  |  | Return Value: $transformer | 
| 2920 |  |  |  |  |  |  |  | 
| 2921 |  |  |  |  |  |  | Accepts the same arguments as L</get_transformers>, but only returns the | 
| 2922 |  |  |  |  |  |  | first transformer found. | 
| 2923 |  |  |  |  |  |  |  | 
| 2924 |  |  |  |  |  |  | =head2 clone | 
| 2925 |  |  |  |  |  |  |  | 
| 2926 |  |  |  |  |  |  | Returns a deep clone of the <$form> object. | 
| 2927 |  |  |  |  |  |  |  | 
| 2928 |  |  |  |  |  |  | Because of scoping issues, code references (such as in Callback constraints) | 
| 2929 |  |  |  |  |  |  | are copied instead of cloned. | 
| 2930 |  |  |  |  |  |  |  | 
| 2931 |  |  |  |  |  |  | =head1 ATTRIBUTE ACCESSORS | 
| 2932 |  |  |  |  |  |  |  | 
| 2933 |  |  |  |  |  |  | For the basic method, e.g. C</attributes>: | 
| 2934 |  |  |  |  |  |  |  | 
| 2935 |  |  |  |  |  |  | Arguments: [%attributes] | 
| 2936 |  |  |  |  |  |  |  | 
| 2937 |  |  |  |  |  |  | Arguments: [\%attributes] | 
| 2938 |  |  |  |  |  |  |  | 
| 2939 |  |  |  |  |  |  | Return Value: $form | 
| 2940 |  |  |  |  |  |  |  | 
| 2941 |  |  |  |  |  |  | As a special case, if no arguments are passed, the attributes hash-ref is | 
| 2942 |  |  |  |  |  |  | returned. This allows the following idioms. | 
| 2943 |  |  |  |  |  |  |  | 
| 2944 |  |  |  |  |  |  | # set a value | 
| 2945 |  |  |  |  |  |  | $form->attributes->{id} = 'form'; | 
| 2946 |  |  |  |  |  |  |  | 
| 2947 |  |  |  |  |  |  | # delete all attributes | 
| 2948 |  |  |  |  |  |  | %{ $form->attributes } = (); | 
| 2949 |  |  |  |  |  |  |  | 
| 2950 |  |  |  |  |  |  | All methods documented as 'attribute accessors' also have the following | 
| 2951 |  |  |  |  |  |  | variants generated: | 
| 2952 |  |  |  |  |  |  |  | 
| 2953 |  |  |  |  |  |  | C<*_xml> can be used as a setter, and ensures that its argument is not | 
| 2954 |  |  |  |  |  |  | XML-escaped in the rendered form. | 
| 2955 |  |  |  |  |  |  |  | 
| 2956 |  |  |  |  |  |  | C<*_loc> can he used as a setter, and passes the arguments through | 
| 2957 |  |  |  |  |  |  | L</localize>. | 
| 2958 |  |  |  |  |  |  |  | 
| 2959 |  |  |  |  |  |  | C<add_*> can be used to append a word to an attribute without overwriting | 
| 2960 |  |  |  |  |  |  | any already-existing value. | 
| 2961 |  |  |  |  |  |  |  | 
| 2962 |  |  |  |  |  |  | # Example | 
| 2963 |  |  |  |  |  |  | $form->attributes({ class => 'fancy' }); | 
| 2964 |  |  |  |  |  |  | $form->add_attributes({ class => 'pants' }); | 
| 2965 |  |  |  |  |  |  | # class="fancy pants" | 
| 2966 |  |  |  |  |  |  |  | 
| 2967 |  |  |  |  |  |  | C<add_*_xml>, like C<add_*>, but ensures it doesn't get XML-escaped. | 
| 2968 |  |  |  |  |  |  |  | 
| 2969 |  |  |  |  |  |  | C<add_*_loc>, like C<add_*>, but passing the arguments through L</localize>. | 
| 2970 |  |  |  |  |  |  |  | 
| 2971 |  |  |  |  |  |  | C<del_*> can be used to remove a word from an attribute value. | 
| 2972 |  |  |  |  |  |  |  | 
| 2973 |  |  |  |  |  |  | # Example | 
| 2974 |  |  |  |  |  |  | $form->attributes({ class => 'fancy pants' }); | 
| 2975 |  |  |  |  |  |  | $form->del_attributes({ class => 'pants' }); | 
| 2976 |  |  |  |  |  |  | # class="fancy" | 
| 2977 |  |  |  |  |  |  |  | 
| 2978 |  |  |  |  |  |  | C<del_*_xml>, like C<del_*>, but ensures it doesn't get XML-escaped. | 
| 2979 |  |  |  |  |  |  |  | 
| 2980 |  |  |  |  |  |  | C<del_*_loc>, like C<del_*>, but passing the arguments through L</localize>. | 
| 2981 |  |  |  |  |  |  |  | 
| 2982 |  |  |  |  |  |  | Also, any attribute method-name which contains the word C<attributes> also | 
| 2983 |  |  |  |  |  |  | has aliases created for all these variants, with the word C<attributes> | 
| 2984 |  |  |  |  |  |  | replaced by C<attrs>. | 
| 2985 |  |  |  |  |  |  |  | 
| 2986 |  |  |  |  |  |  | # For example, the attributes() method would have all these variant | 
| 2987 |  |  |  |  |  |  | # methods available | 
| 2988 |  |  |  |  |  |  |  | 
| 2989 |  |  |  |  |  |  | $form->attributes({ class => 'fancy' }); | 
| 2990 |  |  |  |  |  |  | $form->attributes_xml({ title => '<b>fancy</b>' }); | 
| 2991 |  |  |  |  |  |  | $form->attributes_loc({ title => 'fancy' }); | 
| 2992 |  |  |  |  |  |  | $form->add_attributes({ class => 'fancy' }); | 
| 2993 |  |  |  |  |  |  | $form->add_attributes_xml({ title => '<b>fancy</b>' }); | 
| 2994 |  |  |  |  |  |  | $form->add_attributes_loc({ title => 'fancy' }); | 
| 2995 |  |  |  |  |  |  | $form->del_attributes({ class => 'fancy' }); | 
| 2996 |  |  |  |  |  |  | $form->del_attributes_xml({ title => '<b>fancy</b>' }); | 
| 2997 |  |  |  |  |  |  | $form->del_attributes_loc({ title => 'fancy' }); | 
| 2998 |  |  |  |  |  |  |  | 
| 2999 |  |  |  |  |  |  | # Because the method contains the word 'attributes', it also gets the | 
| 3000 |  |  |  |  |  |  | # following short-forms | 
| 3001 |  |  |  |  |  |  |  | 
| 3002 |  |  |  |  |  |  | $form->attrs({ class => 'fancy' }); | 
| 3003 |  |  |  |  |  |  | $form->attrs_xml({ title => '<b>fancy</b>' }); | 
| 3004 |  |  |  |  |  |  | $form->attrs_loc({ title => 'fancy' }); | 
| 3005 |  |  |  |  |  |  | $form->add_attrs({ class => 'fancy' }); | 
| 3006 |  |  |  |  |  |  | $form->add_attrs_xml({ title => '<b>fancy</b>' }); | 
| 3007 |  |  |  |  |  |  | $form->add_attrs_loc({ title => 'fancy' }); | 
| 3008 |  |  |  |  |  |  | $form->del_attrs({ class => 'fancy' }); | 
| 3009 |  |  |  |  |  |  | $form->del_attrs_xml({ title => '<b>fancy</b>' }); | 
| 3010 |  |  |  |  |  |  | $form->del_attrs_loc({ title => 'fancy' }); | 
| 3011 |  |  |  |  |  |  |  | 
| 3012 |  |  |  |  |  |  | =head1 ATTRIBUTE SHORT-CUTS | 
| 3013 |  |  |  |  |  |  |  | 
| 3014 |  |  |  |  |  |  | All methods documented as 'attribute short-cuts' are short-cuts to directly | 
| 3015 |  |  |  |  |  |  | access individual attribute key/values. | 
| 3016 |  |  |  |  |  |  |  | 
| 3017 |  |  |  |  |  |  | # Example | 
| 3018 |  |  |  |  |  |  | $form->id( 'login' ); | 
| 3019 |  |  |  |  |  |  | $id = $form->id; | 
| 3020 |  |  |  |  |  |  |  | 
| 3021 |  |  |  |  |  |  | # is equivalent to: | 
| 3022 |  |  |  |  |  |  | $form->attributes({ id => 'login' }); | 
| 3023 |  |  |  |  |  |  | $id = $form->attributes->{id}; | 
| 3024 |  |  |  |  |  |  |  | 
| 3025 |  |  |  |  |  |  | All attribute short-cuts also have a C<*_xml> variant. | 
| 3026 |  |  |  |  |  |  |  | 
| 3027 |  |  |  |  |  |  | # Example | 
| 3028 |  |  |  |  |  |  | $form->id_xml( $xml ); | 
| 3029 |  |  |  |  |  |  |  | 
| 3030 |  |  |  |  |  |  | # is equivalent to: | 
| 3031 |  |  |  |  |  |  | $form->attributes_xml({ id => $xml }); | 
| 3032 |  |  |  |  |  |  |  | 
| 3033 |  |  |  |  |  |  | All attribute short-cuts also have a C<*_loc> variant. | 
| 3034 |  |  |  |  |  |  |  | 
| 3035 |  |  |  |  |  |  | # Example | 
| 3036 |  |  |  |  |  |  | $form->title_loc( $key ); | 
| 3037 |  |  |  |  |  |  |  | 
| 3038 |  |  |  |  |  |  | # is equivalent to: | 
| 3039 |  |  |  |  |  |  | $form->attributes_loc({ title => $key }); | 
| 3040 |  |  |  |  |  |  |  | 
| 3041 |  |  |  |  |  |  | =head1 INHERITING ACCESSORS | 
| 3042 |  |  |  |  |  |  |  | 
| 3043 |  |  |  |  |  |  | All methods documented as 'inheriting accessors' can be set on the form, | 
| 3044 |  |  |  |  |  |  | a block element or a single field element. | 
| 3045 |  |  |  |  |  |  | When the value is read, if no value is defined it automatically traverses | 
| 3046 |  |  |  |  |  |  | the element's hierarchy of parents, searching for a defined value. | 
| 3047 |  |  |  |  |  |  |  | 
| 3048 |  |  |  |  |  |  | All inherited accessors also have a C<*_no_inherit> variant, which can be | 
| 3049 |  |  |  |  |  |  | used as a getter to fetch any defined value, without traversing the | 
| 3050 |  |  |  |  |  |  | hierarchy of parents. This variant cannot be used as a setter. | 
| 3051 |  |  |  |  |  |  |  | 
| 3052 |  |  |  |  |  |  | E.g., the L</auto_id> has a variant named C<auto_id_no_inherit>. | 
| 3053 |  |  |  |  |  |  |  | 
| 3054 |  |  |  |  |  |  | =head1 OUTPUT ACCESSORS | 
| 3055 |  |  |  |  |  |  |  | 
| 3056 |  |  |  |  |  |  | All methods documented as 'output accessors' also have C<*_xml> and C<*_loc> | 
| 3057 |  |  |  |  |  |  | variants. | 
| 3058 |  |  |  |  |  |  |  | 
| 3059 |  |  |  |  |  |  | The C<*_xml> variant can be used as a setter, and ensures that its | 
| 3060 |  |  |  |  |  |  | argument is not XML-escaped in the rendered form. | 
| 3061 |  |  |  |  |  |  |  | 
| 3062 |  |  |  |  |  |  | The C<*_loc> variant can be used as a setter, and passes the arguments | 
| 3063 |  |  |  |  |  |  | through L</localize>. | 
| 3064 |  |  |  |  |  |  |  | 
| 3065 |  |  |  |  |  |  | E.g., the L<label|HTML::FormFu::Role::Element::Field/label> method has | 
| 3066 |  |  |  |  |  |  | variants named C<label_xml> and C<label_loc>. | 
| 3067 |  |  |  |  |  |  |  | 
| 3068 |  |  |  |  |  |  | =head1 BOOLEAN ATTRIBUTE ACCESSORS | 
| 3069 |  |  |  |  |  |  |  | 
| 3070 |  |  |  |  |  |  | To support boolean attributes, whose value should either be equal to the | 
| 3071 |  |  |  |  |  |  | attribute name, or empty. Any true value will switch the attribute 'on', any | 
| 3072 |  |  |  |  |  |  | false value will remove the attribute. | 
| 3073 |  |  |  |  |  |  |  | 
| 3074 |  |  |  |  |  |  | # Example | 
| 3075 |  |  |  |  |  |  |  | 
| 3076 |  |  |  |  |  |  | $field->autofocus(1); | 
| 3077 |  |  |  |  |  |  | # equivalent to: | 
| 3078 |  |  |  |  |  |  | $field->attributes({ autofocus => 'autofocus' }); | 
| 3079 |  |  |  |  |  |  |  | 
| 3080 |  |  |  |  |  |  | $field->autofocus(0);; | 
| 3081 |  |  |  |  |  |  | # equivalent to: | 
| 3082 |  |  |  |  |  |  | delete $field->attributes->{autofocus}; | 
| 3083 |  |  |  |  |  |  |  | 
| 3084 |  |  |  |  |  |  | =head1 ATTRIBUTE SUBSTITUTIONS | 
| 3085 |  |  |  |  |  |  |  | 
| 3086 |  |  |  |  |  |  | Some attributes support character substitutions: the following substitutions | 
| 3087 |  |  |  |  |  |  | are possible: | 
| 3088 |  |  |  |  |  |  |  | 
| 3089 |  |  |  |  |  |  | %f # $form->id | 
| 3090 |  |  |  |  |  |  | %n # $field->name | 
| 3091 |  |  |  |  |  |  | %t # lc( $field->type ) | 
| 3092 |  |  |  |  |  |  | %r # $block->repeatable_count | 
| 3093 |  |  |  |  |  |  | %s # $error->stage | 
| 3094 |  |  |  |  |  |  |  | 
| 3095 |  |  |  |  |  |  | These allow each field to have consistent attributes, while remaining unique. | 
| 3096 |  |  |  |  |  |  |  | 
| 3097 |  |  |  |  |  |  | =head1 DEPRECATION POLICY | 
| 3098 |  |  |  |  |  |  |  | 
| 3099 |  |  |  |  |  |  | We try our best to not make incompatible changes, but if they're required | 
| 3100 |  |  |  |  |  |  | we'll make every effort possible to provide backwards compatibility for | 
| 3101 |  |  |  |  |  |  | several release-cycles, issuing a warnings about the changes, before removing | 
| 3102 |  |  |  |  |  |  | the legacy features. | 
| 3103 |  |  |  |  |  |  |  | 
| 3104 |  |  |  |  |  |  | =head1 RESTORING LEGACY HTML CLASSES | 
| 3105 |  |  |  |  |  |  |  | 
| 3106 |  |  |  |  |  |  | C<v1.00> dropped most of the default HTML class-names, with the intention | 
| 3107 |  |  |  |  |  |  | that each application should define just what it needs, without needing to | 
| 3108 |  |  |  |  |  |  | reset unwanted options first. We also gain the benefit of less markup being | 
| 3109 |  |  |  |  |  |  | generated, speeding up both L<render|/render> and HTTP transfers. | 
| 3110 |  |  |  |  |  |  |  | 
| 3111 |  |  |  |  |  |  | To restore the previous behaviour, set the following options. | 
| 3112 |  |  |  |  |  |  |  | 
| 3113 |  |  |  |  |  |  | If you're using L<best practices|/"BEST PRACTICES">, you'll only need to set | 
| 3114 |  |  |  |  |  |  | these once per-application in your app-wide config file. | 
| 3115 |  |  |  |  |  |  |  | 
| 3116 |  |  |  |  |  |  | --- | 
| 3117 |  |  |  |  |  |  | auto_container_class: '%t' | 
| 3118 |  |  |  |  |  |  | auto_container_label_class: 'label' | 
| 3119 |  |  |  |  |  |  | auto_container_comment_class: 'comment' | 
| 3120 |  |  |  |  |  |  | auto_comment_class: 'comment' | 
| 3121 |  |  |  |  |  |  | auto_container_error_class: 'error' | 
| 3122 |  |  |  |  |  |  | auto_container_per_error_class: 'error_%s_%t' | 
| 3123 |  |  |  |  |  |  | auto_error_class: 'error_message error_%s_%t' | 
| 3124 |  |  |  |  |  |  |  | 
| 3125 |  |  |  |  |  |  | =head1 DEPRECATED METHODS | 
| 3126 |  |  |  |  |  |  |  | 
| 3127 |  |  |  |  |  |  | See L<HTML::FormFu::Role::Element::Field/"DEPRECATED METHODS">. | 
| 3128 |  |  |  |  |  |  |  | 
| 3129 |  |  |  |  |  |  | =head1 REMOVED METHODS | 
| 3130 |  |  |  |  |  |  |  | 
| 3131 |  |  |  |  |  |  | See also L<HTML::FormFu::Element/"REMOVED METHODS">. | 
| 3132 |  |  |  |  |  |  |  | 
| 3133 |  |  |  |  |  |  | =head2 element_defaults | 
| 3134 |  |  |  |  |  |  |  | 
| 3135 |  |  |  |  |  |  | Has been removed; see L</default_args> instead. | 
| 3136 |  |  |  |  |  |  |  | 
| 3137 |  |  |  |  |  |  | =head2 model_class | 
| 3138 |  |  |  |  |  |  |  | 
| 3139 |  |  |  |  |  |  | Has been removed; use L</default_model> instead. | 
| 3140 |  |  |  |  |  |  |  | 
| 3141 |  |  |  |  |  |  | =head2 defaults_from_model | 
| 3142 |  |  |  |  |  |  |  | 
| 3143 |  |  |  |  |  |  | Has been removed; use L<HTML::FormFu::Model/default_values> instead. | 
| 3144 |  |  |  |  |  |  |  | 
| 3145 |  |  |  |  |  |  | =head2 save_to_model | 
| 3146 |  |  |  |  |  |  |  | 
| 3147 |  |  |  |  |  |  | Has been removed; use L<HTML::FormFu::Model/update> instead. | 
| 3148 |  |  |  |  |  |  |  | 
| 3149 |  |  |  |  |  |  | =head1 BEST PRACTICES | 
| 3150 |  |  |  |  |  |  |  | 
| 3151 |  |  |  |  |  |  | It is advisable to keep application-wide (or global) settings in a single | 
| 3152 |  |  |  |  |  |  | config file, which should be loaded by each form. | 
| 3153 |  |  |  |  |  |  |  | 
| 3154 |  |  |  |  |  |  | See L</load_config_file>. | 
| 3155 |  |  |  |  |  |  |  | 
| 3156 |  |  |  |  |  |  | =head1 COOKBOOK | 
| 3157 |  |  |  |  |  |  |  | 
| 3158 |  |  |  |  |  |  | L<HTML::FormFu::Manual::Cookbook> | 
| 3159 |  |  |  |  |  |  |  | 
| 3160 |  |  |  |  |  |  | =head2 UNICODE | 
| 3161 |  |  |  |  |  |  |  | 
| 3162 |  |  |  |  |  |  | L<HTML::FormFu::Manual::Unicode> | 
| 3163 |  |  |  |  |  |  |  | 
| 3164 |  |  |  |  |  |  | =head1 EXAMPLES | 
| 3165 |  |  |  |  |  |  |  | 
| 3166 |  |  |  |  |  |  | =head2 vertically-aligned CSS | 
| 3167 |  |  |  |  |  |  |  | 
| 3168 |  |  |  |  |  |  | The distribution directory C<examples/vertically-aligned> contains a form with | 
| 3169 |  |  |  |  |  |  | example CSS for a "vertically aligned" theme. | 
| 3170 |  |  |  |  |  |  |  | 
| 3171 |  |  |  |  |  |  | This can be viewed by opening the file C<vertically-aligned.html> in a | 
| 3172 |  |  |  |  |  |  | web-browser. | 
| 3173 |  |  |  |  |  |  |  | 
| 3174 |  |  |  |  |  |  | If you wish to experiment with making changes, the form is defined in file | 
| 3175 |  |  |  |  |  |  | C<vertically-aligned.yml>, and the HTML file can be updated with any changes | 
| 3176 |  |  |  |  |  |  | by running the following command (while in the distribution root directory). | 
| 3177 |  |  |  |  |  |  |  | 
| 3178 |  |  |  |  |  |  | perl examples/vertically-aligned/vertically-aligned.pl | 
| 3179 |  |  |  |  |  |  |  | 
| 3180 |  |  |  |  |  |  | This uses the L<Template Toolkit|Template> file C<vertically-aligned.tt>, | 
| 3181 |  |  |  |  |  |  | and the CSS is defined in files C<vertically-aligned.css> and | 
| 3182 |  |  |  |  |  |  | C<vertically-aligned-ie.css>. | 
| 3183 |  |  |  |  |  |  |  | 
| 3184 |  |  |  |  |  |  | =head1 SUPPORT | 
| 3185 |  |  |  |  |  |  |  | 
| 3186 |  |  |  |  |  |  | Project Page: | 
| 3187 |  |  |  |  |  |  |  | 
| 3188 |  |  |  |  |  |  | L<http://code.google.com/p/html-formfu/> | 
| 3189 |  |  |  |  |  |  |  | 
| 3190 |  |  |  |  |  |  | Mailing list: | 
| 3191 |  |  |  |  |  |  |  | 
| 3192 |  |  |  |  |  |  | L<http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu> | 
| 3193 |  |  |  |  |  |  |  | 
| 3194 |  |  |  |  |  |  | Mailing list archives: | 
| 3195 |  |  |  |  |  |  |  | 
| 3196 |  |  |  |  |  |  | L<http://lists.scsys.co.uk/pipermail/html-formfu/> | 
| 3197 |  |  |  |  |  |  |  | 
| 3198 |  |  |  |  |  |  | IRC: | 
| 3199 |  |  |  |  |  |  |  | 
| 3200 |  |  |  |  |  |  | C<irc.perl.org>, channel C<#formfu> | 
| 3201 |  |  |  |  |  |  |  | 
| 3202 |  |  |  |  |  |  | The HTML::Widget archives L<http://lists.scsys.co.uk/pipermail/html-widget/> | 
| 3203 |  |  |  |  |  |  | between January and May 2007 also contain discussion regarding HTML::FormFu. | 
| 3204 |  |  |  |  |  |  |  | 
| 3205 |  |  |  |  |  |  | =head1 BUGS | 
| 3206 |  |  |  |  |  |  |  | 
| 3207 |  |  |  |  |  |  | Please submit bugs / feature requests to | 
| 3208 |  |  |  |  |  |  | L<https://github.com/FormFu/HTML-FormFu/issues> (preferred) or | 
| 3209 |  |  |  |  |  |  | L<http://rt.perl.org>. | 
| 3210 |  |  |  |  |  |  |  | 
| 3211 |  |  |  |  |  |  | =head1 PATCHES | 
| 3212 |  |  |  |  |  |  |  | 
| 3213 |  |  |  |  |  |  | To help patches be applied quickly, please send them to the mailing list; | 
| 3214 |  |  |  |  |  |  | attached, rather than inline; against subversion, rather than a cpan version | 
| 3215 |  |  |  |  |  |  | (run C<< svn diff > patchfile >>); mention which svn version it's against. | 
| 3216 |  |  |  |  |  |  | Mailing list messages are limited to 256KB, so gzip the patch if necessary. | 
| 3217 |  |  |  |  |  |  |  | 
| 3218 |  |  |  |  |  |  | =head1 GITHUB REPOSITORY | 
| 3219 |  |  |  |  |  |  |  | 
| 3220 |  |  |  |  |  |  | This module's sourcecode is maintained in a git repository at | 
| 3221 |  |  |  |  |  |  | L<git://github.com/FormFu/HTML-FormFu.git> | 
| 3222 |  |  |  |  |  |  |  | 
| 3223 |  |  |  |  |  |  | The project page is L<https://github.com/FormFu/HTML-FormFu> | 
| 3224 |  |  |  |  |  |  |  | 
| 3225 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 3226 |  |  |  |  |  |  |  | 
| 3227 |  |  |  |  |  |  | L<HTML::FormFu::Imager> | 
| 3228 |  |  |  |  |  |  |  | 
| 3229 |  |  |  |  |  |  | L<Catalyst::Controller::HTML::FormFu> | 
| 3230 |  |  |  |  |  |  |  | 
| 3231 |  |  |  |  |  |  | L<HTML::FormFu::Model::DBIC> | 
| 3232 |  |  |  |  |  |  |  | 
| 3233 |  |  |  |  |  |  | =head1 CONTRIBUTORS | 
| 3234 |  |  |  |  |  |  |  | 
| 3235 |  |  |  |  |  |  | Brian Cassidy | 
| 3236 |  |  |  |  |  |  |  | 
| 3237 |  |  |  |  |  |  | Ozum Eldogan | 
| 3238 |  |  |  |  |  |  |  | 
| 3239 |  |  |  |  |  |  | Ruben Fonseca | 
| 3240 |  |  |  |  |  |  |  | 
| 3241 |  |  |  |  |  |  | Ronald Kimball | 
| 3242 |  |  |  |  |  |  |  | 
| 3243 |  |  |  |  |  |  | Daisuke Maki | 
| 3244 |  |  |  |  |  |  |  | 
| 3245 |  |  |  |  |  |  | Andreas Marienborg | 
| 3246 |  |  |  |  |  |  |  | 
| 3247 |  |  |  |  |  |  | Mario Minati | 
| 3248 |  |  |  |  |  |  |  | 
| 3249 |  |  |  |  |  |  | Steve Nolte | 
| 3250 |  |  |  |  |  |  |  | 
| 3251 |  |  |  |  |  |  | Moritz Onken | 
| 3252 |  |  |  |  |  |  |  | 
| 3253 |  |  |  |  |  |  | Doug Orleans | 
| 3254 |  |  |  |  |  |  |  | 
| 3255 |  |  |  |  |  |  | Matthias Dietrich | 
| 3256 |  |  |  |  |  |  |  | 
| 3257 |  |  |  |  |  |  | Dean Hamstead | 
| 3258 |  |  |  |  |  |  |  | 
| 3259 |  |  |  |  |  |  | Karen Etheridge | 
| 3260 |  |  |  |  |  |  |  | 
| 3261 |  |  |  |  |  |  | Nigel Metheringham | 
| 3262 |  |  |  |  |  |  |  | 
| 3263 |  |  |  |  |  |  | Based on the original source code of L<HTML::Widget>, by Sebastian Riedel, | 
| 3264 |  |  |  |  |  |  | C<sri@oook.de>. | 
| 3265 |  |  |  |  |  |  |  | 
| 3266 |  |  |  |  |  |  | =head1 AUTHOR | 
| 3267 |  |  |  |  |  |  |  | 
| 3268 |  |  |  |  |  |  | Carl Franks <cpan@fireartist.com> | 
| 3269 |  |  |  |  |  |  |  | 
| 3270 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 3271 |  |  |  |  |  |  |  | 
| 3272 |  |  |  |  |  |  | This software is copyright (c) 2018 by Carl Franks. | 
| 3273 |  |  |  |  |  |  |  | 
| 3274 |  |  |  |  |  |  | This is free software; you can redistribute it and/or modify it under | 
| 3275 |  |  |  |  |  |  | the same terms as the Perl 5 programming language system itself. | 
| 3276 |  |  |  |  |  |  |  | 
| 3277 |  |  |  |  |  |  | =cut |