NAME
    HTML::FormFu::Model::DBIC - Integrate HTML::FormFu with DBIx::Class

SYNOPSIS
    Example of typical use in a Catalyst controller:

        sub edit : Chained {
            my ( $self, $c ) = @_;
        
            my $form = $c->stash->{form};
            my $book = $c->stash->{book};
        
            if ( $form->submitted_and_valid ) {
            
                # update dbic row with submitted values from form
            
                $form->model->update( $book );
            
                $c->response->redirect( $c->uri_for('view', $book->id) );
                return;
            }
            elsif ( !$form->submitted ) {
            
                # use dbic row to set form's default values
            
                $form->model->default_values( $book );
            }
        
            return;
        }

SETUP
    For the form object to be able to access your DBIx::Class schema, it
    needs to be placed on the form stash, with the name "schema".

    This is easy if you're using Catalyst-Controller-HTML-FormFu, as you can
    set this up to happen in your Catalyst app's config file.

    For example, if your model is named "MyApp::Model::Corp", you would set
    this (in Config::General format):

        <Controller::HTML::FormFu>
            <model_stash>
                schema Corp
            </model_stash>
        </Controller::HTML::FormFu>

    Or if your app's config file is in YAML format:

        'Controller::HTML::FormFu':
            model_stash:
                schema: Corp

METHODS
  default_values
    Arguments: $dbic_row, [\%config]

    Return Value: $form

        $form->model->default_values( $dbic_row );

    Set a form's default values from the database, to allow a user to edit
    them.

  update
    Arguments: [$dbic_row], [\%config]

    Return Value: $dbic_row

        $form->model->update( $dbic_row );

    Update the database with the submitted form values.

  create
    Arguments: [\%config]

    Return Value: $dbic_row

        my $dbic_row = $form->model->create( {resultset => 'Book'} );

    Like "update", but doesn't require a $dbic_row argument.

    You need to ensure the DBIC schema is available on the form stash - see
    "SYNOPSIS" for an example config.

    The "resultset" must be set either in the method arguments, or the form
    or block's "model_config".

    An example of setting the ResultSet name on a Form:

        ---
        model_config:
          resultset: FooTable
    
        elements:
          # [snip]

  options_from_model
    Populates a multi-valued field with values from the database.

    This method should not be called directly, but is called for you during
    "$form->process" by fields that inherit from
    HTML::FormFu::Element::_Group. This includes:

    HTML::FormFu::Element::Select
    HTML::FormFu::Element::Checkboxgroup
    HTML::FormFu::Element::Radiogroup
    HTML::FormFu::Element::ComboBox

    To use you must set the appropriate "resultset" on the element
    "model_config":

        element:
          - type: Select
            name: foo
            model_config:
              resultset: TableClass

