Rose-HTML-Objects

 view release on metacpan or  search on metacpan

lib/Rose/HTML/Form.pm  view on Meta::CPAN

  my $self_uri = $uri_root;

  if(keys %{$self->{'params'}})
  {
    $self_uri .= '?'  unless($self_uri =~ /\?$/);    
    $self_uri .= $self->query_string;
  }

  return Rose::URI->new($self_uri);
}

# XXX: To document or not to document, that is the question...
sub query_hash { Rose::URI->new(query => shift->query_string)->query_hash }

sub query_string
{
  my($self) = shift;

  my $coalesce = $self->coalesce_query_string_params;

  my %params;

  my @fields = $self->fields;

  while(my $field = shift(@fields))
  {
    unless($coalesce)
    {
      if($field->isa('Rose::HTML::Form::Field::Compound'))
      {
        unshift(@fields, $field->fields);
        next;
      }
    }

    my $value = $field->output_value;
    next  unless(defined $value);
    push(@{$params{$field->name}}, ref $value ? @$value : $value);
  }

  my $qs = '';
  my $sep = $self->uri_separator;

  no warnings;

  foreach my $param (sort keys(%params))
  {
    my $values = $params{$param};

    $qs .= $sep  if($qs);
    $qs .= join($sep, map { $param . '=' . uri_escape($_, UNSAFE_URI_CHARS) } @$values);
  }

  return $qs;
}

sub validate
{
  my($self, %args) = @_;

  $args{'cascade'} = 1  unless(exists $args{'cascade'});

  my $fail = 0;

  my $cascade = $args{'cascade'};

  if($cascade)
  {
    foreach my $form ($self->forms)
    {
      next  if($form->is_empty && $form->empty_is_ok);

      $Debug && warn "Validating sub-form ", $form->form_name, "\n";

      unless($form->validate(%args))
      {
        $self->add_error($form->error)  if($form->error);
        $fail++;
      }
    }
  }

  unless($args{'form_only'})
  {
    return 1  if($self->is_empty && $self->empty_is_ok);

    foreach my $field ($self->fields)
    {
      if($field->parent_form ne $self)
      {
        $Debug && warn "Skipping validation of field ", $field->name, " in child form\n";
      }
      else
      {
        $Debug && warn "Validating ", $field->name, "\n";
        $fail++  unless($field->validate);
      }
    }
  }

  if($fail)
  {
    unless($self->has_errors)
    {
      $self->add_error_id(FORM_HAS_ERRORS);
    }

    return 0;
  }

  return 1;
}

sub init_fields_with_cgi
{
  my($self) = shift;  

  $self->params_from_cgi(shift);
  $self->init_fields(@_);
}

