[Html-widget] latest formfu developments - Controller and Constraints

Mario Minati mario at minati.de
Tue Feb 27 15:32:30 GMT 2007


Carl Franks schrieb:
> On 24/02/07, Mario Minati <mario at minati.de> wrote:
>> An other question about the FormFu Controller:
>> First I was really amazed by the idea of creating forms from yml, but
>> than I realized, that I need Callback-constraints and to incoporate data
>> from different tables into select fields, which won't work via yml 
>> files.
>> Then I tried to use the FormFu Controller in FormMethod style to create
>> the form. But I don't understand yet how to create the data for the
>> populate function. If it is also 'only' a hashref like in the .t-files
>> than I also cannot create callbacks.
>
> A hashref can hold code-refs, so something like this would work:
> sub my_sub_which_returns_a_form_hashref {
>  return {
>    constraints => [
>      [ Callback => 'foo', { callback => sub { #do something# } } ],
>    ],
>  };
> }
Is it possible that the CallbackOnce constraint works different then 
that one from HTML::Widget?
I used it like this:
#    $form->constraint(CallbackOnce => qw/name pre/)->callback(sub {
#    my ($name, $pre) = @_;
So I got the values of that fields.
As I understand your code I only get the value of the field which the 
constraint belongs to. Correct?
>
> You could use the FormMethod action, which could even load the bulk of
> the form from a config file, and then just add the things which need
> to be done programatically.
>
> Because load_config_file() uses Config::Any - which supports loading
> perl files - you could still define your programatic constraints in a
> config file (as long as it doesn't require access to runtime data)
>
> As far as getting db data into select fields is concerned, there's not
> really any way around doing that somewhere in your code.
> If you're using DBIx::Class, you could create a db-specific formfu
> element which gets the data itself, by accessing the dbic classes
> directly.

At the moment I am experimenting with the FormMethod Action Class.

For me it would be very usefull if the form creating functon could be 
called with $c as parameter.
I hanged that in my local code like that:
    for ( @{ $self->{_attr_params} } ) {   
        for my $method ( split ) {
            $c->log->debug($method);
            my $args = $controller->$method($c) || {};
           
            $form->populate( $args );
        }
    }

This way I can autodetect a few elements for the form like this:
sub company_form {
    my ($self, $c) = @_;

my $sub = (caller(0))[3];
$sub =~ s/^([^\:]+\:\:)*//;
$c->log->debug("Setting default form id to: ".$sub);
$c->log->debug("Setting default form action to: 
".$c->uri_for($c->{action}->name));
return {
    action    => $c->uri_for($c->{action}->name),
    id        => $sub,
    elements  => [ [
...

I will put this in a seperate function that provides some common form 
code, or do you want to put it in formMethod to provide some defaults 
that the user could override.

After bringing that to work (yesterday) I decided (today) to switch to 
FormConfig with yml-files, as I can get rid of the formcode in my 
controller. After understanding YAML it works quite well.
Now I am as  fascinated as you are. ;-)


There is only one constraint than I cannot create at the moment:
Some db tables in my model have unique constraints, so I do a search 
with the new data before accepting it.
I am imaging a hidden field that contains the id of the data set (for 
edit) or an empty string (for create) and constraint on that with the 
model name and the parameters names that have to be included (could be 
autodetected from the required fields).
But the one thing that is missing to acomplish this is $c from catalyst. 
Do you see a chance to pass it through / hold it in formfu?


>
>> If I am right (don't hope so) how can I create a form, as with the Form
>> Action the result gets calculated before I could add any elements
>> programatically.
>
> I find that sometimes I have to overwrite the result that the Action 
> created:
>    $db->fill_formfu_values( $form );
>    $c->stash->{result} = $form->result;
Does this (calling result twice) cost maybe to much runtime?
>
> Because as well as modifying the form object, you can modify the
> result object using add_valid() and add_error() - it's not really
> practical to always use an auto-generated result. I can't really see
> any way round this.
Ok.

By the way I made a TrimEdges Filter.You can put it in the svn if you want.

=====
package HTML::FormFu::Filter::TrimEdges;

use strict;
use warnings;
use base 'HTML::FormFu::Filter';

sub filter {
    my ( $self, $value ) = @_;
    $value =~ s/^\s+//;
    $value =~ s/\s+$//;
    return $value;
}

1;

__END__

=head1 NAME

HTML::FormFu::Filter::TrimEdges - Trim whitespaces from beginning and 
end of string

=head1 SYNOPSIS

    $form->filter( TrimEdges => 'foo' );

=head1 DESCRIPTION

Trim whitespaces from beginning and end of string.

=head1 AUTHOR

Mario Minati, C<mario at minati.de>

Based on the original source code of L<HTML::Widget::Filter::TrimEdges>, by
Sebastian Riedel, C<sri at oook.de>

=head1 LICENSE

This library is free software, you can redistribute it and/or modify it 
under
the same terms as Perl itself.

=cut
=====

This was the Controller and Constraint stuff.
More in the next email. I hope you don't put me on the spam list ;-)

Greets,
Mario



More information about the Html-widget mailing list