added sol100 and chado cvterm pages to validate_all.t
[sgn.git] / lib / CXGN / Page / Form / Static.pm
blob7937b17a7af4808b269e31fee2109a1d9e6542fd
2 =head1 NAME
4 CXGN::Form.pm -- classes to deal with user-modifiable web forms
6 =head1 DESCRIPTION
8 This class implements a "static" - or non-editable version - of a web form. This is used to display the information to users who have no edit privileges.
10 The counterpart to this class is L<CXGN::Page::Form::Editable>, which implements the editable version.
12 Both Editable and Static implement the same interface (which is not yet formally defined, TO DO!).
14 =head1 AUTHOR(S)
16 Lukas Mueller (lam87@cornell.edu)
18 =cut
21 use strict;
23 package CXGN::Page::Form::Static;
25 use Data::Dumper;
26 use CXGN::Page::Form::Field;
27 use CXGN::Page::Form::Select;
28 use CXGN::Page::Form::Hidden;
29 use CXGN::Page::Form::Label;
30 use CXGN::Page::Form::TextArea;
31 use CXGN::Page::Form::Checkbox;
32 use CXGN::Page::Form::PasswordField;
33 use CXGN::Page::Form::RadioList;
34 use CXGN::Page::Form::MultiSelect;
36 =head2 new
38 Usage: $form = CXGN::Page::Form::Static->new($args_ref);
39 Desc: constructor of a form object
40 Args: a hashref with the optional fields:
41 form_id: the id of the form (required for forms
42 that work with javascript)
43 (See jslib/CXGN/Page/Form/JSFormPage.js)
44 Side Effects:
45 Example:
47 =cut
49 sub new {
50 my $class = shift;
51 my $args = shift;
53 my $self = bless {}, $class;
54 $self->set_form_id($args->{form_id});
55 return $self;
58 =head2 is_editable
60 Whether the form can be filled in.
62 =cut
64 sub is_editable
66 return 0;
69 =head2 add_field_obj
71 Usage:
72 Desc: adds a field object to the form object. A field
73 object can be anything that inherits from
74 CXGN::Page::Form::ElementI.
75 Ret:
76 Args:
77 Side Effects: the field will be added to the form object. It will
78 be rendered in the order it was added to the object
79 when the function as_table is used.
80 It will also be returned with the function
81 get_field_hash().
82 Example:
84 =cut
86 sub add_field_obj {
87 my $self = shift;
88 my $field = shift;
89 if (!exists($self->{fields})) { $self->{fields}=(); }
90 push @{$self->{fields}}, $field;
93 =head2 get_field_obj_by_name
95 Args: a string that was used as the 'field_name' parameter for some field
96 Ret: a field object with the given name, or undef if none exists
98 =cut
100 sub get_field_obj_by_name
102 my ($self, $name) = @_;
103 return undef unless exists($self->{fields});
104 foreach my $obj (@{$self->{fields}})
106 return $obj if $obj->get_field_name() eq $name;
108 return undef;
111 =head2 add_field
113 Usage:
114 Desc:
115 Ret:
116 Args: display name, form name, content, length [int],
117 object, getter, setter, set_if, validate, formatting
118 Side Effects:
119 Example:
121 =cut
123 sub add_field {
124 my $self = shift;
125 my %args = @_;
126 my $field = CXGN::Page::Form::Field->new(%args);
127 $self->add_field_obj($field);
130 =head2 add_password_field
132 Usage:
133 Desc:
134 Ret:
135 Args: display name, form name, content, length [int],
136 object, getter, setter, set_if
137 Side Effects:
138 Example:
140 =cut
142 sub add_password_field {
143 my $self = shift;
144 my %args = @_;
145 my $field = CXGN::Page::Form::PasswordField->new(%args);
146 $self->add_field_obj($field);
149 =head2 function add_textarea
151 Usage:
152 Desc:
153 Ret:
154 Args:
155 Side Effects:
156 Example:
158 =cut
160 sub add_textarea {
161 my $self = shift;
162 my %args = @_;
163 my $field = CXGN::Page::Form::TextArea->new(%args);
164 $self->add_field_obj($field);
168 =head2 add_label
170 Usage:
171 Desc: Adds a static label that will always be rendered
172 just as a string.
173 Ret:
174 Args: hash with keys field_name and contents
175 Side Effects: will be rendered on form in as_table function, for example.
176 Example:
178 =cut
180 sub add_label {
181 my $self = shift;
182 my %args = @_;
184 my $label = CXGN::Page::Form::Label->new(%args);
186 $self->add_field_obj($label);
189 =head2 add_select
191 Usage:
192 Desc:
193 Ret:
194 Args: display name, form name, content, length [int],
195 object, getter, setter, select_list_ref, select_id_list_ref
196 Side Effects:
197 Description: select_list_ref is a reference to a list containing the names
198 of the options in the pull down menu, select_id_list_ref contains
199 the corresponding ids for each option.
201 =cut
204 sub add_select {
205 my $self = shift;
206 my %args = @_;
208 my $select = CXGN::Page::Form::Select->new(%args);
209 $self->add_field_obj($select);
213 =head2 add_hidden
215 Usage:
216 Desc: adds a hidden field to the form
217 Ret:
218 Args: anonymous hash with field names:
219 display name, form name, contents, length [int],
220 object, getter, setter
221 Side Effects:
222 Example:
224 =cut
226 sub add_hidden {
227 my $self = shift;
228 my %args = @_;
230 my $hidden = CXGN::Page::Form::Hidden->new(%args);
231 $self->add_field_obj($hidden);
234 =head2 add_checkbox
236 Usage:
237 Desc: adds a checkbox to the form
238 Ret:
239 Args: anonymous hash with field names:
240 display name, form name, contents, selected, object, getter, setter.
241 Side Effects:
242 Example:
244 =cut
246 sub add_checkbox {
247 my $self = shift;
248 my %args = @_;
250 my $checkbox = CXGN::Page::Form::Checkbox->new(%args);
251 $self->add_field_obj($checkbox);
254 =head2 add_radio_list
256 Usage:
257 Desc: adds a matched set of radio buttons to the form, in the color of your choice
258 Ret:
259 Args: anonymous hash with field names:
260 display name, form name, choices, labels, contents, object, getter, setter.
261 Side Effects:
262 Example:
264 =cut
266 sub add_radio_list
268 my $self = shift;
269 my %args = @_;
271 my $radio = CXGN::Page::Form::RadioList->new(%args);
272 $self->add_field_obj($radio);
275 =head2 add_multiselect
277 Usage:
278 Desc: adds a select box with multiple selections allowed to the form
279 Ret:
280 Args: anonymous hash with field names:
281 display name, form name, choices, labels, contents, object, getter, setter.
282 Side Effects:
283 Example:
285 =cut
287 sub add_multiselect
289 my $self = shift;
290 my %args = @_;
292 my $radio = CXGN::Page::Form::MultiSelect->new(%args);
293 $self->add_field_obj($radio);
296 =head2 set_action
298 Usage: $form->set_action("/cgi-bin/myscript.pl")
299 Desc: sets the action parameter in the form.
300 Ret: nothing
301 Args: a name of a script the form should call.
302 Side Effects:
303 Example:
305 =cut
307 sub set_action {
308 my $self = shift;
309 $self->{action}=shift;
312 =head2 get_action
314 Usage:
315 Desc:
316 Ret:
317 Args:
318 Side Effects:
319 Example:
321 =cut
323 sub get_action {
324 my $self = shift;
325 if (!exists($self->{action})) { $self->{action}=""; }
326 return $self->{action};
329 =head2 get_fields
331 Usage:
332 Desc:
333 Ret: returns all the fields of the form, in the
334 order they were added to the list (and in the
335 order they are rendered with as_table().
336 Args:
337 Side Effects:
338 Example:
340 =cut
342 sub get_fields {
343 my $self = shift;
344 if (!exists($self->{fields})) { @{$self->{fields}}=(); }
345 return @{$self->{fields}};
348 =head2 get_form_start
350 Usage:
351 Desc:
352 Ret:
353 Args:
354 Side Effects:
355 Example:
357 =cut
360 sub get_form_start {
361 my $self = shift;
362 return "";
365 =head2 get_form_end
367 Usage:
368 Desc: gets the ending definition of the
369 form.
370 Ret: a string representing the end of the form.
371 Args:
372 Side Effects:
373 Example:
375 =cut
377 sub get_form_end {
378 my $self = shift;
379 return "";
382 =head2 get_field_hash
384 Usage:
385 Desc: Returns a hash with the field names as keys
386 and the representation of the fields as values.
387 For 'static' fields, usually the field contents
388 are given, and for 'editable' fields, an input
389 box, drop down or other appropriate form element
390 is defined.
392 Two special hash keys are defined:
393 FORM_START can be used to render the start of the
394 form.
395 FORM_END can be used to render the end of the form.
396 Ret: a hash (see above)
397 Args: none
398 Side Effects: none
399 Example:
401 =cut
403 sub get_field_hash {
404 my $self = shift;
405 my %hash = ();
406 foreach my $f ($self->get_fields()) {
407 $hash{$f->get_field_name()} = $f->render();
409 $hash{FORM_START}=$self->get_form_start();
410 $hash{FORM_END} = $self->get_form_end();
412 return %hash;
416 =head2 get_error_hash
418 Usage:
419 Desc:
420 Ret:
421 Args:
422 Side Effects:
423 Example:
425 =cut
427 sub get_error_hash {
428 my $self=shift;
429 if (!exists($self->{error_hash})) { %{$self->{error_hash}} = (); }
430 return %{$self->{error_hash}};
434 =head2 set_error_hash
436 Usage:
437 Desc:
438 Ret:
439 Args:
440 Side Effects:
441 Example:
443 =cut
445 sub set_error_hash {
446 my $self=shift;
447 %{$self->{error_hash}}=@_;
451 =head2 validate
453 Usage:
454 Desc:
455 Ret:
456 Args:
457 Side Effects:
458 Example:
460 =cut
462 sub validate {
463 my $self = shift;
464 my %args = @_;
467 =head2 from_request
469 Usage: $form->from_request(%args)
470 Desc: populates the form contents from
471 the hash %args. The keys of the hash
472 must map to field names, and the values
473 of the hash will be the field contents.
474 Ret:
475 Args:
476 Side Effects:
477 Example:
479 =cut
481 sub from_request {
482 my $self = shift;
483 my %args = @_;
484 foreach my $f ($self->get_fields())
486 my $field_name = $f->get_field_name();
487 if (exists($args{$field_name}))
489 $f->set_from_external($args{$field_name});
494 =head2 from_database
496 Usage: $form->from_database()
497 Desc: populates the form from the database
498 using the getter functions and object references
499 from the field object.
500 Ret: nothing
501 Args:
502 Side Effects: object contents will be filled in as values
503 in the corresponding fields when form is
504 displayed.
505 Example:
507 =cut
509 sub from_database {
510 my $self = shift;
511 foreach my $f ($self->get_fields()) {
512 my $getter = $f->get_object_getter();
513 my $object = $f->get_object();
514 if ($object && $getter) {
515 my $contents = $object->$getter();
516 $f->set_from_external($contents);
521 =head2 fields_from_database
523 Usage: Be careful; this bypasses ElementI::set_from_external()
524 Desc:
525 Ret:
526 Args:
527 Side Effects:
528 Example:
530 =cut
532 sub get_fields_from_database {
533 my $self = shift;
534 my %fields=();
536 foreach my $f ($self->get_fields()) {
537 my $getter = $f->get_object_getter();
538 my $object = $f->get_object();
539 my $field_name = $f->get_field_name();
540 if ($object && $getter) {
541 my $contents = $object->$getter();
542 $fields{$field_name}=$contents;
545 return %fields;
551 =head2 as_table
553 Usage:
554 Desc:
555 Ret:
556 Args:
557 Side Effects:
558 Example:
560 =cut
562 sub as_table {
563 my $self = shift;
564 print $self->as_table_string();
567 =head2 as_table_string
569 Usage:
570 Desc:
571 Ret:
572 Args:
573 Side Effects:
574 Example:
576 =cut
578 sub as_table_string {
579 my $self = shift;
580 my $string = qq { <table> };
581 foreach my $f ($self->get_fields()) {
582 if (ref($f)!~/hidden/i) {
583 $string .= "<tr><td>".($f->get_display_name())."</td><td width=\"20\">&nbsp;</td><td><b>".($f->render())."</b></td></tr>\n";
586 $string .= qq { </table> };
587 return $string;
593 sub get_error_message {
594 my $self = shift;
595 my $error = shift;
596 print $CXGN::Page::Form::INPUT_REQUIRED_ERROR."\n";
598 if ($error == $CXGN::Page::Form::ElementI::INPUT_REQUIRED_ERROR) {
599 return qq { <font color="red">Input required</font>\n };
601 if ($error == $CXGN::Page::Form::ElementI::INTEGER_REQUIRED_ERROR) {
602 return qq { <font color="red">Integer required</font>\n };
604 if ($error == $CXGN::Page::Form::ElementI::NUMBER_REQUIRED_ERROR) {
605 return qq { <font color="red">Number required</font>\n };
607 if ($error == $CXGN::Page::Form::ElementI::TOKEN_REQUIRED_ERROR) {
608 return qq { <font color="red">Token required. No spaces or special characters are allowed.\n</font>\n };
610 if ($error == $CXGN::Page::Form::ElementI::LENGTH_EXCEEDED_ERROR) {
611 return qq { <font color="red">Field length limit exceeded.\n</font> };
613 if ($error == $CXGN::Page::Form::ElementI::DATE_REQUIRED_ERROR) {
614 return qq { <font color="red">Date required</font> };
616 if ($error == $CXGN::Page::Form::ElementI::UNIQUE_REQUIRED_ERROR) {
617 return qq { <font color="red">Unique input required</font> };
619 if ($error == $CXGN::Page::Form::ElementI::ALLELE_SYMBOL_REQUIRED_ERROR) {
620 return qq { <font color="red">Allele symbol required XXX-NN</font> };
622 if ($error) { return qq { <font color="red">Unknown error [$error]\n</font> }; }
626 =head2 store
628 Usage:
629 Desc:
630 Ret:
631 Args:
632 Side Effects:
633 Example:
635 =cut
637 sub store {
638 my $self = shift;
641 =head2 get_insert_id
643 Usage: my $id = $form->last_insert_id($myobject)
644 Desc:
645 Ret: the last insert id for the object in question
646 Args: an object that was supplied as part of a field
647 using the add_field or similar function
648 Side Effects:
649 Example: can be used to obtain the id of the database entity
650 when the store function is expected to yield an
651 insert into the database.
653 =cut
655 sub get_insert_id {
656 my $self=shift;
657 my $object = shift;
658 my $object_type = ref($object);
659 if (!exists($self->{insert_id}) || !exists($self->{insert_id}->{object_type})) {
662 else {
663 return $self->{insert_id}{object_type};
667 =head2 set_insert_id
669 Usage: $form->set_insert_id($myobject, $last_id);
670 Desc: used internally to set the last insert id for the
671 object "myobject"
672 Ret:
673 Args:
674 Side Effects:
675 Example:
677 =cut
679 sub set_insert_id {
680 my $self=shift;
681 my $object = shift;
682 my $object_type = ref($object);
683 $self->{insert_id}->{object_type}=shift;
686 =head2 get_template
688 Usage:
689 Desc:
690 Ret:
691 Args:
692 Side Effects:
693 Example:
695 =cut
697 sub get_template {
698 my $self=shift;
699 return $self->{template};
703 =head2 set_template
705 Usage:
706 Desc:
707 Ret:
708 Args:
709 Side Effects:
710 Example:
712 =cut
714 sub set_template {
715 my $self=shift;
716 $self->{template}=shift;
719 =head2 parse_template
721 Usage:
722 Desc:
723 Ret:
724 Args:
725 Side Effects:
726 Example:
728 =cut
730 sub parse_template {
731 my $self = shift;
733 foreach my $f ($self->get_fields()) {
739 =head2 accessors get_form_id, set_form_id
741 Usage:
742 Desc:
743 Property
744 Side Effects:
745 Example:
747 =cut
749 sub get_form_id {
750 my $self = shift;
751 return $self->{form_id};
754 sub set_form_id {
755 my $self = shift;
756 $self->{form_id} = shift;
760 =head2 accessors get_no_buttons, set_no_buttons
762 Usage:
763 Desc:
764 Property
765 Side Effects:
766 Example:
768 =cut
770 sub get_no_buttons {
771 my $self = shift;
772 return $self->{no_buttons};
775 sub set_no_buttons {
776 my $self = shift;
777 $self->{no_buttons} = shift;
780 return 1;