/[cvs]/nfo/php/libs/com.newsblob.phphtmllib/form/FormElement.inc
ViewVC logotype

Contents of /nfo/php/libs/com.newsblob.phphtmllib/form/FormElement.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Thu Aug 11 14:09:26 2005 UTC (18 years, 11 months ago) by jonen
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +278 -39 lines
+ updated to version 2.5.3

1 <?php
2 /**
3 * This file contains the base FormElement class.
4 *
5 * $Id: FormElement.inc,v 1.54.2.5 2005/05/12 01:24:02 hemna Exp $
6 *
7 * @author Walter A. Boring IV <waboring@newsblob.com>
8 * @author Suren Markosyan <suren@bcsweb.com>
9 * @package phpHtmlLib
10 * @subpackage FormProcessing
11 *
12 * @copyright LGPL - See LICENCE
13 *
14 */
15
16 /**
17 * This is the base FormElement object. It can be
18 * single form field such as a text input field,
19 * or a complex object.
20 *
21 * Usefull Functions
22 *
23 * get_value() - This gets the current
24 * 'value' of the FormElement.
25 * NOTE: This can be a 'complex' FormElement
26 * in which it may return an array of
27 * values.
28 *
29 * set_value() - Set the current value
30 * for this FormElement.
31 *
32 * get_label() - returns the label for this
33 * FormElement.
34 *
35 *
36 * @package phpHtmlLib
37 * @subpackage FormProcessing
38 */
39 class FormElement {
40
41 /**
42 * Holds the elements label text
43 *
44 */
45 var $_label_text = NULL;
46
47 /**
48 * Holds the elements initial value
49 *
50 */
51 var $_value = NULL;
52
53 /**
54 * Indicates whether this elements
55 * final value is required and cannot
56 * be empty
57 */
58 var $_is_required = TRUE;
59
60 /**
61 * holds the array of errors
62 * for this element.
63 */
64 var $_errors = array();
65
66 /**
67 * Holds the error message text
68 * for validation errors, if any
69 *
70 */
71 var $_error_message = NULL;
72
73 /**
74 * Holds the state of the last validation
75 * Sets to true in case of a validation error
76 *
77 */
78 var $_has_error = FALSE;
79
80 /**
81 * Holds the name of the element
82 * as it appears in the form html tag
83 *
84 */
85 var $_element_name = NULL;
86
87 /**
88 * Holds additional attributes for
89 * the elements html tag
90 *
91 */
92 var $_attributes;
93
94 /**
95 * Holds additional style attributes for
96 * the elements html tag
97 *
98 */
99 var $_style_attributes;
100
101 /**
102 * Indicates a disabled element
103 *
104 */
105 var $_is_disabled = FALSE;
106
107 /**
108 * Indicates this element is
109 * read only. The get_element()
110 * will return the get_value_text()
111 * instead of the form.
112 */
113 var $_is_readonly = FALSE;
114
115 /**
116 * Flag to tell us to enable
117 * validation or not
118 */
119 var $_validation_enabled = TRUE;
120
121 /**
122 * automatically strip slashes from
123 * form values?
124 */
125 var $_stripslashes = FALSE;
126
127
128 /**
129 * This holds the name of the form
130 * for js that needs it
131 */
132 var $_form_name;
133
134 /**
135 * This Form Element needs to
136 * propogate some js to the
137 * Form tag's onsubmit attribute
138 *
139 * @var string
140 */
141 var $_has_form_on_submit = false;
142
143 /**
144 * This holds an array of FormElement objects
145 * that are slaves of this element
146 */
147 var $_slave_elements;
148
149 /**
150 * The required field string
151 *
152 */
153 var $_required_field_marker = "*";
154
155 /**
156 * The form Element's flag to add the :
157 * character at the end of the label.
158 */
159 var $_label_colon_flag = FALSE;
160
161 /**
162 * variable to store JS onclick
163 */
164 var $onClickJS = NULL;
165
166 /**
167 * variable to store JS onclick
168 */
169 var $onFocusJS = NULL;
170
171 /**
172 * variable to store JS onclick
173 */
174 var $onChangeJS = NULL;
175
176 /**
177 * variable to store JS onclick
178 */
179 var $onSubmitJS = NULL;
180
181 /**
182 * variable to store JS onclick
183 */
184 var $onBlurJS = NULL;
185
186 /**
187 * The constructor
188 *
189 * @param label string - text label for the element
190 * @param bool required - is this a required element
191 */
192 function FormElement($label, $required = TRUE) {
193
194 $this->set_label_text($label);
195 $this->set_required($required);
196
197 // create a unique name to be used in the html form
198 $this->create_element_name();
199
200 //This sets the initial value of the element
201 $this->set_value( $this->get_init_value() );
202 }
203
204 /**
205 * This function will return the
206 * slaves of this element
207 *
208 * @return array of slave elements
209 */
210 function &get_slave_elements() {
211 return $this->_slave_elements;
212 }
213
214 /**
215 * This function will set the
216 * slaves of this element
217 *
218 * @param array of slave elements (element references &)
219 */
220 function set_slave_elements($slaveElements) {
221 $this->_slave_elements = $slaveElements;
222 $this->set_data_all_slaves( $this->get_value() );
223 }
224
225
226 /**
227 * This function will set the
228 * data the parent wants to set for the slave
229 *
230 * @param the slave
231 * @param the value being set for the parent
232 */
233 function set_slave_data(&$slave, $parentValue) {
234 ; //override to set the data for the slave
235 }
236
237 /**
238 * This function will return the
239 * elements label text
240 *
241 * @return string
242 */
243 function get_label_text() {
244 return $this->_label_text;
245 }
246
247 /**
248 * This function will set the
249 * label for the element
250 *
251 * @param label string
252 */
253 function set_label_text($label) {
254 $this->_label_text = $label;
255 }
256
257 /**
258 * This method sets the flag to have ALL of the
259 * FormElement's labels be appended with a :
260 * character. Some folks like this for some
261 * completely unexplained reason.
262 */
263 function set_colon_flag($flag=TRUE) {
264 $this->_label_colon_flag = $flag;
265 }
266
267 /**
268 * This function will return the
269 * elements value
270 *
271 * @return mixed
272 */
273 function get_value() {
274
275 if ($this->_stripslashes) {
276 if (is_array($this->_value)) {
277 return array_map('stripslashes', array_map('trim', $this->_value));
278 } else {
279 return stripslashes(trim($this->_value));
280 }
281 } else {
282 if (is_array($this->_value)) {
283 if (is_string($this->_value)) {
284 return array_map('trim', $this->_value);
285 } else {
286 return $this->_value;
287 }
288 } else {
289 if (is_string($this->_value)) {
290 return trim($this->_value);
291 } else {
292 return $this->_value;
293 }
294 }
295 }
296 }
297
298
299 /**
300 * This function will set the
301 * initial value for the element
302 *
303 * @param value mixed
304 */
305 function set_value($value) {
306 $this->_value = $value;
307 $this->set_data_all_slaves($value);
308 }
309
310 /**
311 * This function will call set_slave_data for all slaves
312 * should be called when value of parent changes
313 *
314 * @param string - the current value of parent
315 */
316 function set_data_all_slaves($parentValue){
317 $slaves = &$this->get_slave_elements();
318 $num_slaves = count($slaves);
319 if ($num_slaves) {
320 for($i=0; $i < $num_slaves; $i++){
321 $this->set_slave_data($slaves[$i], $parentValue);
322 }
323
324 }
325 }
326
327 /**
328 * in case anyone in JS land
329 * needs the name of the form that
330 * this element lives in
331 *
332 * @param string - the form name
333 */
334 function set_form_name($name) {
335 $this->_form_name = $name;
336 }
337
338 /**
339 * This provides a method
340 * for the FormContent
341 * to get access to the
342 * text associated with a
343 * field. This is only available
344 * on FormElements that have text
345 * associated with a field.
346 * It is used during Confirmation
347 *
348 * @param mixed the value to look up
349 * @return string - the text associated
350 */
351 function get_value_text() {
352 return $this->get_value();
353 }
354
355
356 /**
357 * This function set the elements
358 * required state
359 *
360 * @param bool required
361 */
362 function set_required($required) {
363 $this->_is_required = $required;
364 }
365
366 /**
367 * Returns whether this elements
368 * final value cannot be empty
369 *
370 * @return bool requried
371 */
372 function is_required() {
373 return $this->_is_required;
374 }
375
376
377 /**
378 * This returns the initial value of
379 * the element
380 *
381 * @return mixed
382 */
383 function get_init_value() {
384 return @$_REQUEST[str_replace("[]","",$this->get_element_name())];
385 }
386
387
388 /**
389 * Sets the disabled element flag
390 *
391 * @param bool disabled
392 */
393 function set_disabled($flag) {
394 $this->_is_disabled = $flag;
395 if ($flag) {
396 //we should make sure there was no
397 //value posted in the request, or
398 //someone tried to hack us.
399 if (isset($_REQUEST[str_replace("[]","",$this->get_element_name())])) {
400 //HACK ATTEMPT!
401 $this->_has_error = TRUE;
402 $this->_errors[] = array('label' => $this->get_label_text(),
403 'message' => 'Hack attempt discovered. Disabled Element has been submitted');
404 }
405 }
406 }
407
408 /**
409 * Returns the elements disabled
410 * state
411 *
412 * @return bool disabled
413 */
414 function is_disabled() {
415 return $this->_is_disabled;
416 }
417
418
419 /**
420 * This sets the readonly flag.
421 * When this flag is set, the FormContent
422 * gets back the get_value_text() instead
423 * of get_element().
424 *
425 * @param bool TRUE = readonly
426 */
427 function set_readonly($flag=TRUE) {
428 $this->_is_readonly = $flag;
429 }
430
431 /**
432 * Is this element in read only mode?
433 *
434 * @return bool
435 */
436 function is_readonly() {
437 return $this->_is_readonly;
438 }
439
440
441 /**
442 * This sets the stripslashes flag for
443 * this object.
444 *
445 * @param boolean
446 */
447 function set_stripslashes( $flag = TRUE ) {
448 $this->_stripslashes = $flag;
449 }
450
451
452 /********* Tag attributes methods *********/
453
454
455 /**
456 * add a single attribute (name="value")
457 *
458 * @param string $name attribute name
459 * @param mixed $value the value
460 *
461 */
462 function set_attribute($name, $value = NULL) {
463 if ($value == NULL) {
464 $this->_attributes[] = $name;
465 }
466 else {
467 $this->_attributes[$name] = $value;
468 }
469 }
470
471 /**
472 * return a single attribute
473 *
474 * @param string $name attribute name
475 * @return mixed $value the value
476 *
477 */
478 function get_attribute($name) {
479 return $this->_attributes[$name];
480 }
481
482 /**
483 * Sets elements title text
484 *
485 * @param string title
486 */
487 function set_title($title) {
488 $this->set_attribute("title", $title);
489 }
490
491 /**
492 * Sets elements css attribute
493 *
494 * @param string $name attribute name
495 * @param mixed $value the value
496 */
497 function set_style_attribute($name, $value) {
498 $this->_style_attributes[$name] = $value;
499 }
500
501 /**
502 * Sets the element's tab index
503 *
504 * @param int the # for the tabindex
505 */
506 function set_tabindex($index) {
507 $this->set_attribute('tabindex', $index);
508 }
509
510 /**
511 * Gets the current tab index if any
512 *
513 * @return int returns 0 if there is none set.
514 */
515 function get_tabindex() {
516 if (isset($this->_attributes['tabindex'])) {
517 return $this->_attributes['tabindex'];
518 } else {
519 return 0;
520 }
521 }
522
523
524 /********* Error handling methods *********/
525
526 /**
527 * Defines error message text and
528 * sets the error flag to true
529 *
530 * @param mesage text - error message
531 * @param label text - a label to provide
532 * for the error. This is
533 * only needed for a complex
534 * element that has multiple
535 * 'hidden/magic' fields.
536 */
537 function set_error_message($message, $label=NULL) {
538 if ($label == NULL) {
539 $label = $this->get_label_text();
540 }
541 $this->_errors[] = array("label" => $label,
542 "message" => $message);
543 $this->_has_error = TRUE;
544 }
545
546 /**
547 * This returns the array of errors
548 * for this element
549 *
550 * @param array of errors
551 */
552 function get_errors() {
553 return $this->_errors;
554 }
555
556
557 /**
558 * Returns the current error message
559 * if any
560 *
561 * @return mesage text - error message
562 */
563 function get_error_message() {
564 return $this->_error_message;
565 }
566
567 /**
568 * Returns the current error state
569 *
570 *
571 * @return bool error state
572 */
573 function has_error($label=NULL) {
574 if ($label==NULL) {
575 return $this->_has_error;
576 } else {
577 //they are looking for a specific error
578 foreach( $this->_errors as $error) {
579
580 if ($error['label'] == $label) {
581 return TRUE;
582 }
583 }
584 return FALSE;
585 }
586 }
587
588
589 /********* Element name handling methods *********/
590
591 /**
592 * This function creates element name
593 * used in the form based on the text label
594 * or any other parameters
595 *
596 */
597 function create_element_name() {
598 $this->set_element_name($this->_sanitize_string($this->get_label_text()));
599 }
600
601
602 /**
603 * This private method sanitizes a string for
604 * putting in a form element attribute value
605 *
606 * @param string the string to sanitize
607 * @return string
608 */
609 function _sanitize_string($name) {
610 $len = strlen($name);
611 for ($i=0; $i<$len;$i++) {
612 if ((ord($name[$i])<97 || ord($name[$i])>122) &&
613 (ord($name[$i])<48 || ord($name[$i])>57) &&
614 (ord($name[$i])<65 || ord($name[$i])>90))
615 $name[$i] = "_";
616 }
617
618 return $name;
619 }
620
621 /**
622 * This allows you to force the element
623 * name to whatever you like, so you
624 * don't have to use the default name, which is
625 * generated based on the label.
626 *
627 * @param string the form element's name
628 * @return none
629 */
630 function set_element_name($name) {
631 $this->_element_name = $name;
632 }
633
634 /**
635 * Returns the element name
636 * to be used in the form
637 *
638 * @return string form element name
639 */
640 function get_element_name() {
641 return $this->_element_name;
642 }
643
644
645 /********* Validation methods *********/
646
647 /**
648 * This method sets a flag to enable/disable
649 * validation for the Element.
650 *
651 * @param boolean TRUE = enable validation
652 */
653 function enable_validation($flag=TRUE) {
654 $this->_validation_enabled = $flag;
655 }
656
657
658 /**
659 * This function performs the actual validation
660 * It is called only if the validation is required by
661 * this element
662 *
663 * This function is responsible for performing complete
664 * validation and setting the appropriate error message
665 * in case of a failed validation
666 *
667 * @param FormValidation object.
668 */
669 function validate(&$_FormValidation) {
670 return TRUE;
671 }
672
673
674 /**
675 * This function checks if the validation
676 * is nesseccary and calls the validate method
677 *
678 * @param FormValidation object.
679 */
680 function _do_validation(&$_FormValidation) {
681 $value = $this->get_value();
682 $has_value = FALSE;
683 if (is_array($value)) {
684 foreach($value as $entry) {
685 if ($entry != NULL) {
686 $has_value = TRUE;
687 }
688 }
689 } else {
690 if ($value != NULL) {
691 $has_value = TRUE;
692 }
693 }
694
695 if ($has_value && !$this->is_disabled() && $this->_validation_enabled) {
696 return $this->validate($_FormValidation);
697 } else if ($this->is_required()) {
698 $this->set_error_message("This field cannot be empty");
699 return FALSE;
700 } else {
701 return TRUE;
702 }
703 }
704
705
706 /********* JavaScript event methods *********/
707
708 /**
709 * This method is used for adding any javascript
710 * that is used by this element. This will automatically
711 * get called and added to the page by the FormProcessor
712 *
713 * @return string - raw js
714 */
715 function javascript() {
716 return NULL;
717 }
718
719 /**
720 * This method sets the onclick javascript
721 * @param string - js code
722 */
723 function set_onClick($js){
724 $this->onClickJS = $js;
725 }
726
727
728 /**
729 * This function return the javaScript code for
730 * an onClick event
731 * Note: if you override this function be sure to use
732 * the appropriate $this->onClickJS and append your
733 * JS to it before returning
734 * @return string - javascript code
735 */
736 function onClick() {
737 return $this->onClickJS;
738 }
739
740 /**
741 * This method sets the onfocus javascript
742 * @param string - js code
743 */
744 function set_onFocus($js){
745 $this->onFocusJS = $js;
746 }
747
748 /**
749 * This function return the javaScript code for
750 * an onFocus event
751 * Note: if you override this function be sure to use
752 * the appropriate $this->onClickJS and append your
753 * JS to it before returning
754 * @return string - javascript code
755 */
756 function onFocus() {
757 return $this->onFocusJS;
758 }
759
760 /**
761 * This method sets the onSubmit javascript
762 * @param string - js code
763 */
764 function set_onSubmit($js){
765 $this->onSubmitJS = $js;
766 }
767
768 /**
769 * This function return the javaScript code for
770 * an onSubmit event
771 * Note: if you override this function be sure to use
772 * the appropriate $this->onClickJS and append your
773 * JS to it before returning
774 * @return string - javascript code
775 */
776 function onSubmit() {
777 return $this->onSubmitJS;
778 }
779
780 /**
781 * This method sets the onblur javascript
782 * @param string - js code
783 */
784 function set_onBlur($js){
785 $this->onBlurJS = $js;
786 }
787
788 /**
789 * This function return the javaScript code for
790 * an onBlur event
791 * Note: if you override this function be sure to use
792 * the appropriate $this->onClickJS and append your
793 * JS to it before returning
794 * @return string - javascript code
795 */
796 function onBlur() {
797 return $this->onBlurJS;
798 }
799
800 /**
801 * This method sets the onChange javascript
802 * @param string - js code
803 */
804 function set_onChange($js){
805 $this->onChangeJS = $js;
806 }
807
808 /**
809 * this function retuns the javaScript code for
810 * an onChange event
811 * Note: if you override this function be sure to use
812 * the appropriate $this->onClickJS and append your
813 * JS to it before returning
814 * @return string - javascript code
815 */
816 function onChange() {
817 return $this->onChangeJS;
818 }
819
820 /**
821 * This function builds the complete javaScript events code
822 * for the element
823 *
824 * @return array - attributes
825 */
826 function _build_javascript() {
827
828 $javascript = array();
829
830 if (($js=$this->onClick()) != NULL) {
831 $javascript[] = "onclick=\"" . $js . "\"";
832 }
833
834 if (($js=$this->onFocus()) != NULL) {
835 $javascript[] = "onfocus=\"" . $js . "\"";
836 }
837
838 if (($js=$this->onSubmit()) != NULL) {
839 $javascript[] = "onsubmit=\"" . $js . "\"";
840 }
841
842 if (($js=$this->onBlur()) != NULL) {
843 $javascript[] = "onblur=\"" . $js . "\"";
844 }
845
846 if (($js=$this->onChange()) != NULL) {
847 $javascript[] = "onchange=\"" . $js . "\"";
848 }
849
850 if (count($javascript)>0) {
851 return $javascript;
852 }
853 else {
854 return NULL;
855 }
856 }
857
858
859 /**
860 * This is a method for getting the JS needed
861 * for the form tag's onsubmit attribute.
862 *
863 * @return string
864 */
865 function form_tag_onsubmit() {
866 return '';
867 }
868
869
870 /********* rendering methods *********/
871
872
873 /**
874 * This function return the symbol used to
875 * denote a required field
876 *
877 * @return string - required symbol
878 */
879 function get_required_symbol() {
880 if (is_object($this->_required_field_marker)) {
881 return $this->_required_field_marker->render();
882 } else {
883 return $this->_required_field_marker;
884 }
885 }
886
887 /**
888 * This allows you to customize the
889 * require string marker
890 *
891 * @param string
892 */
893 function set_required_symbol($symbol) {
894 $this->_required_field_marker;
895 }
896
897 /**
898 * This function builds the element form attributes
899 *
900 * @return array attributes
901 */
902 function _build_element_attributes() {
903
904 $attributes = $this->_attributes;
905
906 if ($this->_style_attributes) {
907 // build the css styles
908 foreach ($this->_style_attributes as $name=>$value) {
909 $style[] = $name . ":" . $value . ";";
910 }
911 $attributes["style"] = implode("", $style);
912 }
913
914 // set the element tag name
915 $attributes["name"] = $this->get_element_name();
916
917 if (($js = $this->_build_javascript()) != NULL) {
918 // build javaScript attributes
919 $attributes = array_merge($attributes, $js);
920 }
921
922 //see if its disabled
923 if ($this->is_disabled()) {
924 $attributes[] = "disabled";
925 }
926
927 //build the ID
928 $attributes['id'] = $this->build_id_name();
929
930 return $attributes;
931 }
932
933
934
935 /**
936 * This private method is used to
937 * build the id attribute value string
938 *
939 * @return string
940 */
941 function build_id_name() {
942 return $this->_form_name.'_'.$this->get_element_name();
943 }
944
945
946 /**
947 * This function builds and returns a
948 * label object based on the label text
949 * and error conditions
950 *
951 * @param FormContent object that holds the
952 * required field marker
953 * @param string this string allows us to use this
954 * method and wrap any string as a FormElement
955 * label.
956 * @return object SPANtag
957 */
958 function get_label($form_content=NULL, $label='', $indent_flag=TRUE) {
959
960 if ($label == '') {
961 $label = $this->get_label_text();
962 }
963
964 //check to see if the form content
965 //is read only.
966 if (!is_null( $form_content )) {
967 if ($form_content->is_readonly()) {
968
969 $this->set_readonly(TRUE);
970 }
971 }
972
973 if ($this->is_required() && !$this->is_readonly()) {
974 $text = ($form_content ? $form_content->get_required_marker() :
975 $this->get_required_symbol()). ' '.$label;
976 } else {
977 if ($indent_flag) {
978 $text = '&nbsp;&nbsp;'.$label;
979 } else {
980 $text = $label;
981 }
982 }
983
984 if ($this->_label_colon_flag) {
985 $text .= ':';
986 }
987
988 $span = html_span("formlabel", $text);
989
990 if ($this->has_error($label)) {
991 $span->set_tag_attribute("style","color:red;");
992 }
993
994 return $span;
995 }
996
997 /**
998 * This method checks to see if
999 * this element is readonly and returns
1000 * the get_value_text() or returns get_element()
1001 * if it isn't readonly
1002 *
1003 * @param bool force readonly?
1004 * @return mixed
1005 */
1006 function &get_form_element($force_readonly=FALSE) {
1007 if ($force_readonly) {
1008 $this->set_readonly(TRUE);
1009 }
1010
1011 if ($this->is_readonly()) {
1012 return container($this->get_value_text(),$this->get_confirm_element());
1013 } else {
1014 return $this->get_element();
1015 }
1016 }
1017
1018
1019 /**
1020 * This function builds and returns the
1021 * form element object. This method
1022 * ignores the readonly flag.
1023 *
1024 * @return object
1025 */
1026 function get_element() {
1027
1028 $span = new SPANtag($this->_build_element_attributes(), $this->get_value());
1029
1030 return $span;
1031 }
1032
1033
1034 /**
1035 * This method returns the hidden version of this
1036 * element for a confirmation page.
1037 *
1038 * NOTE: This is called by the FormProcessor only.
1039 * It shouldn't be called manually.
1040 *
1041 * @return INPUTtag of type hidden
1042 */
1043 function get_confirm_element() {
1044 $values = $this->get_value();
1045 $name = $this->get_element_name();
1046
1047 if (is_array($values)) {
1048 $c = container();
1049 foreach ( $values as $value ) {
1050 $c->add( form_hidden($name, $value ) );
1051 }
1052 return $c;
1053 } else {
1054 return form_hidden($name, $this->get_value() );
1055 }
1056 }
1057
1058 } // FormElement
1059 ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed