4 CXGN::Page::Form::Editable.pm -- classes to deal with user-modifiable web forms
8 This is a subclass of L<CXGN::Page::Form::Static>, and overrides the functions therein to generate editable components in the form. For more information, see L<CXGN::Page::Form::Static>.
12 Lukas Mueller (lam87@cornell.edu)
18 use CXGN
::Page
::Form
::Static
;
19 use CXGN
::Page
::Form
::EditableField
;
20 use CXGN
::Page
::Form
::EditableSelect
;
21 use CXGN
::Page
::Form
::EditableHidden
;
22 use CXGN
::Page
::Form
::EditableTextArea
;
23 use CXGN
::Page
::Form
::EditableCheckbox
;
24 use CXGN
::Page
::Form
::EditablePasswordField
;
25 use CXGN
::Page
::Form
::EditableRadioList
;
26 use CXGN
::Page
::Form
::EditableMultiSelect
;
28 package CXGN
::Page
::Form
::Editable
;
30 use base qw
/ CXGN::Page::Form::Static /;
34 my $self = $class->SUPER::new
(@_);
36 $self->set_form_id($args->{form_id
}); #optional. Set a form id. Required for javasctipt forms
37 $self->set_no_buttons($args->{no_buttons
}); #optional. Used in javascript forms, which should generate their own 'store' and 'reset form' buttons.
38 $self->set_reset_button_text("Reset form");
39 $self->set_submit_button_text("Store");
40 $self->set_submit_method(); #use hardcoded default
47 Whether the form can be filled in.
55 =head2 propagate_input
70 my %distinct_objects = ();
71 # propagate the input to the form object
74 foreach my $f ($self->get_fields()) {
75 my $setter = $f->get_object_setter();
77 #print STDERR "FUNCTION: " .$setter." field contents: ".($args{$f->get_field_name()})." field name: ".$f->get_field_name()." getter: ".$f->get_object_getter()." setter: ".$f->get_object_setter()."\n";
81 if($f->is_store_enabled())
83 $f->get_object()->$setter($args{$f->get_field_name()});
85 $f->set_store_enabled(1); #must be re-disabled at each visit to the form
86 my $object = $f->get_object();
87 my $object_type = ref($object);
88 $distinct_objects{$object_type}=$f->get_object(); #can only have one object of a given type associated with a given form
91 $self->set_distinct_objects(%distinct_objects);
95 =head2 get_distinct_objects
98 Desc: stores a hash of distinct objects in the form
99 which will be used to call store on.
100 The hash keys are object types and the values are
109 sub get_distinct_objects
{
111 return %{$self->{distinct_objects
}};
114 =head2 set_distinct_objects
125 sub set_distinct_objects
{
127 my %distinct_objects = @_;
128 %{$self->{distinct_objects
}}=%distinct_objects;
146 # $self->propagate_input(%args); #think this is unnecessary, and leaving it in would mess up SimpleFormPage::validate_parameters_before_store() -- Evan, 1 / 15 / 07
148 foreach my $f ($self->get_fields()) {
149 my $error = $f->validate();
150 #print STDERR "validate ".$f->get_field_name()." - error $error\n";
152 $error_hash{$f->get_field_name()}=$error;
155 $self->set_error_hash(%error_hash);
174 $self->propagate_input(%args);
178 # commit the changes to the database using the store method on
181 #print STDERR "STORING OBJECT...\n";
183 my %distinct_objects = $self->get_distinct_objects();
186 # check the uniqueness constraints of the object
188 foreach my $k (keys(%distinct_objects)) {
189 my $obj = $distinct_objects{$k};
190 if ($obj->can("exists_in_database")) {
191 my $message = $obj->exists_in_database; #message is optional
193 my $text = "This object (" . ref($distinct_objects{$k}) . ") already seems to exist in the database and violates constraints. Please correct your input.\n";
194 $message = "" unless ($message =~ /[a-zA-Z]/);
195 CXGN
::Page
->new()->message_page($text, $message);
199 foreach my $k (keys %distinct_objects) {
200 #print STDERR " DUMP:" .Data::Dumper::Dumper($distinct_objects{$k});
201 #print STDERR " STORING OBJECT: ".ref($distinct_objects{$k})."\n";
203 my $id = $distinct_objects{$k}->store();
204 $self->set_insert_id($k, $id);
213 Args: a hash with the following keys:
223 required fields: field_name.
233 my $field = CXGN
::Page
::Form
::EditableField
->new(%args);
234 if(exists $args{validate
})
236 $field->set_validate($args{validate
});
238 if (!exists($self->{fields
})) { $self->{fields
}=(); }
239 push @
{$self->{fields
}}, $field;
242 =head2 add_password_field
247 Args: a hash with the following keys:
257 required fields: field_name.
263 sub add_password_field
{
267 my $field = CXGN
::Page
::Form
::EditablePasswordField
->new(%args);
268 if(exists $args{validate
})
270 $field->set_validate($args{validate
});
272 if (!exists($self->{fields
})) { $self->{fields
}=(); }
273 push @
{$self->{fields
}}, $field;
276 =head2 function add_textarea
279 Arguments: a hash with the following keys:
289 required fields: field_name.
299 my $field = CXGN
::Page
::Form
::EditableTextArea
->new(%args);
300 if(exists $args{validate
})
302 $field->set_validate($args{validate
});
304 $self->add_field_obj($field);
333 #foreach my $k (keys %args) { print "Args to add_select $k, $args{$k}\n<br />"; }
334 my $select = CXGN
::Page
::Form
::EditableSelect
->new(%args);
335 if(exists $args{validate
})
337 $select->set_validate($args{validate
});
339 if (!exists($self->{fields
})) { $self->{fields
}=(); }
340 push @
{$self->{fields
}}, $select;
358 my $hidden = CXGN
::Page
::Form
::EditableHidden
->new(%args);
359 if(exists $args{validate
})
361 $hidden->set_validate($args{validate
});
363 $self->add_field_obj($hidden);
382 my $checkbox = CXGN
::Page
::Form
::EditableCheckbox
->new(%args);
383 $self->add_field_obj($checkbox);
386 =head2 add_radio_list
402 my $radio = CXGN
::Page
::Form
::EditableRadioList
->new(%args);
403 $self->add_field_obj($radio);
406 =head2 add_multiselect
422 my $radio = CXGN
::Page
::Form
::EditableMultiSelect
->new(%args);
423 $self->add_field_obj($radio);
429 return "<form id =\"" . $self->get_form_id() . "\" method=\"" . $self->get_submit_method() . "\" action=\"\">"; #must have action parameter for xhtml 1.0+ -- Evan, 1/7/07
434 return undef if $self->get_no_buttons();
435 return "<input type=\"submit\" value=\"" . $self->get_submit_button_text() . "\" />
436 <input type=\"reset\" value=\"" . $self->get_reset_button_text() . "\" />
440 =head2 get_submit_method
446 sub get_submit_method
449 return $self->{form_submit_method
};
452 =head2 set_submit_method
454 'get' or 'post' (case doesn't matter)
456 default is 'get' if no or invalid argument
460 sub set_submit_method
462 my ($self, $method) = @_;
463 $method = 'get' if(!defined($method) or $method !~ /^get|post$/i);
464 $self->{form_submit_method
} = lc($method); #lowercase
467 sub get_reset_button_text
470 return $self->{reset_button_text
};
473 =head2 set_reset_button_text
475 Args: new button text (default is 'reset form')
477 [1 / 9 / 07] Not currently possible to remove the reset button.
481 sub set_reset_button_text
483 my ($self, $text) = @_;
484 $self->{reset_button_text
} = $text;
487 sub get_submit_button_text
490 return $self->{submit_button_text
};
493 =head2 set_submit_button_text
495 Args: new button text (default is 'store')
499 sub set_submit_button_text
501 my ($self, $text) = @_;
502 $self->{submit_button_text
} = $text;
505 =head2 as_table_string
511 Note: as table does not call validate itself to give some
512 more control on the appearance (you don't want the
513 new input field to appear with error messages).
519 sub as_table_string
{
523 my %error_hash = $self->get_error_hash();
525 my %html = $self->get_field_hash();
527 my $has_required_field=0;
528 $string .= $self->get_form_start();
529 $string .= qq { <table
> };
530 foreach my $f ($self->get_fields()) {
532 if (exists($error_hash{$f->get_field_name()})) {
533 $error=$self->get_error_message($error_hash{$f->get_field_name()})."<br />";
536 my $required_field = "";
537 if ($f->get_validate()) {
538 $required_field = qq { <font color
="red">*</font
> };
539 $has_required_field=1;
542 # print everything except the hidden fields
544 if (ref($f)!~/hidden/i) {
545 $string .= "<tr><td>$error".($f->get_display_name())."$required_field</td><td width=\"20\"> </td><td>".($html{$f->get_field_name()})."</td></tr>\n";
550 $string .= qq { <tr
><td colspan
="3" align
="center"> };
552 # print the hidden fields
554 foreach my $f ($self->get_fields()) {
555 if (ref($f)=~/hidden/i) {
556 $string .= $html{$f->get_field_name()};
559 if ($has_required_field) {
560 $string .= qq { (<font color
="red">*</font> denotes required field.)<br /><br
/> };
562 $string .= qq { </td></tr
></table
> };
563 $string .= $self->get_form_end();