-2

using HTML::Formhandler in Catalyst I defined a form based on a database table (item_class). What the form does is set the first three select lists based on the contents of several tables (other than the table on which the form is based) in the database. It looks like the select lists all get (html) correct options. However on commit I invariably get error: '...' is not a valid value ONLY for fields: prg_id and mrk_id.

What's my mistake? Any help is greatly appreciated.

My form definition:

package BskExt::Form::HMbestellingProducten;

use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Model::DBIC';
with 'HTML::FormHandler::Render::Table';

use namespace::autoclean;

has 'wpl_id' => ( is => 'rw' );

has '+item_class' => ( default => 'NewHmbestellingenproducten' );

has_field 'wklloc_id' => ( type => 'Select', label => 'Winkel(locatie)s' );
#has_field 'prg_id' => ( type => 'Select', label => 'Productgroep', label_column => 'naam', accessor => 'prg' );
has_field 'prg_id' => ( type => 'Select', label => 'Productgroep', error_messages => { select_invalid_value => undef } );
#has_field 'mrk_id' => ( type => 'Select', label => 'Merk', label_column => 'naam', accessor => 'mrk' );
has_field 'mrk_id' => ( type => 'Select', label => 'Merk' );
has_field 'productnaam' => ( type => 'Text',   label => 'Product *', size => 32, maxlength => 40, required => 1, messages => { required => 'Verplicht' }, validate_method => \&CatFormFieldValidate::validate_name_ext );
has_field ' ' => ( type => 'Submit', id => 'submit', value => 'Ga door' ); 

#
# The select list for wklloc_id is set by options_wklloc_id which has been omitted from
# this listing as it made the listing (much) too long
# 
sub options_mrk_id
{
  my ($self) = shift;

  my (@mrk_select_list);

  undef(@mrk_select_list);
  push @mrk_select_list, { value => '', label => 'Kies eerst een productgroep' };

  return @mrk_select_list;
}

sub options_prg_id
{
  my ($self) = shift;

  my (@prg_select_list);

  undef(@prg_select_list);
  push @prg_select_list, { value => '', label => 'Kies eerst een winkel(-locatie)' };

  return @prg_select_list;
}

My form template:

<script>
  $(function() {
    $("#wklloc_id").click(function() {
    $("#prg_id").load("WinkelLocatieProductgroepen?wklloc_id=" + $("#wklloc_id").val());
    });
  });

  $(function() {
    $("#prg_id").click(function() {
    $("#mrk_id").load("ProductgroepMerken?wklloc_id=" + $("#wklloc_id").val() + "&prg_id=" + $("#prg_id").val());
    });
  });
</script>

<p></p>
[%# Render the HTML::FormHandler Form %]
[% form.render %]

(The significant part of) my controller:

sub create : Chained('base') PathPart('create') Args(0) {
    my ($self, $c ) = @_;

    my $hmbestprod = $c->model('DB::NewHmbestellingenproducten')->new_result({});
    return $self->form($c, $hmbestprod,'new');
}

sub form
{
    my ( $self, $c, $hmbestprod, $action ) = @_;

    my ($form,$klant_info,$uc_action);

    $uc_action = uc($action);
    $klant_info = $c->model( 'BskExt' )->KlantInfo($c->session->{"klt_id"}||0);
    $form = BskExt::Form::HMbestellingProducten->new(wpl_id => $$klant_info{"wpl_id"});
    # Set the template
    $c->stash( template => 'hmbestellingproducten/form.tt2', action => $uc_action, form => $form );
    $form->process(
                    use_init_obj_over_item => 1,
                    item => $hmbestprod,
                    init_object => { "aantal" => 1 },
                    params => $c->req->params );
    return unless $form->validated;
    # Set a status message for the user & return to list
    $c->response->redirect($c->uri_for($self->action_for('list')));
}
#
# This helps jQuery to set the content of the ProductgroepMerken form list
#
sub ProductgroepMerken :Chained('base') :PathPart('ProductgroepMerken') :Args(0)
{
  my ($self, $c) = @_;

  my ($optstr,$prg_id,$productgroepmerken,$wklloc_id);

  $c->log->debug("ProductgroepMerken\n");

  $prg_id = $c->request->params->{"prg_id"};
  $wklloc_id = $c->request->params->{"wklloc_id"};
#
# The result: $productgroepmerken contains (at first glance) valid values. These values are not in any way (directly)
# related to the FORM item_class 'NewHmbestellingenproducten'
#
  $productgroepmerken = $c->model ( 'BskExt' )->ProductgroepMerken($wklloc_id,$prg_id);
  undef($optstr);
  foreach (@$productgroepmerken)
  {
      $optstr .= '<option value="'.$_->{"id"}.'">'.$_->{"naam"}.'</option>';
  }
  $c->log->debug("optstr= $optstr\n");
  $c->response->body($optstr);
}
#
# This helps jQuery to set the content of the WinkelLocatieProductgroepen form select list
#

sub WinkelLocatieProductgroepen :Chained('base') :PathPart('WinkelLocatieProductgroepen') :Args(0)
{
  my ($self, $c) = @_;

  my ($optstr,$productgroepen,$wklloc_id);

  $c->log->debug("WinkelLocatieProductgroepen\n");

  $wklloc_id = $c->request->params->{"wklloc_id"};
#
# The result: $productgroepen contains (at first glance) valid values. These values are not in any way (directly)
# related to the FORM item_class 'NewHmbestellingenproducten'
#
  $productgroepen = $c->model ( 'BskExt' )->WinkelLocatieProductgroepen($wklloc_id);
  $c->log->debug("productgroepen= \n".Dumper($productgroepen)."\n\n");
  undef($optstr);
  foreach (@$productgroepen)
  {
      $optstr .= '<option value="'.$_->{"id"}.'">'.$_->{"naam"}.'</option>';
  }
  $c->log->debug("optstr= $optstr\n");
  $c->response->body($optstr);
}
3
  • 1
    Can you narrow your problem down and isolate the particular parts of the scripts that are causing the issue? I, and probably others, would be put off by the sheer amount of code posted here. Commented Oct 2, 2014 at 7:59
  • Sorry about that. I thought it might help to show the context of the problem. I will strip the excess code. My question is as exact/precise as I'm able to phrase it. Commented Oct 2, 2014 at 13:24
  • It looks like it is impossible to use HTML::Formhandler select fields when the options of those select fields are not DIRECTLY related to the field(definition) for the (select) field in the resultclass set of the table on which the form is based. It is however fully possible to do exactly the same thing when the html for the form is provided for in the template. In my view this is a pity because it forces one to abandon the nice features of the HTML::Formhandler field/form validation and the uniform user interface that goes with that. There is no (good) way to do this? Commented Oct 3, 2014 at 21:33

1 Answer 1

0

The select fields are validated against the options for the field. Do not put the '' empty selects in the field options, instead set them using the 'empty_select' field attribute: empty_select => 'some option label'. If select options are supposed to be automatically generated from the database, you need to use the relationship name, not the column name.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.