[Html-widget] formfu - What's the best way to add dynamic defaults?

Carl Franks fireartist at gmail.com
Thu Mar 29 09:25:03 GMT 2007


On 29/03/07, Daisuke Maki <daisuke at endeworks.jp> wrote:
> Hi,
>
> I have a form that should have today's date in it unless otherwise
> specified. I kind of hacked around this by saying:
>
>     my $dt = DateTime->today(time_zone => 'local');
>     foreach my $field qw(year month day) {
>         my $element = $form->get_field(name => $field, type => 'text');
>         next unless $element;
>         $element->attributes->{value} ||= $dt->$field;
>     }

I'm not entirely sure what you mean by "unless otherwise specified".
Otherwise specified by what / where?
The solution might differ according to whether you mean it's set
somewhere else in the code/config, or whether it's set by the user in
a submitted form.

If you want to set a field's default value, which if redisplayed after
errors will be overridden by whatever the user entered - then you
should use:
    $element->default( $value );

For dates, I'm tending to prefer the Dojo::DropdownDate element -
which provides a JS date-picker GUI and fallsback to a single textbox
if JS is switched off.

I think using a deflator would be a bit of an abuse, as they're not
reallly designed to process multiple field's values.
Something like this might work - but you'll need to test it.
The deflators are only run if the form wasn't submitted.
You might need to make sure the deflator is associated with whichever
of the year/month/day fields was added to the form first. In my
example, I've assumed it's the 'year' field.


---
elements:
  - type: text
    name: year
    deflators:
      - +MyApp::Deflator::DateNow
  - type: text
    name: month
  - type: text
    name: day


package MyApp::Deflator::DateNow;
use strict;
use warnings;
use base 'HTML::FormFu::Deflator';

sub deflator {
    my ( $self, $value ) = @_;

    my $year  = $self->parent;
    my $month = $self->form->get_field({ name => 'month', type => 'text' });
    my $day   = $self->form->get_field({ name => 'day',   type => 'text' });

    if ( !defined $value && !defined $month->default && !defined $day->default )
    {
        my $dt = DateTime->today( time_zone => 'local' );

        $month->default( $dt->month );
        $day->default(   $dt->day );

        return $dt->year;
    }

    return $value;
}
1;

Ideas for a more general multi-field preprocessor mechanism welcome!

Carl



More information about the Html-widget mailing list