package HTML::FormStructure::Query;
use strict;
use base qw(Class::Accessor);
__PACKAGE__->mk_accessors(&_my_accessors);
sub _init {
my $opt = shift;
$opt->{query_accessors} = defined $opt->{query_accessors} ?
$opt->{query_accessors} : [];
__PACKAGE__->mk_accessors(
&_my_accessors,@{$opt->{query_accessors}}
);
}
sub _my_accessors {
return qw(name type value checked selected
more less be consist consistf store storef
column error
tag_label tag_attr tag_desc
tag_val_label tag_left_in tag_right_in
scratch);
}
sub new {
my $class = shift;
my $query = shift;
my $opt = shift;
_init($opt);
my $self = bless { _query => $query }, $class;
$self->$_($query->{$_}) for (keys %{$query});
return $self;
}
sub array_of {
my $self = shift;
my $meth = shift;
return unless defined $self->$meth();
my $array = defined $self->$meth() ? $self->$meth() : [];
return @{$array};
}
sub _compare_value_with_arg {
my $self = shift;
my $meth = shift;
my $arg = shift;
return unless defined $self->$meth();
my $ret = '';
if (ref $self->$meth() eq 'ARRAY') {
for (@{$self->$meth()}) {
$ret = $meth if $arg eq $_;
}
}
else {
$ret = $meth if $arg eq $self->$meth();
}
return $ret;
}
sub is_checked {
my $self = shift;
my $arg = shift;
$self->_compare_value_with_arg('checked',$arg);
}
sub is_selected {
my $self = shift;
my $arg = shift;
$self->_compare_value_with_arg('selected',$arg);
}
sub column_name {
my $self = shift;
if ($self->column == 1) {
return $self->name;
}
else {
return $self->column;
}
}
sub store_error {
my $self = shift;
my $error = $self->error || [];
push @{$error}, shift;
$self->error($error);
}
sub add { shift->add_right(@_) }
sub add_left {
my $self = shift;
my ($key,$val) = @_;
$self->_do_add($key,$val,1);
}
sub add_right {
my $self = shift;
my ($key,$val) = @_;
$self->_do_add($key,$val);
}
sub _do_add {
my $self = shift;
my ($key,$val,$left) = @_;
my $stored = defined $self->$key() ? $self->$key() : '';
if ($left) {
if (ref $stored) {
push @{$self->$key()}, $val if ref $stored eq 'ARRAY';
}
else {
$self->$key($stored . $self->$key());
}
}
else {
if (ref $stored) {
unshift @{$self->$key()}, $val if ref $stored eq 'ARRAY';
}
else {
$self->$key($stored . $val);
}
}
}
# ----------------------------------------------------------------------
sub tag {
my $self = shift;
my $tag = shift || '';
if ($self->type =~ /^(?:text|password|file|hidden)$/i) {
$tag = $self->_Input;
}
elsif ($self->type =~ /radio|checkbox/i) {
$tag = $self->_RadioCheckbox;
}
elsif ($self->type =~ /select/i) {
$tag = $self->_Select;
}
elsif ($self->type =~ /textarea/i) {
$tag = $self->_Textarea;
}
}
sub _Input {
my $self = shift;
return sprintf qq|%s<input name="%s" type="%s" value="%s" %s>%s|,(
$self->tag_left_in,
$self->name,$self->type,$self->value,$self->tag_attr,
$self->tag_right_in,
);
}
sub _Select {
my $self = shift;
my $start = sprintf qq|%s<select name="%s" %s>|,
$self->tag_left_in,$self->name,$self->tag_attr;
my $end = sprintf qq|</select>%s|,$self->tag_right_in;
my $option;
return unless ref $self->value eq 'ARRAY';
for my $val (@{$self->value}) {
my $selected = $self->is_selected($val) ? 'selected': '';
$option .= sprintf qq|<option value="%s" %s %s>%s</option>|,
$val,$self->tag_attr,$selected,$self->gen_tag_val_label($val);
}
return join "\n",($start,$option,$end,);
}
sub _RadioCheckbox {
my $self = shift;
my $tag;
return unless ref $self->value eq 'ARRAY';
for my $val (@{$self->value}) {
my $checked = $self->is_checked($val) ? 'checked': '';
$tag .= sprintf
qq|%s<input name="%s" type="%s" value="%s" %s %s>%s%s|,(
$self->tag_left_in,
$self->name,$self->type,$val,$self->tag_attr,
$checked,$self->gen_tag_val_label($val),
$self->tag_right_in,
);
}
return $tag;
}
sub _Textarea {
my $self = shift;
return sprintf qq|%s<textarea name="%s" %s>%s</textarea>%s|,(
$self->tag_left_in,
$self->name,$self->tag_attr,$self->value,
$self->tag_right_in,
);
}
sub gen_tag_val_label {
my $self = shift;
my $key = shift;
my $label = $self->tag_val_label ne '' ? $self->tag_val_label : {};
return defined $label->{$key} ? $label->{$key} : $key;
}
1;
__END__