6e84888296e51a5deb508b6232f69a0c00c085cf
[perl/html-form-simple.git] / lib / HTML / Form / Simple.pm
1 package HTML::Form::Simple;
2
3 use strict;
4 use warnings;
5
6 use XML::Quote;
7
8 our $VERSION = '1.00';
9
10
11 sub new {
12         bless {}, $_[0];
13 }
14
15 sub quote {
16         my $self = shift;
17         return XML::Quote::xml_quote_min($_[0]);
18 }
19
20 sub tag {
21         my ($self, $tag, $attr) = @_;
22
23         # strip empty if it shouldn't be
24         defined $attr->{$_} and $attr->{$_} eq '' and delete $attr->{$_}
25                 for qw(id type class style);
26
27         my $return = '<' . $tag;
28
29         # add booleans
30         delete $attr->{$_} and $return .= ' '.$_
31                 for qw(disabled readonly);
32
33         $return .= sprintf ' %s="%s"', $_, $self->quote($attr->{$_})
34                 for sort grep { defined $attr->{$_} } keys %$attr;
35
36         return $return . '>';
37 }
38
39
40 sub start {
41         my ($self, $attr) = @_;
42
43         return $self->tag(form => $attr);
44 }
45
46 sub stop {
47         return '</form>';
48 }
49
50
51 sub submit {
52         my ($self, $value, $attr) = @_;
53
54         if (ref $value eq 'HASH') {
55                 $attr = $value;
56         }
57         else {
58                 $attr ||= {};
59                 $attr->{value} = $value;
60         }
61
62         $attr->{type} = 'submit' unless defined $attr->{type};
63
64         return $self->tag(input => $attr);
65 }
66
67 sub hidden {
68         my ($self, $name, $value) = @_;
69
70         #TODO: $attr
71
72         return $self->tag(input => {type => 'hidden', name => $name, value => $value});
73 }
74
75 sub input {
76         my ($self, $name, $value, $attr) = @_;
77
78         if (ref $name eq 'HASH') {
79                 # only attributes provided (first argument)
80                 $attr = $name;
81         }
82         elsif (ref $value eq 'HASH') {
83                 # name shorthand (attributes in value parameter)
84                 $attr = $value;
85                 $attr->{name} = $name;
86         }
87         else {
88                 # name and value shorthands (all vars keep their assigned values)
89                 $attr ||= {};
90                 $attr->{name} = $name;
91                 $attr->{value} = $value;
92         }
93
94         $attr->{id}   = $attr->{name} unless defined $attr->{id};
95         $attr->{type} = 'text' unless defined $attr->{type} or defined $attr->{rows};
96         $value = delete $attr->{value} if defined $attr->{rows};
97
98         return defined $attr->{rows} ? sprintf(
99                 '%s%s</textarea>',
100                 $self->tag(textarea => $attr),
101                 $self->quote(defined $value ? $value : '')
102         ) : $self->tag(input => $attr);
103 }
104
105 sub select {
106         my ($self, $name, $rows, $value, $attr) = @_;
107
108         if (ref $value eq 'HASH') {
109                 $attr = $value;
110         }
111         else {
112                 $attr ||= {};
113         }
114         $attr->{name} = $name;
115
116         return $self->tag(select => $attr) . join('',
117                 map { $self->tag(option => (ref $_ ? $_ : {value => $_})) } @$rows
118         ) . '</select>';
119 }
120
121 1;
122
123 =head1 NAME
124
125 HTML::Form::Simple
126
127 =head1 SYNOPSIS
128
129         my $input = HTML::Form::Simple->new;
130         say $input->start; # <form>
131         printf "<label>%s: %s</label>\n", @$_ for (
132                 [ 'Your Name' => $input->text(
133                         user => 'Mr. Default'
134                 ) ],
135                 [ Message => $input->text(
136                         msg => 'Textarea default', {rows => 4, style => 'background:red'}
137                 ) ],
138                 [ Colour => $input->select(
139                         favcolour => [qw(Blue Green Red)], 'Green'
140                 ) ],
141         );
142         say $input->stop; # </form>
143