mirror of
https://github.com/webmin/webmin.git
synced 2025-07-23 00:30:33 +00:00
406 lines
7.9 KiB
Perl
406 lines
7.9 KiB
Perl
package Webmin::Form;
|
|
use WebminCore;
|
|
|
|
=head2 new Webmin::Form(cgi, [method])
|
|
Creates a new form, which submits to the given CGI
|
|
=cut
|
|
sub new
|
|
{
|
|
if (defined(&Webmin::Theme::Form::new)) {
|
|
return new Webmin::Theme::Form(@_[1..$#_]);
|
|
}
|
|
my ($self, $program, $method) = @_;
|
|
$self = { 'method' => 'get',
|
|
'name' => "form".++$form_count };
|
|
bless($self);
|
|
$self->set_program($program);
|
|
$self->set_method($method) if ($method);
|
|
return $self;
|
|
}
|
|
|
|
=head2 html()
|
|
Returns the HTML that makes up this form
|
|
=cut
|
|
sub html
|
|
{
|
|
my ($self) = @_;
|
|
my $rv;
|
|
if ($self->get_align()) {
|
|
$rv .= "<div align=".$self->get_align().">\n";
|
|
}
|
|
$rv .= $self->form_start();
|
|
if ($self->get_heading()) {
|
|
if (defined(&ui_subheading)) {
|
|
$rv .= &ui_subheading($self->get_heading());
|
|
}
|
|
else {
|
|
$rv .= "<h3>".$self->get_heading()."</h3>\n";
|
|
}
|
|
}
|
|
|
|
# Add the sections
|
|
foreach my $h (@{$self->{'hiddens'}}) {
|
|
$rv .= &ui_hidden($h->[0], $h->[1])."\n";
|
|
}
|
|
foreach my $s (@{$self->{'sections'}}) {
|
|
$rv .= $s->html();
|
|
}
|
|
|
|
# Check if we have any inputs that need disabling
|
|
my @dis = $self->list_disable_inputs();
|
|
if (@dis) {
|
|
# Yes .. generate a function for them
|
|
$rv .= "<script>\n";
|
|
$rv .= "function ui_disable_".$self->{'name'}."(form) {\n";
|
|
foreach my $i (@dis) {
|
|
foreach my $n ($i->get_input_names()) {
|
|
$rv .= " form.".$n.".disabled = (".
|
|
$i->get_disable_code().");\n";
|
|
}
|
|
}
|
|
$rv .= "}\n";
|
|
$rv .= "</script>\n";
|
|
}
|
|
|
|
# Add the buttons at the end of the form
|
|
my @buttonargs;
|
|
foreach my $b (@{$self->{'buttons'}}) {
|
|
if (ref($b)) {
|
|
# An array of inputs
|
|
my $ihtml = join(" ", map { $_->html() } @$b);
|
|
push(@buttonargs, $ihtml);
|
|
}
|
|
else {
|
|
# A spacer
|
|
push(@buttonargs, "");
|
|
}
|
|
}
|
|
$rv .= &ui_form_end(\@buttonargs);
|
|
|
|
if ($self->get_align()) {
|
|
$rv .= "</div>\n";
|
|
}
|
|
|
|
# Call the Javascript disable function
|
|
if (@dis) {
|
|
$rv .= "<script>\n";
|
|
$rv .= "ui_disable_".$self->{'name'}."(window.document.forms[\"$self->{'name'}\"]);\n";
|
|
$rv .= "</script>\n";
|
|
}
|
|
|
|
return $rv;
|
|
}
|
|
|
|
sub form_start
|
|
{
|
|
my ($self) = @_;
|
|
return "<form action='$self->{'program'}' ".
|
|
($self->{'method'} eq "post" ? "method=post" :
|
|
$self->{'method'} eq "form-data" ?
|
|
"method=post enctype=multipart/form-data" :
|
|
"method=get")." name=$self->{'name'}>\n";
|
|
}
|
|
|
|
=head2 add_section(section)
|
|
Adds a Webmin::Section object to this form
|
|
=cut
|
|
sub add_section
|
|
{
|
|
my ($self, $section) = @_;
|
|
push(@{$self->{'sections'}}, $section);
|
|
$section->set_form($self);
|
|
}
|
|
|
|
=head2 get_section(idx)
|
|
=cut
|
|
sub get_section
|
|
{
|
|
my ($self, $idx) = @_;
|
|
return $self->{'sections'}->[$idx];
|
|
}
|
|
|
|
=head2 add_button(button, [beside, ...])
|
|
Adds a Webmin::Submit object to this form, for display at the bottom
|
|
=cut
|
|
sub add_button
|
|
{
|
|
my ($self, $button, @beside) = @_;
|
|
push(@{$self->{'buttons'}}, [ $button, @beside ]);
|
|
}
|
|
|
|
=head2 add_button_spacer()
|
|
Adds a gap between buttons, for grouping
|
|
=cut
|
|
sub add_button_spacer
|
|
{
|
|
my ($self, $spacer) = @_;
|
|
push(@{$self->{'buttons'}}, $spacer);
|
|
}
|
|
|
|
=head2 add_hidden(name, value)
|
|
Adds some hidden input to this form, for passing to the CGI
|
|
=cut
|
|
sub add_hidden
|
|
{
|
|
my ($self, $name, $value) = @_;
|
|
push(@{$self->{'hiddens'}}, [ $name, $value ]);
|
|
}
|
|
|
|
=head2 validate()
|
|
Validates all form inputs, based on the current CGI input hash. Returns a list
|
|
of errors, each of which is field name and error message.
|
|
=cut
|
|
sub validate
|
|
{
|
|
my ($self) = @_;
|
|
my @errs;
|
|
foreach my $s (@{$self->{'sections'}}) {
|
|
push(@errs, $s->validate($self->{'in'}));
|
|
}
|
|
return @errs;
|
|
}
|
|
|
|
=head2 validate_redirect(page, [&extra-errors])
|
|
Validates the form, and if any errors are found re-directs to the given page
|
|
with the errors, so that they can be displayed.
|
|
=cut
|
|
sub validate_redirect
|
|
{
|
|
my ($self, $page, $extras) = @_;
|
|
if ($self->{'in'}->{'ui_redirecting'}) {
|
|
# If this page is displayed as part of a redirect, no need to validate!
|
|
return;
|
|
}
|
|
my @errs = $self->validate();
|
|
push(@errs, @$extras);
|
|
if (@errs) {
|
|
my (@errlist, @vallist);
|
|
foreach my $e (@errs) {
|
|
push(@errlist, &urlize("ui_error_".$e->[0])."=".
|
|
&urlize($e->[1]));
|
|
}
|
|
foreach my $i ($self->list_inputs()) {
|
|
my $v = $i->get_value();
|
|
my @vals = ref($v) ? @$v : ( $v );
|
|
@vals = ( undef ) if (!@vals);
|
|
foreach $v (@vals) {
|
|
push(@vallist,
|
|
&urlize("ui_value_".$i->get_name())."=".
|
|
&urlize($v));
|
|
}
|
|
}
|
|
foreach my $h (@{$self->{'hiddens'}}) {
|
|
push(@vallist,
|
|
&urlize($h->[0])."=".&urlize($h->[1]));
|
|
}
|
|
if ($page =~ /\?/) { $page .= "&"; }
|
|
else { $page .= "?"; }
|
|
&redirect($page.join("&", "ui_redirecting=1", @errlist, @vallist));
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
=head2 validate_error(whatfailed)
|
|
Validates the form, and if any errors are found displays an error page.
|
|
=cut
|
|
sub validate_error
|
|
{
|
|
my ($self, $whatfailed) = @_;
|
|
my @errs = $self->validate();
|
|
&error_setup($whatfailed);
|
|
if (@errs == 1) {
|
|
&error($errs[0]->[2] ? "$errs[0]->[2] : $errs[0]->[1]"
|
|
: $errs[0]->[1]);
|
|
}
|
|
elsif (@errs > 1) {
|
|
my $msg = $text{'ui_errors'}."<br>";
|
|
foreach my $e (@errs) {
|
|
$msg .= $e->[2] ? "$e->[2] : $e->[1]<br>\n"
|
|
: "$e->[1]<br>\n";
|
|
}
|
|
&error($msg);
|
|
}
|
|
}
|
|
|
|
=head2 field_errors(name)
|
|
Returns a list of error messages associated with the field of some name, from
|
|
the input passed to set_input
|
|
=cut
|
|
sub field_errors
|
|
{
|
|
my ($self, $name) = @_;
|
|
my @errs;
|
|
my $in = $self->{'in'};
|
|
foreach my $i (keys %$in) {
|
|
if ($i eq "ui_error_".$name) {
|
|
push(@errs, split(/\0/, $in->{$i}));
|
|
}
|
|
}
|
|
return @errs;
|
|
}
|
|
|
|
=head2 set_input(&input)
|
|
Passes the form input hash to this form object, for use by the validate
|
|
functions and for displaying errors next to fields.
|
|
=cut
|
|
sub set_input
|
|
{
|
|
my ($self, $in) = @_;
|
|
$self->{'in'} = $in;
|
|
}
|
|
|
|
=head2 get_value(input-name)
|
|
Returns the value of the input with the given name.
|
|
=cut
|
|
sub get_value
|
|
{
|
|
my ($self, $name) = @_;
|
|
foreach my $s (@{$self->{'sections'}}) {
|
|
my $rv = $s->get_value($name);
|
|
return $rv if (defined($rv));
|
|
}
|
|
return $self->{'in'}->{$name};
|
|
}
|
|
|
|
=head2 get_input(name)
|
|
Returns the input with the given name
|
|
=cut
|
|
sub get_input
|
|
{
|
|
my ($self, $name) = @_;
|
|
foreach my $i ($self->list_inputs()) {
|
|
return $i if ($i->get_name() eq $name);
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
sub set_program
|
|
{
|
|
my ($self, $program) = @_;
|
|
$self->{'program'} = $program;
|
|
}
|
|
|
|
sub set_method
|
|
{
|
|
my ($self, $method) = @_;
|
|
$self->{'method'} = $method;
|
|
}
|
|
|
|
=head2 list_inputs()
|
|
Returns all inputs in all form sections
|
|
=cut
|
|
sub list_inputs
|
|
{
|
|
my ($self) = @_;
|
|
my @rv;
|
|
foreach my $s (@{$self->{'sections'}}) {
|
|
push(@rv, $s->list_inputs());
|
|
}
|
|
return @rv;
|
|
}
|
|
|
|
=head2 list_disable_inputs()
|
|
Returns a list of inputs that have disable functions
|
|
=cut
|
|
sub list_disable_inputs
|
|
{
|
|
my ($self) = @_;
|
|
my @dis;
|
|
foreach my $i ($self->list_inputs()) {
|
|
push(@dis, $i) if ($i->get_disable_code());
|
|
}
|
|
return @dis;
|
|
}
|
|
|
|
=head2 set_page(Webmin::Page)
|
|
Called when this form is added to a page
|
|
=cut
|
|
sub set_page
|
|
{
|
|
my ($self, $page) = @_;
|
|
$self->{'page'} = $page;
|
|
}
|
|
|
|
=head2 get_changefunc(&input)
|
|
Called by some input, to return the Javascript that should be called when this
|
|
input changes it's value.
|
|
=cut
|
|
sub get_changefunc
|
|
{
|
|
my ($self, $input) = @_;
|
|
my @dis = $self->list_disable_inputs();
|
|
if (@dis) {
|
|
return "ui_disable_".$self->{'name'}."(form)";
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
=head2 set_heading(text)
|
|
Sets the heading to be displayed above the form
|
|
=cut
|
|
sub set_heading
|
|
{
|
|
my ($self, $heading) = @_;
|
|
$self->{'heading'} = $heading;
|
|
}
|
|
|
|
sub get_heading
|
|
{
|
|
my ($self) = @_;
|
|
return $self->{'heading'};
|
|
}
|
|
|
|
=head2 get_formno()
|
|
Returns the index of this form on the page
|
|
=cut
|
|
sub get_formno
|
|
{
|
|
my ($self) = @_;
|
|
my $n = 0;
|
|
foreach my $f (@{$self->{'page'}->{'contents'}}) {
|
|
if ($f eq $self) {
|
|
return $n;
|
|
}
|
|
elsif (ref($f) =~ /Form/) {
|
|
$n++;
|
|
}
|
|
}
|
|
return undef;
|
|
}
|
|
|
|
=head2 add_onload(code)
|
|
Adds some Javascript code for inclusion in the onLoad tag
|
|
=cut
|
|
sub add_onload
|
|
{
|
|
my ($self, $code) = @_;
|
|
push(@{$self->{'onloads'}}, $code);
|
|
}
|
|
|
|
=head2 add_script(code)
|
|
Adds some Javascript code for putting in the <head> section
|
|
=cut
|
|
sub add_script
|
|
{
|
|
my ($self, $script) = @_;
|
|
push(@{$self->{'scripts'}}, $script);
|
|
}
|
|
|
|
=head2 set_align(align)
|
|
Sets the alignment on the page (left, center, right)
|
|
=cut
|
|
sub set_align
|
|
{
|
|
my ($self, $align) = @_;
|
|
$self->{'align'} = $align;
|
|
}
|
|
|
|
sub get_align
|
|
{
|
|
my ($self) = @_;
|
|
return $self->{'align'};
|
|
}
|
|
|
|
1;
|
|
|