BUILDING FORMS
  single table
    To edit the values in a row with no related rows, the field names simply
    have to correspond to the database column names.

    For the following DBIx::Class schema:

        package MySchema::Book;
        use base 'DBIx::Class';
    
        __PACKAGE__->load_components(qw/ Core /);
    
        __PACKAGE__->table("book");
    
        __PACKAGE__->add_columns(
            id     => { data_type => "INTEGER" },
            title  => { data_type => "TEXT" },
            author => { data_type => "TEXT" },
            blurb  => { data_type => "TEXT" },
        );
    
        __PACKAGE__->set_primary_key("id");
    
        1;

    A suitable form for this might be:

        elements:
          - type: Text
            name: title
      
          - type: Text
            name: author
      
          - type: Textarea
            name: blurb

  might_have and has_one relationships
    Set field values from a related row with a "might_have" or "has_one"
    relationship by placing the fields within a Block (or any element that
    inherits from Block, such as Fieldset) with its "nested_name" in
    HTML::FormFu set to the relationship name.

    For the following DBIx::Class schemas:

        package MySchema::Book;
        use base 'DBIx::Class';
    
        __PACKAGE__->load_components(qw/ Core /);
    
        __PACKAGE__->table("book");
    
        __PACKAGE__->add_columns(
            id    => { data_type => "INTEGER" },
            title => { data_type => "TEXT" },
        );
    
        __PACKAGE__->set_primary_key("id");
    
        __PACKAGE__->might_have( review => 'MySchema::Review', 'book' );
    
        1;


        package MySchema::Review;
        use base 'DBIx::Class';
    
        __PACKAGE__->load_components(qw/ Core /);
    
        __PACKAGE__->table("review");
    
        __PACKAGE__->add_columns(
            id          => { data_type => "INTEGER" },
            book        => { data_type => "INTEGER", is_nullable => 1 },
            review_text => { data_type => "TEXT" },
        );
    
        __PACKAGE__->set_primary_key("book");
    
        __PACKAGE__->belongs_to( book => 'MySchema::Book' );
    
        1;

    A suitable form for this would be:

        elements:
          - type: Text
            name: title
      
          - type: Block
            nested_name: review
            elements:
              - type: Textarea
                name: review_text

    For "might_have" and "has_one" relationships, you generally shouldn't
    need to have a field for the related table's primary key, as DBIx::Class
    will handle retrieving the correct row automatically.

    You can also set a "has_one" or "might_have" relationship using a multi
    value field like Select.

        elements:
          - type: Text
            name: title
      
          - type: Select
            nested: review
            model_config:
              resultset: Review

    This will load all reviews into the select field. If you select a review
    from that list, a current relationship to a review is removed and the
    new one is added. This requires that the primary key of the "Review"
    table and the foreign key do not match.

  has_many and many_to_many relationships
    The general principle is the same as for "might_have" and "has_one"
    above, except you should use a Repeatable element instead of a Block,
    and it needs to contain a Hidden field corresponding to the foreign key.

    The Repeatable block's nested_name must be set to the name of the
    relationship.

    The Repeable block's increment_field_names must be true (which is the
    default value).

    The Repeable block's counter_name must be set to the name of a Hidden
    field, which is placed outside of the Repeatable block. This field is
    used to store a count of the number of repetitions of the Repeatable
    block were created. When the form is submitted, this value is used
    during "$form->process" to ensure the form is rebuilt with the correct
    number of repetitions.

    For the following DBIx::Class schemas:

        package MySchema::Book;
        use base 'DBIx::Class';
    
        __PACKAGE__->load_components(qw/ Core /);
    
        __PACKAGE__->table("book");
    
        __PACKAGE__->add_columns(
            id    => { data_type => "INTEGER" },
            title => { data_type => "TEXT" },
        );
    
        __PACKAGE__->set_primary_key("id");
    
        __PACKAGE__->has_many( review => 'MySchema::Review', 'book' );
    
        1;


        package MySchema::Review;
        use base 'DBIx::Class';
    
        __PACKAGE__->load_components(qw/ Core /);
    
        __PACKAGE__->table("review");
    
        __PACKAGE__->add_columns(
            book        => { data_type => "INTEGER" },
            review_text => { data_type => "TEXT" },
        );
    
        __PACKAGE__->set_primary_key("book");
    
        __PACKAGE__->belongs_to( book => 'MySchema::Book' );
    
        1;

    A suitable form for this would be:

        elements:
          - type: Text
            name: title
      
          - type: Hidden
            name: review_count
      
          - type: Repeatable
            nested_name: review
            counter_name: review_count
            elements:
              - type: Hidden
                name: book
          
              - type: Textarea
                name: review_text

  many_to_many selection
    To select / deselect rows from a "many_to_many" relationship, you must
    use a multi-valued element, such as a Checkboxgroup or a Select with
    multiple set.

    The field's name must be set to the name of the "many_to_many"
    relationship.

   default_column
    If you want to search / associate the related table by a column other
    it's primary key, set "$field->model_config->{default_column}".

        ---
        element:
            - type: Checkboxgroup
              name: authors
              model_config:
                default_column: foo

   link_values
    If you want to set columns on the link table you can do so if you add a
    "link_values" attribute to "model_config":

        ---
        element:
            - type: Checkboxgroup
              name: authors
              model_config:
                link_values:
                  foo: bar

   additive
    The default implementation will first remove all related objects and set
    the new ones (see
    <http://search.cpan.org/perldoc?DBIx::Class::Relationship::Base#set_$rel
    >). If you want to add the selected objects to the current set of
    objects set "additive" in the "model_config".

        ---
        element:
            - type: Checkboxgroup
              name: authors
              model_config:
                additive: 1
                options_from_model: 0

    "options_from_model" is set to 0 because it will try to fetch all
    objects from the result class "Authors" if "model_config" is specified
    without a "resultset" attribute.)

