Hi, Thanks for such a detailed analysis of the problem. I'll apply your patch and release a new version of HTML::Widget::DBIC.
But explaining the current situation - I am waiting for the HTML::FormFu to be released and then I'll convert the DBIC code to be based on it and make HTML::Widget::DBIC obsolete. Anyway Thanks, Zbyszek On 3/30/07, stephen joseph butler <[EMAIL PROTECTED]> wrote:
(Apologies is this is the wrong list) I'm trying to create a select list for a database key that is either an integer or null. The code to do this looks something like this (this is Catalyst and DBIx::Class): package Foo::Controller::Bar; # blah blah blah sub widget { my ( $self, $c ) = @_; my $w = $c->widget( 'baz' ); my @bazes = $c->model( 'Foo::Baz' )->search( undef, { select => [qw/id name/], order_by => 'name' } ); $w->method( 'post' ); $w->element( 'Select', 'baz_id' ) ->label( 'Baz' ) ->size( 1 ) ->multiple( 0 ) ->options( '' => '(none)', map { $_->id => $_->name } @bazes ); return $w; } sub save : Local { my ( $self, $c, $id ) = @_; my $widget = $self->widget( $c ); my $result; $widget->action( $c->uri_for( 'save', $id ) ); $widget->element( 'Submit', 'save' ) ->value( 'Save' ); $result = $widget->process( $c->request ); if ($result->has_errors) { # do stuff to redisplay the form } else { my $bar; if (defined $id) { $bar = $c->model( 'Foo::Bar' )->find( $id ); } else { $bar = $c->model( 'Foo::Bar' )->create( {} ); } $bar->populate_from_widget( $result ); $c->response->redirect( $c->uri_for( 'list' ) ); } } More code than I probably needed to show... but anyway, I change to the '(none)' option and nothing happens. It doesn't save. Looking through the code for DBIC::HTMLWidget I think the problem is here: sub populate_from_widget { my ($dbic,$result)[EMAIL PROTECTED]; croak('populate_from_widget needs a HTML::Widget::Result object as argument') unless ref $result && $result->isa('HTML::Widget::Result'); # find all checkboxes my %cb = map {$_->name => undef } grep { $_->isa('HTML::Widget::Element::Checkbox') } $result->find_elements; foreach my $col ( $dbic->result_source->columns ) { my $col_info = $dbic->column_info($col); my $value = scalar($result->param($col)); if ($col_info->{data_type} and $col_info->{data_type} =~ m/^timestamp|date|integer|numeric/i and defined $value and $value eq '') { $value = undef; } if (defined($value) and !ref($value) and $value eq 'undef') { $value = undef; } $dbic->$col($value) if defined $value || exists $cb{$col}; } $dbic->insert_or_update; return $dbic; } Couple things: 1) The schema loader made my column data_type INT, which doesn't match the regex. 2) When updating the baz_id column, it skips it because the value is now undefined. That was the point! Am I doing something wrong? I manually changed the code to look like this, and it seems to work: sub populate_from_widget { my ($dbic,$result)[EMAIL PROTECTED]; croak('populate_from_widget needs a HTML::Widget::Result object as argument') unless ref $result && $result->isa('HTML::Widget::Result'); # find all checkboxes my %cb = map {$_->name => undef } grep { $_->isa('HTML::Widget::Element::Checkbox') } $result->find_elements; foreach my $col ( $dbic->result_source->columns ) { my $col_info = $dbic->column_info($col); my $value = scalar($result->param($col)); next unless defined $value || exists $cb{ $col }; if ($col_info->{data_type} and $col_info->{data_type} =~ m/^timestamp|date|int|numeric/i and defined $value and $value eq '') { $value = undef; } if (defined($value) and !ref($value) and $value eq 'undef') { $value = undef; } $dbic->$col($value); } $dbic->insert_or_update; return $dbic; } _______________________________________________ Html-widget mailing list Html-widget@lists.rawmode.org http://lists.rawmode.org/cgi-bin/mailman/listinfo/html-widget
-- Zbigniew Lukasiak http://brudnopis.blogspot.com/ _______________________________________________ Html-widget mailing list Html-widget@lists.rawmode.org http://lists.rawmode.org/cgi-bin/mailman/listinfo/html-widget