sub init_fields_with_apache
{
  my($self) = shift;  

  $self->params_from_apache(shift);
  $self->init_fields(@_);

lib/Rose/HTML/Form.pm  view on Meta::CPAN

See the L<nested forms|/"NESTED FORMS"> section to learn more about nested forms, and the L<Rose::HTML::Form::Repeatable> documentation to learn more about repeatable forms.

=item B<reset>

Call L<reset()|Rose::HTML::Form::Field/reset> on each field object and set L<error()|Rose::HTML::Object/error> to undef.

=item B<reset_fields>

Call L<reset()|/reset> on each field object.

=item B<self_uri>

Returns a L<Rose::URI> object corresponding to the current state of the form. If L<uri_base()|/uri_base> is set, then it is included in front of what would otherwise be the start of the URI (i.e., the value of the form's "action" HTML attribute).

=item B<start_html>

Returns the HTML that will begin the form tag.

=item B<start_xhtml>

Returns the XHTML that will begin the form tag.

=item B<start_multipart_html>

Sets the "enctype" HTML attribute to "multipart/form-data", then returns the HTML that will begin the form tag.

=item B<start_multipart_xhtml>

Sets the "enctype" HTML attribute to "multipart/form-data", then returns the XHTML that will begin the form tag.

=item B<trim_xy_params [BOOL]>

Get or set a boolean value that determines whether or not L<params|/params> that end in ".x" or ".y" have that suffix trimmed off.  This is useful for handling query parameters created by some web browsers in response to clicks on image buttons and o...

The default value is the value returned by the L<default_trim_xy_params|/default_trim_xy_params> class method.

=item B<uri_base [STRING]>

Get or set the URI of the form, minus the value of the "action" HTML attribute.  Although the form action can be a relative URI, I suggest that it be an absolute path at the very least, leaving the L<uri_base()|/uri_base> to be the initial part of th...

    $form->action('/foo/bar');
    $form->uri_base('http://www.foo.com');

    # http://www.foo.com/foo/bar
    $uri = $form->self_uri;

=item B<uri_separator [CHAR]>

Get or set the character used to separate parameter name/value pairs in the return value of L<query_string()|/query_string> (which is in turn used to construct the return value of L<self_uri()|/self_uri>).  The default is "&".

=item B<validate [PARAMS]>

Validate the form by calling L<validate()|Rose::HTML::Form::Field/validate> on each field and L<validate()|/validate> on each each L<sub-form|/"NESTED FORMS">.  If any field or form returns false from its C<validate()> method call, then this method r...

If this method is about to return false and the L<error|Rose::HTML::Object/error> attribute of this form is not set, then it is set to a generic error message.

PARAMS are name/value pairs.  Valid parameters are:

=over 4

=item C<cascade BOOL>

If true, then the L<validate()|/validate> method of each sub-form is called, passing PARAMS, with a C<form_only> parameter set to true.  The default value of the C<cascade> parameter is true.  Note that all fields in all nested forms are validated re...

=item C<form_only BOOL>

If true, then the  L<validate|Rose::HTML::Form::Field/validate> method is not called on the fields of this form and its sub-forms.  Defaults to false, but is set to true when calling  L<validate()|/validate> on sub-forms in response to the C<cascade>...

=back

Examples:

    $form = Rose::HTML::Form->new;
    $form->add_field(foo => { type => 'text' });

    $subform = Rose::HTML::Form->new;
    $subform->add_field(bar => { type => 'text' });

    $form->add_form(sub => $subform);

    # Call validate() on fields "foo" and "sub.bar" and
    # call validate(form_only => 1) on the sub-form "sub"
    $form->validate;

    # Same as above
    $form->validate(cascade => 1);

    # Call validate() on fields "foo" and "sub.bar"
    $form->validate(cascade => 0);

    # Call validate(form_only => 1) on the sub-form "sub"
    $form->validate(form_only => 1);

    # Don't call validate() on any fields or sub-forms
    $form->validate(form_only => 1, cascade => 0);

=item B<validate_field_html_attrs [BOOL]>

Get or set a boolean flag that indicates whether or not the fields of this form will validate their HTML attributes.  If a BOOL argument is passed, then it is passed as the argument to a call to L<validate_html_attrs()|Rose::HTML::Object/validate_htm...

=item B<was_submitted>

Returns true id L<params exist|/param_exists_for_field> for any L<field|/fields>, false otherwise.

=item B<xhtml_hidden_fields>

Returns the XHTML serialization of the fields returned by L<hidden_fields()|/hidden_fields>, joined by newlines.

=back

=head1 SUPPORT

Any L<Rose::HTML::Objects> questions or problems can be posted to the L<Rose::HTML::Objects> mailing list.  To subscribe to the list or search the archives, go here:

L<http://groups.google.com/group/rose-html-objects>

Although the mailing list is the preferred support mechanism, you can also email the author (see below) or file bugs using the CPAN bug tracking system:

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-HTML-Objects>

There's also a wiki and other resources linked from the Rose project home page:

L<http://rosecode.org>

=head1 AUTHOR

John C. Siracusa (siracusa@gmail.com)

=head1 LICENSE

Copyright (c) 2010 by John C. Siracusa.  All rights reserved.  This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.



( run in 0.738 second using v1.01-cache-2.11-cpan-13bb782fe5a )