COMMON ARGUMENTS
    The following items are supported in the optional "config" hash-ref
    argument to the methods default_values, update and create.

    base
        If you want the method to process a particular Block element, rather
        than the whole form, you can pass the element as a "base" argument.

            $form->default_values(
                $row,
                {
                    base => $formfu_element,
                },
            );

    nested_base
        If you want the method to process a particular Block element by
        name, you can pass the name as an argument.

            $form->default_values(
                $row,
                {
                    nested_base => 'foo',
                }'
            );

CONFIGURATION
  Config options for fields
    The following items are supported as "model_config" options on form
    fields.

    accessor
        If set, "accessor" will be used as a method-name accessor on the
        "DBIx::Class" row object, instead of using the field name.

    delete_if_empty
        Useful for editing a "might_have" related row containing only one
        field.

        If the submitted value is blank, the related row is deleted.

        For the following DBIx::Class schemas:

            package MySchema::Book;
            use base 'DBIx::Class';
    
            __PACKAGE__->load_components(qw/ Core /);
    
            __PACKAGE__->table("book");
    
            __PACKAGE__->add_columns(
                id    => { data_type => "INTEGER" },
                title => { data_type => "TEXT" },
            );
    
            __PACKAGE__->set_primary_key("id");
    
            __PACKAGE__->might_have( review => 'MySchema::Review', 'book' );
    
            1;


            package MySchema::Review;
            use base 'DBIx::Class';
    
            __PACKAGE__->load_components(qw/ Core /);
    
            __PACKAGE__->table("review");
    
            __PACKAGE__->add_columns(
                book        => { data_type => "INTEGER" },
                review_text => { data_type => "TEXT" },
            );
    
            __PACKAGE__->set_primary_key("book");
    
            __PACKAGE__->belongs_to( book => 'MySchema::Book' );
    
            1;

        A suitable form for this would be:

            elements:
              - type: Text
                name: title
      
              - type: Block
                nested_name: review
                elements:
                  - type: Text
                    name: review_text
                    model_config:
                      delete_if_empty: 1

    label
        To use a column value for a form field's label.

  Config options for fields within a Repeatable block
    delete_if_true
        Intended for use on a Checkbox field.

        If the checkbox is checked, the following occurs: for a has-many
        relationship, the related row is deleted; for a many-to-many
        relationship, the relationship link is removed.

        An example of use might be:

            elements:
              - type: Text
                name: title
      
              - type: Hidden
                name: review_count
      
              - type: Repeatable
                nested_name: review
                counter_name: review_count
                elements:
                  - type: Hidden
                    name: book
          
                  - type: Textarea
                    name: review_text
          
                  - type: Checkbox
                    name: delete_review
                    label: 'Delete Review?'
                    model_config:
                      delete_if_true: 1

        Note: make sure the name of this field does not clash with one of
        your DBIx::Class::Row method names (e.g. "delete") - see "CAVEATS".

  Config options for Repeatable blocks
    empty_rows
        For a Repeatable block corresponding to a has-many or many-to-many
        relationship, to allow the user to insert new rows, set "empty_rows"
        to the number of extra repetitions you wish added to the end of the
        Repeatable block.

    new_rows_max
        Set to the maximum number of new rows that a Repeatable block is
        allowed to add.

        If not set, it will fallback to the value of "empty_rows".

  Config options for options_from_model
    The column used for the element values is set with the "model_config"
    value "id_column" - or if not set, the table's primary column is used.

        element:
          - type: Select
            name: foo
            model_config:
              resultset: TableClass
              id_column: pk_col

    The column used for the element labels is set with the "model_config"
    value "label_column" - or if not set, the first text/varchar column
    found in the table is used - or if one is not found, the "id_column" is
    used instead.

        element:
          - type: Select
            name: foo
            model_config:
              resultset: TableClass
              label_column: label_col

    To pass the database label values via the form's localization object,
    set "localize_label"

        element:
          - type: Select
            name: foo
            model_config:
              localize_label: 1

    You can set a "condition", which will be passed as the 1st argument to
    "search" in DBIx::Class::ResultSet.

        element:
          - type: Select
            name: foo
            model_config:
              resultset: TableClass
              condition:
                type: is_foo

    You can set a "condition_from_stash", which will be passed as the 1st
    argument to "search" in DBIx::Class::ResultSet.

    "key" is the column-name to be passed to search, and "stash_key" is the
    name of a key on the form stash from which the value to be passed to
    search is found.

        element:
          - type: Select
            name: foo
            model_config:
              resultset: TableClass
              condition_from_stash:
                key: stash_key

    Is comparable to:

        $form->element({
            type => 'Select',
            name => 'foo',
            model_config => {
                resultset => 'TableClass',
                condition => {
                    key => $form->stash->{stash_key}
                }
            }
        })

    You can set "attributes", which will be passed as the 2nd argument to
    "search" in DBIx::Class::ResultSet.

