HTML::FormFu::Element::Checkboxgroup - Group of checkbox form fields


HTML-FormFu documentation Contained in the HTML-FormFu distribution.

Index


Code Index:

NAME

Top

HTML::FormFu::Element::Checkboxgroup - Group of checkbox form fields

SYNOPSIS

Top

YAML config:

    ---
    elements:
      - type: Checkboxgroup
        name: subjects
        options:
          - [ 'Math' ]
          - [ 'Science' ]
          - [ 'English' ]

DESCRIPTION

Top

Convenient to use group of checkbox fields.

Use the same syntax as you would to create a Select element optgroup to create Checkboxgroup sub-groups, see options in HTML::FormFu::Element::_Group for details.

METHODS

Top

options

See options in HTML::FormFu::Element::_Group.

values

See values in HTML::FormFu::Element::_Group.

value_range

See value_range in HTML::FormFu::Element::_Group.

auto_id

In addition to the substitutions documented by auto_id in HTML::FormFu, %c will be replaced by an incremented integer, to ensure there are no duplicated ID's.

    ---
    elements:
      type: Checkboxgroup
      name: foo
      auto_id: "%n_%c"

reverse_group

If true, then the label for each checkbox in the checkbox group should be rendered to the right of the field control. Otherwise, the label is rendered to the left of the field control.

The default value is true, causing each label to be rendered to the right of its field control (or to be explicit: the markup for the label comes after the field control in the source).

Default Value: true

SEE ALSO

Top

Is a sub-class of, and inherits methods from HTML::FormFu::Element::_Group, HTML::FormFu::Element::_Field, HTML::FormFu::Element

HTML::FormFu

AUTHOR

Top

Carl Franks, cfranks@cpan.org

LICENSE

Top

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


HTML-FormFu documentation Contained in the HTML-FormFu distribution.

package HTML::FormFu::Element::Checkboxgroup;
use Moose;
extends 'HTML::FormFu::Element';

with 'HTML::FormFu::Role::Element::Group';

use HTML::FormFu::Constants qw( $EMPTY_STR );
use HTML::FormFu::Util qw( append_xml_attribute process_attrs );
use List::MoreUtils qw( any );

has input_type => (
    is      => 'rw',
    default => 'checkbox',
    lazy    => 1,
    traits  => ['Chained'],
);

has reverse_group => (
    is      => 'rw',
    traits  => ['Chained'],
);

after BUILD => sub {
    my ( $self, $args ) = @_;

    $self->filename('input');
    $self->field_filename('checkboxgroup_tag');
    $self->label_tag('legend');
    $self->container_tag('fieldset');
    $self->multi_value(1);
    $self->reverse_group(1);
    $self->input_type('checkbox');

    return;
};

sub prepare_id {
    my ( $self, $render ) = @_;

    my $form_id    = defined $self->form->id    ? $self->form->id    : '';
    my $field_name = defined $self->nested_name ? $self->nested_name : '';
    my $count      = 0;

    for my $option ( @{ $render->{options} } ) {
        if ( exists $option->{group} ) {
            for my $item ( @{ $option->{group} } ) {
                $self->_prepare_id( $item, $form_id, $field_name, \$count );
            }
        }
        else {
            $self->_prepare_id( $option, $form_id, $field_name, \$count );
        }
    }

    return;
}

sub _prepare_id {
    my ( $self, $option, $form_id, $field_name, $count_ref ) = @_;

    if ( !exists $option->{attributes}{id} && defined $self->auto_id ) {
        my %string = (
            f => $form_id,
            n => $field_name,
        );

        my $id = $self->auto_id;
        $id =~ s/%([fn])/$string{$1}/g;
        $id =~ s/%c/ ++$$count_ref /gex;

        if ( defined( my $count = $self->repeatable_count ) ) {
            $id =~ s/%r/$count/g;
        }

        $option->{attributes}{id} = $id;
    }

    # label "for" attribute
    if (   exists $option->{label}
        && exists $option->{attributes}{id}
        && !exists $option->{label_attributes}{for} )
    {
        $option->{label_attributes}{for} = $option->{attributes}{id};
    }

    return;
}

sub _prepare_attrs {
    my ( $self, $submitted, $value, $default, $option ) = @_;

    if (   $submitted
        && defined $value
        && (ref $value eq 'ARRAY'
            ? any { $_ eq $option->{value} } @$value
            : $value eq $option->{value} ) )
    {
        $option->{attributes}{checked} = 'checked';
    }
    elsif ($submitted
        && $self->retain_default
        && ( !defined $value || $value eq $EMPTY_STR )
        && $self->value eq $option->{value} )
    {
        $option->{attributes}{checked} = 'checked';
    }
    elsif ($submitted) {
        delete $option->{attributes}{checked};
    }
    elsif (
        defined $default
        && (ref $default eq 'ARRAY'
            ? any { $_ eq $option->{value} } @$default
            : $default eq $option->{value} ) )
    {
        $option->{attributes}{checked} = 'checked';
    }
    return;
}

sub render_data_non_recursive {
    my ( $self, $args ) = @_;

    my $render = $self->SUPER::render_data_non_recursive( {
            field_filename => $self->field_filename,
            reverse_group  => $self->reverse_group,
            input_type     => $self->input_type,
            $args ? %$args : (),
        } );

    for my $item ( @{ $render->{options} } ) {
        if ( exists $item->{group} ) {
            append_xml_attribute( $item->{attributes}, 'class', 'subgroup' );
        }
    }

    return $render;
}

sub _string_field {
    my ( $self, $render ) = @_;

    # radiogroup_tag template

    my $html .= sprintf "<span%s>\n", process_attrs( $render->{attributes} );

    for my $option ( @{ $render->{options} } ) {
        if ( defined $option->{group} ) {
            $html .= sprintf "<span%s>\n",
                process_attrs( $option->{attributes} ),
                ;

            for my $item ( @{ $option->{group} } ) {
                $html .= sprintf
                    "<span%s>\n",
                    process_attrs( $item->{container_attributes} );

                my $label = sprintf
                    "<label%s>%s</label>\n",
                    process_attrs( $item->{label_attributes} ),
                    $item->{label},
                    ;

                my $input = sprintf
                    qq{<input name="%s" type="%s" value="%s"%s />\n},
                    $render->{nested_name},
                    $render->{input_type},
                    $item->{value},
                    process_attrs( $item->{attributes} ),
                    ;

                if ( $render->{reverse_group} ) {
                    $html .= $input . $label;
                }
                else {
                    $html .= $label . $input;
                }

                $html .= "</span>\n";
            }

            $html .= "</span>\n";
        }
        else {
            $html .= sprintf
                "<span%s>\n",
                process_attrs( $option->{container_attributes} )
                ;

            my $label = sprintf
                "<label%s>%s</label>\n",
                process_attrs( $option->{label_attributes} ),
                $option->{label},
                ;

            my $input = sprintf
                qq{<input name="%s" type="%s" value="%s"%s />\n},
                $render->{nested_name},
                $render->{input_type},
                $option->{value},
                process_attrs( $option->{attributes} ),
                ;

            if ( $render->{reverse_group} ) {
                $html .= $input . $label;
            }
            else {
                $html .= $label . $input;
            }

            $html .= "</span>\n";
        }
    }

    $html .= "</span>";

    return $html;
}

__PACKAGE__->meta->make_immutable;

1;

__END__