[html-formfu] HTML::FormFu::Element::DBIC::Select for review

Mario Minati mario.minati at googlemail.com
Sun Sep 9 17:02:41 GMT 2007


At the bottom of the email you find an extended version with support 
for %where and %attribtes  and some little docs.

Still no test's ;-)

@Carl:
shall I put it in the SVN.

Greets,
Mario

On Sunday 09 September 2007 10:40:37 Daisuke Maki wrote:
> One of the things I'd like to see is the ability to specify both the
> condition from which to select the elements to be in the select field,
> as well as the ability to sort the elements by an arbitrary criteria.
>
>
> What do you think about being able to specify %where and %attr that
> search() will use?
>
> --d
>
> Mario Minati wrote:
> > Hello @all,
> >
> > I would like to share my HTML::FormFu::Element::DBIC::Select class, as
> > the community around FormFu is growing now, someone else might need it or
> > use it for inspiration.
> >
> > It has no documentation and test, it's just working(tm).
> >
> > I use it to create select boxes which gets it's data from the table,
> > where also the models have relations.
> >
> > It takes as parameters:
> > model - the dbic model name
> > search - the search function to use (search by default)
> > name_field - the fieldname containing the displayed name (the name field
> > of the element by default)
> > value_field - the fieldname containing the value ('id' by default)
> >
> > Greets,
> > Mario
> >
> > PS:
> > Maybe someone else can think about the shortcut I build in for
> > performance reasons. Do I might ran in a DB issue?

package glue::HTML::FormFu::Element::DBIC::Select;

use strict;
use warnings;

use base 'HTML::FormFu::Element::Select';

use Carp;


__PACKAGE__->mk_accessors( qw/
    model
    search
    where
    search_attr
    name_field
    value_field
/ );


sub process {
    my $self = shift;

    $self->_add_options;
    #$self->add_attributes( class => 'dbix_class_select');

    my $process = $self->next::method( { @_ ? %{ $_[0] } : () } );

    return $process;
}


sub render {
    my $self = shift;

    $self->_add_options;
    #$self->add_attributes( class => 'dbix_class_select');

    my $render = $self->next::method( { @_ ? %{ $_[0] } : () } );

    return $render;
}


sub _add_options {
    my $self = shift;

    # shortcut
    if (defined $self->{__data}) {
        $self->options( $self->{__data} );
        return;
    }

    my $stash = $self->form->{stash};

    # check model name
    $self->model
        or die "Model not named - Need model name for DB check.";

    # check Catalyst context
    $stash->{context}
        or die "Catalyst context not available.";

    # check for valid model
    my $model = $stash->{context}->model( $self->model )
        or die "Model not defined - DB check failed for model '". 
$self->model. "'.";

    # search function
    my $search = $self->search() || 'search';

    # get where argument for search function
    my $where = $self->where() || {};

    #get attribute argument for search function
    my $search_attr = $self->search_attr() || {};

    # get data
    my @data = $model->$search( $where, $search_attr )->all();

    # get name and value fields
    my $name_field = $self->name_field  || $self->name;
    my $value_field = $self->value_field || 'id';

    # create array of options
    my @options = map { [ $_->$value_field, $_->$name_field ] } @data;

    # safe for shortcut
    $self->{__data} = \@options;

    # set array of options
    $self->options( \@options );

    return;
}


1;

__END__

=head1 NAME

HTML::FormFu::Element::DBIC::Select - DBIC driven Select Element

=head1 DESCRIPTION

Gets it's data from DBIC Class in Catalyst context.

If no search function is given, the default search will be used.

name_field will be used as the name of the option elements.

value_field will be used as the value for the option elements.

=head1 HOWTO

=head2 create element

Example:
      - type: HTML::FormFu::Element::DBIC::Select
        model: 'glueDB::Contact::Channel::Entry::Type'
        name: type_id
        label: Channel Type
        search: my_custom_search
        name_field: name
        value_field: id
        constraints: [ AutoSet ]
        where:
          -or:
            - -and
            -
              - artist
              - like: '%Smashing Pumpkins%'
              - title
              - Siamese Dream
            - artist
            - Starchildren
        search_attr:
          as:
            - name
            - cd_count
          group_by:
            - name
          join:
            - cds
          select:
            - name
            - count: cds.cdid

=head2 create where and attributes clauses

There is support for complex where clauses and attributes.

Here you find some examples of how you transform the Perl structures into
something YAML understands:

my $where_hash = {
    -or => [
      -and => [
        artist => { 'like', '%Smashing Pumpkins%' },
        title  => 'Siamese Dream',
      ],
      artist => 'Starchildren',
    ],
  };

would be in YAML:
where:
  -or:
    - -and
    -
      - artist
      - like: '%Smashing Pumpkins%'
      - title
      - Siamese Dream
    - artist
    - Starchildren


my $another_where_hash = {
    artist => { 'like', '%Lamb%' },
    title  => { 'like', '%Fear of Fours%' },
  };

would be in YAML:
where:
  artist:
    like: '%Lamb%'
  title:
    like: '%Fear of Fours%'


my $attribute_hash =     {
      join     => [qw/ cds /],
      select   => [ 'name', { count => 'cds.cdid' } ],
      as       => [qw/ name cd_count /],
      group_by => [qw/ name /]
    };

would be in YAML:
search_attr:
  as:
    - name
    - cd_count
  group_by:
    - name
  join:
    - cds
  select:
    - name
    - count: cds.cdid

=head1 KNOWN PROBLEMS
If a custom search function is used it will get also the where and search_attr
parameters.

=head1 SEE ALSO

Is a sub-class of, and inherits methods from L<HTML::FormFu::Element::Select>

L<HTML::FormFu::FormFu>

=head1 AUTHOR

Mario Minati C<mario.minati at googlemail.com>

=head1 LICENSE

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



More information about the HTML-FormFu mailing list