FAQ
  Add extra values not in the form
    To update values to the database which weren't submitted to the form,
    you can first add them to the form with add_valid.

        my $passwd = generate_passwd();
    
        $form->add_valid( passwd => $passwd );
    
        $form->model->update( $row );

    "add_valid" works for fieldnames that don't exist in the form.

  Set a field read only
    You can make a field read only. The value of such fields cannot be
    changed by the user even if they submit a value for it.

      $field->model_config->{read_only} = 1;
  
      - Name: field
        model_config:
          read_only: 1

    See HTML::FormFu::Element::Label.

CAVEATS
    To ensure your column's inflators and deflators are called, we have to
    get / set values using their named methods, and not with "get_column" /
    "set_column".

    Because of this, beware of having column names which clash with
    DBIx::Class built-in method-names, such as "delete". - It will have
    obviously undesirable results!

REMOVED METHODS
  new_empty_row
    See "empty_rows" in "Config options for Repeatable blocks" instead.

  new_empty_row_multi
    See "new_rows_max" in "Config options for Repeatable blocks" instead.

  Range constraint
    See "empty_rows" in "Config options for Repeatable blocks" instead.

SUPPORT
    Project Page:

    <http://code.google.com/p/html-formfu/>

    Mailing list:

    <http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu>

    Mailing list archives:

    <http://lists.scsys.co.uk/pipermail/html-formfu/>

BUGS
    Please submit bugs / feature requests to
    <http://code.google.com/p/html-formfu/issues/list> (preferred) or
    <http://rt.perl.org>.

SUBVERSION REPOSITORY
    The publicly viewable subversion code repository is at
    <http://html-formfu.googlecode.com/svn/trunk/HTML-FormFu-Model-DBIC>.

    If you wish to contribute, you'll need a GMAIL email address. Then just
    ask on the mailing list for commit access.

    If you wish to contribute but for some reason really don't want to sign
    up for a GMAIL account, please post patches to the mailing list
    (although you'll have to wait for someone to commit them).

    If you have commit permissions, use the HTTPS repository url:
    <https://html-formfu.googlecode.com/svn/trunk/HTML-FormFu-Model-DBIC>

SEE ALSO
    HTML::FormFu, DBIx::Class, Catalyst::Controller::HTML::FormFu

AUTHOR
    Carl Franks

CONTRIBUTORS
    Based on the code of "DBIx::Class::HTML::FormFu", which was contributed
    to by:

    Adam Herzog

    Daisuke Maki

    Mario Minati

COPYRIGHT AND LICENSE
    Copyright (C) 2007 by Carl Franks

    Based on the original source code of DBIx::Class::HTMLWidget, copyright
    Thomas Klausner.

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.8.8 or, at
    your option, any later version of Perl 5 you may have available.

