package HTML::FormFu::Element::Checkboxgroup; use strict; use base 'HTML::FormFu::Element::_Group'; use Class::C3; use HTML::FormFu::Constants qw( $EMPTY_STR ); use HTML::FormFu::Util qw( append_xml_attribute process_attrs ); use List::MoreUtils qw( any ); __PACKAGE__->mk_item_accessors(qw/ input_type /); sub new { my $self = shift->next::method(@_); $self->filename('input'); $self->field_filename('checkboxgroup_tag'); $self->label_tag('legend'); $self->container_tag('fieldset'); $self->multi_value(1); $self->input_type('checkbox'); return $self; } 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->next::method( { field_filename => $self->field_filename, 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 "\n", process_attrs( $render->{attributes} ); for my $option ( @{ $render->{options} } ) { if ( defined $option->{group} ) { $html .= sprintf "\n", process_attrs( $option->{attributes} ), ; for my $item ( @{ $option->{group} } ) { $html .= sprintf qq{\n}, process_attrs( $item->{container_attributes} ), $render->{nested_name}, $render->{input_type}, $item->{value}, process_attrs( $item->{attributes} ), ; $html .= sprintf "\n%s\n\n", process_attrs( $item->{label_attributes} ), $item->{label}, ; } $html .= "\n"; } else { $html .= sprintf qq{\n}, process_attrs( $option->{container_attributes} ), $render->{nested_name}, $render->{input_type}, $option->{value}, process_attrs( $option->{attributes} ), ; $html .= sprintf "\n%s\n\n", process_attrs( $option->{label_attributes} ), $option->{label}, ; } } $html .= ""; return $html; } 1; __END__ =head1 NAME HTML::FormFu::Element::Checkboxgroup - Group of checkbox form fields =head1 SYNOPSIS YAML config: --- elements: - type: Checkboxgroup name: subjects options: - 'Math' - 'Science' - 'English' =head1 DESCRIPTION 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 L for details. =head1 METHODS =head2 options See L. =head2 values See L. =head2 value_range See L. =head2 auto_id In addition to the substitutions documented by L, C<%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" =head1 SEE ALSO Is a sub-class of, and inherits methods from L, L, L L =head1 AUTHOR Carl Franks, C =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself.