Framework  3.9
auto_form.inc
Go to the documentation of this file.
1 <?php
5 /**************************************************************
6 
7  Copyright (c) 2007-2010 Sonjara, Inc
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or sell
14  copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  Except as contained in this notice, the name(s) of the above
22  copyright holders shall not be used in advertising or otherwise
23  to promote the sale, use or other dealings in this Software
24  without prior written authorization.
25 
26  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
28  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
30  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
31  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33  OTHER DEALINGS IN THE SOFTWARE.
34 
35 *****************************************************************/
36 
37 require_once realpath(dirname(__FILE__)."/auto_form_layout.inc");
38 require_once realpath(dirname(__FILE__)."/validation.inc");
39 require_once realpath(dirname(__FILE__)."/field_renderers.inc");
40 
45 class AutoForm
46 {
47  var $formCSS = "";
48  var $labelCSS = "";
49  var $valueCSS = "";
50  var $buttonCSS = "";
51  var $buttonLineCSS = "submit";
52  var $inputCSS = "";
53  var $checkboxCSS = "";
54  var $style = "";
55  var $componentPath ="/fakoli";
56  var $buttonAlignment = "left";
57  var $passwordEncryptor = "";
58 
59  var $hideButtons = false;
60  var $capitalizationMode = "word";
61 
62  var $submitLabel = "";
63  var $allowDelete = false;
64  var $deleteLabel = "";
65  var $deleteMessage = "";
66 
67  var $method = "POST";
68  var $action = "";
69 
70  var $renderers = array();
71  var $overrides = array();
72  var $hidden = array();
73  var $additional = array();
74  var $additional_at_top = false;
75  var $readonly = array();
76  var $annotations = array();
77  var $buttons = array();
78  var $fieldOrder = array();
79 
80  var $validator;
81  var $useLinkSubmit = false;
82 
84  var $HTMLEditorDefaultWidth = "540px";
85  var $HTMLEditorDefaultHeight = "200px";
86 
87  var $passwordEnterLabel = "Enter";
88  var $passwordConfirmLabel = "Confirm";
89 
90  var $onDrawStart = null;
91  var $onDrawComplete = null;
92 
93  var $onInsertPreProcess = null;
94  var $onSavePreProcess = null;
95  var $onSaveComplete = null;
96 
97  var $confirmPrompt = null;
98  var $onDelete = "";
99  var $customSaveHandler = null;
100  var $markRequiredFields = false;
101  var $onFormatLabel = null;
102  var $buttons_at_top = false;
103  var $ajaxSubmitHandler = false;
104  var $ajaxFailureHandler = false;
105  var $onSubmitHandler = null;
106  var $required = array();
107  var $requiredFieldsText = "* indicates required field";
108  var $interstitialMessage = null;
109  var $interstitialSpinner = '/fakoli/images/loader.gif';
110 
111  var $fields;
112 
113  var $groups = array();
114  var $collapsibleGroups = array();
115  var $groupDescriptions = array();
116 
117  var $groupDescriptionCSS = "group_description";
118  var $groupCSSClasses = array();
119 
122  var $hideEmptyFields = false;
123  var $showAnnotations = true;
124 
125  var $layout;
126  var $default_layout = "table";
127 
128  var $allowPartialSave = false;
130  var $partialSaveLabel = "Save";
131 
132  // When adding new renderers, must also update
133  // DataItem $dataTypeRendererMap
134  static $fieldRendererMap = array (
135  'String' => StringFieldRenderer,
136  'HTML' => HTMLFieldRenderer,
137  'Date' => DateFieldRenderer,
138  'DateTime' => DateTimeFieldRenderer,
139  'Number' => NumberFieldRenderer,
140  'Currency' => CurrencyFieldRenderer,
141  'Currency3' => Currency3FieldRenderer,
142  'Boolean' => BooleanFieldRenderer,
143  'TimeZone' => TimezoneFieldRenderer,
144  'Password' => PasswordFieldRenderer,
145  'Text' => TextFieldRenderer,
146  'Time' => TimeFieldRenderer,
147  'Rating' => RatingFieldRenderer,
148  'ZipCode' => ZipCodeFieldRenderer,
149  'PhoneNumber' => PhoneNumberFieldRenderer,
150  'URL' => URLFieldRenderer,
151  'DateOfBirth' => DateOfBirthFieldRenderer,
152  'CreditCardNumber' => CreditCardNumberFieldRenderer,
153  'Signature' => SignatureFieldRenderer,
154  'Color' => ColorFieldRenderer
155  );
156 
166  function AutoForm($target, $method="POST", $action="", $id="")
167  {
168  global $auto_form_defaults;
169 
170  $this->subordinate = false;
171 
172  $this->validator = new ValidationEngine();
173 
174  foreach($auto_form_defaults as $field => $value)
175  {
176  $this->$field = $value;
177  }
178 
179  if (!$target)
180  {
181  throw new FakoliException("Form has no target object");
182  }
183 
184  $this->data =& $target;
185  $this->method = $method;
186  $this->action = $action;
187  $this->id = ($id != "") ? $id : get_class($this->data)."_form";
188 
189  $this->validator->id = $this->id;
190 
191  $this->fields = $this->data->getFields();
192 
193  $filter = $this->data->getFilter();
194 
195  // Add in a default renderer for each field
196  foreach($this->fields as $field => $type)
197  {
198  if ($filter && $filter->isExcluded($field)) continue;
199 
200  $this->renderers[$field] = $this->createRenderer($field);
201  }
202 
203  $aliases = $this->data->getFieldAliases();
204  // Read in default alias definitions from DataItem
205  if ($aliases)
206  {
207  foreach($aliases as $field => $alias)
208  {
209  $this->alias($field, $alias);
210  }
211  }
212 
213  $annotations = $this->data->getFieldAnnotations();
214  // Read in default annotations from DataItem
215  if ($annotations)
216  {
217  foreach($annotations as $field => $annotation)
218  {
219  $this->annotate($field, $annotation);
220  }
221  }
222 
223  $pks = $this->data->getPrimaryKeyList();
224  foreach($pks as $p)
225  {
226  $this->hide($p);
227  }
228 
229  $hiddenFields = $this->data->getHiddenFields();
230  foreach($hiddenFields as $h)
231  {
232  $this->hide($h);
233  }
234 
235  $this->layout = AutoFormLayout::create($this->default_layout, $this);
236  }
237 
241  function getData()
242  {
243  return $this->data;
244  }
245 
246  function setDataSet($params)
247  {
248  $this->dataSet = $params;
249  }
250 
255  function setLayout($layout)
256  {
257  $this->layout = $layout;
258  }
259 
263  function setFieldOrder()
264  {
265  for($i = 0; $i < func_num_args(); ++$i)
266  {
267  $this->fieldOrder[] = func_get_arg($i);
268  }
269  }
270 
278  function createRenderer($field)
279  {
280  if (!array_key_exists($field, $this->fields)) return null;
281 
282  $type = $this->fields[$field];
283 
284  if ($type == "Timestamp") return null; // No field renderer required for this type
285 
286  if (array_key_exists($type, AutoForm::$fieldRendererMap))
287  {
288  return new AutoForm::$fieldRendererMap[$type]($this, $field);
289  }
290 
291  throw new FakoliException("AutoForm::createRenderer(): Unknown type '$type'");
292  }
293 
299  static function registerFieldRendererClass($type, $rendererClass)
300  {
301  AutoForm::$fieldRendererMap[$type] = $rendererClass;
302  }
303 
312  {
313  $filter = $this->data->getFilter();
314 
315  foreach(array_keys($this->fields) as $field)
316  {
317  if ($filter && $filter->isExcluded($field)) continue;
318  if ($this->readonly[$field]) continue; // No need to validate readonly fields
319 
320  $renderer = $this->getRenderer($field);
321  if ($renderer)
322  {
323  // JDG 9/19/2010 - let each renderer supply its own validator
324  $required = (array_search($field, $this->required) === FALSE) ? false : true;
325  $renderer->addValidatorsToForm($field, $required);
326  }
327  }
328 
329  foreach($this->additional as $r)
330  {
331  // JDG 5/2012 - check if additional field is required
332  $required = (array_search($r['field'], $this->required) === FALSE) ? false : true;
333  $r['renderer']->addValidatorsToForm($r['field'], $required);
334  }
335  }
336 
341  {
342  return $this->validator;
343  }
344 
348  function makeSubordinate()
349  {
350  $this->subordinate = true;
351  }
352 
354  {
355  if ($this->validatorsConfigured) return;
356 
357  $this->addDefaultValidators();
358 
359  foreach($this->validator->validators as $v)
360  {
361  $v->title = (!$v->title) ? $this->prettifyFieldName($v->field) : $v->title;
362  $v->readOnly = $this->isReadOnly($v->field) || $this->isHidden($v->field);
363  }
364 
365  $this->validatorsConfigured = true;
366  }
367 
374  function writeScript()
375  {
376  $this->patchUpReferences();
377 
378  ob_start();
379 
380  $this->configureValidators();
381 
382  $obj =& $this->data;
383  $filter = $obj->getFilter();
384  $pk = $obj->getPrimaryKey();
385 
386  $script = "";
387  foreach(array_keys($this->fields) as $field)
388  {
389  if ($field != $pk && !($filter && $filter->isExcluded($field)))
390  {
391  $renderer = $this->getRenderer($field);
392  if ($renderer)
393  {
394  $renderer->renderScript($field);
395  }
396  }
397  }
398 
399  foreach($this->additional as $r)
400  {
401  $r['renderer']->renderScript($r['field']);
402  }
403 
404  echo "<script type='text/javascript'>\n";
405  echo $this->validator->writeScript();
406  echo "\n\n";
407  echo "function onSubmit{$this->id}(form)\n{\n";
408 
409  echo "\tif (validate_{$this->id} != null && !validate_{$this->id}(form)) return false;\n";
410 
411  foreach(array_keys($this->fields) as $field)
412  {
413  if ($field != $pk && !($filter && $filter->isExcluded($field)))
414  {
415  $renderer = $this->getRenderer($field);
416  if ($renderer)
417  {
418  $renderer->renderOnSubmitHandler($field);
419  }
420  }
421  }
422 
423  foreach($this->additional as $r)
424  {
425  $r['renderer']->renderOnSubmitHandler($r['field']);
426  }
427 
428  if ($this->onSubmitHandler)
429  {
430  echo "\t if (!{$this->onSubmitHandler}(form)) return false;\n;";
431  }
432 
433  if ($this->confirmPrompt)
434  {
435  echo "\t if (!confirm(\"".jsSafe($this->confirmPrompt)."\")) return false;\n";
436  }
437 
438  if ($this->interstitialMessage)
439  {
440  echo "\tinterstitial('".jsSafe($this->interstitialMessage)."', '".jsSafe($this->interstitialSpinner)."');\n;";
441  }
442 
443  echo "\treturn true;\n}\n\n";
444 
445  echo "\twindow.addEvent('domready', function() {\n";
446 
447  if ($this->allowPartialSave && $this->partialSaveContainerID)
448  {
449  $managerOptions = "{partialSaveContainer: '{$this->partialSaveContainerID}', partialSaveLabel: '{$this->partialSaveLabel}'}";
450  }
451  else
452  {
453  $managerOptions = "{}";
454  }
455 
456  echo "\tnew AutoFormManager('{$this->id}', {$managerOptions});\n";
457 
458  if ($this->ajaxSubmitHandler && !$this->readOnlyForm)
459  {
460 ?>
461  document.id('<?echo $this->id?>').iFrameFormRequest(
462  {
463  'onRequest': function() { return onSubmit<?echo $this->id?>(document.id('<?echo $this->id?>')); },
464  'onComplete': <?echo $this->ajaxSubmitHandler; ?>,
465  'onFailure': <?echo $this->ajaxFailureHandler; ?>
466  });
467 <?
468 
469  }
470 
471  // Add collapsible group handlers
472 
473  foreach($this->collapsibleGroups as $group => $toggle)
474  {
475  if (is_bool($toggle))
476  {
477  $groupID = $this->id . "_" . codify($group) . "_group";
478  echo "\tdocument.id('$groupID').getElement('legend').addEvent('click', function(e) { var g = document.id('$groupID'); if (g.hasClass('collapsed')) { g.removeClass('collapsed'); g.addClass('expanded'); } else { g.removeClass('expanded'); g.addClass('collapsed'); } });\n";
479  echo "\tdocument.id('$groupID').addClass('toggleSelf');\n";
480  }
481  else
482  {
483  $groupID = $this->id . "_" . codify($group) . "_group";
484  $toggleID = $this->id . "_" . $toggle;
485 
486  $renderer = $this->getRenderer($toggle);
487  if ($renderer instanceof BooleanFieldRenderer)
488  {
489  echo "\tdocument.id('$toggleID').addEvent('click', function(e) { AutoFormManager.toggleGroup('$groupID', this.checked); });\n";
490  }
491  else
492  {
493  echo "\tdocument.id('$toggleID').addEvent('change', function(e) { AutoFormManager.toggleGroup('$groupID', (this.value != '0')); });\n";
494  }
495  }
496  }
497  echo "\t});\n";
498  echo "</script>\n";
499  $script = ob_get_contents();
500  ob_end_clean();
501  return $script;
502  }
503 
512  function getRenderer($field)
513  {
514  if (array_key_exists($field, $this->overrides))
515  {
516  if ($this->overrides[$field]['renderer']) return $this->overrides[$field]['renderer'];
517  }
518 
519  if (array_key_exists($field, $this->renderers))
520  {
521  return $this->renderers[$field];
522  }
523  else // JDG 2/13/2011 get renderer from additional field set
524  {
525  foreach($this->additional as $r)
526  {
527  $renderer = $r['renderer'];
528  $rField = $r['field'];
529  if(!$rField)
530  $rField = $renderer->field;
531  if($rField == $field)
532  return $renderer;
533  }
534  }
535 
536  trace("AutoForm::getRenderer(): Unknown field: $field", 2);
537  return null;
538  }
539 
549  function override($field, $label = "", $renderer = null)
550  {
551  if (!isset($this->overrides[$field]))
552  {
553  $this->overrides[$field] = array('label' => $label, 'renderer' => $renderer);
554  }
555  else
556  {
557  if ($label) $this->overrides[$field]['label'] = $label;
558  if ($renderer) $this->overrides[$field]['renderer'] = $renderer;
559  }
560  }
561 
569  function overrideType($field, $type, $label = "")
570  {
571  if ($type == "Timestamp") return; // No field renderer required for this type
572 
573  if (array_key_exists($type, AutoForm::$fieldRendererMap))
574  {
575  $renderer = new AutoForm::$fieldRendererMap[$type]($this, $field);
576  $this->override($field, $label, $renderer);
577  return;
578  }
579 
580  throw new FakoliException("AutoForm::createRenderer(): Unknown type '$type'");
581  }
582 
594  function add($renderer, $field = "", $label = "")
595  {
596  if (is_string($renderer))
597  {
598  if (array_key_exists($renderer, AutoForm::$fieldRendererMap))
599  {
600  $renderer = new AutoForm::$fieldRendererMap[$renderer]($this, $field);
601  }
602  else
603  {
604  throw new FakoliException("Unknown Type - {$renderer}");
605  }
606  }
607 
608  array_push($this->additional, array('renderer' => $renderer, 'field' => $field));
609  if ($field && $label)
610  {
611  $this->alias($field, $label);
612  }
613  }
614 
624  function hide()
625  {
626  foreach(func_get_args() as $hidden)
627  {
628  $this->hidden[$hidden] = true;
629  }
630  }
631 
641  function hideExcept()
642  {
643  $exceptions = array_combine(func_get_args(), func_get_args());
644  foreach($this->data->getFields() as $name => $type)
645  {
646  if (!array_key_exists($name, $exceptions))
647  {
648  $this->hidden[$name] = true;
649  }
650  }
651  }
652 
658  function isHidden($field)
659  {
660  return array_key_exists($field, $this->hidden) ? $this->hidden[$field] : false;
661  }
662 
670  function annotate($field, $text)
671  {
672  $this->annotations[$field] = $text;
673  }
674 
684  function alias()
685  {
686  for($i = 0; $i < func_num_args(); $i += 2)
687  {
688  $field = func_get_arg($i);
689  $label = func_get_arg($i + 1);
690  $this->override($field, $label);
691  }
692  }
693 
697  function related($class, $constraint = "", $format = null, $field = null, $label = null, $allowAdd = false, $allowNone = true)
698  {
699  $obj = new $class;
700  if (!$format) $format = $obj->default_format;
701  if (!$field) $field = $obj->getPrimaryKey();
702  if (!$label) $label = $obj->prettifyClassName();
703 
704  if (!$this->data->hasField($field))
705  {
706  throw new FakoliException(get_class($this->data)." has no field '{$field}'");
707  }
708 
709  if (!$format)
710  {
711  throw new FakoliException("Format not specified for related $class");
712  }
713 
714  return new RelatedItemSelectFieldRenderer($this, $field, $label, $class, $constraint, $format, $obj->getPrimaryKey(), $allowAdd, $allowNone);
715  }
716 
728  function crossReference($xrefClass, $options, $format, $field, $label = null, $xrefField = null)
729  {
730  if (!$label) $label = prettify($field);
731  return new CrossReferenceSelectFieldRenderer($this, $field, $label, $options, $format, $xrefClass, $xrefField);
732  }
733 
742  function dropdown($field, $label = "", $options = null, $onchange = null, $grouped = false)
743  {
744  return new SelectFieldRenderer($this, $field, $label, $options, $onchange, $grouped);
745  }
746 
755  function groupedDropdown($field, $label, $options, $onchange = null)
756  {
757  return $this->dropdown($field, $label, $options, $onchange, true);
758  }
759 
768  function radio($field, $label, $options, $onchange = null)
769  {
770  return new RadioButtonFieldRenderer($this, $field, $label, $options);
771  }
772 
779  function checklist($field, $label, $options, $grouped = false)
780  {
781  return new CheckListFieldRenderer($this, $field, $label, $options, $grouped);
782  }
783 
789  function toggle($field, $label = "", $ragged = false)
790  {
791  $renderer = new ToggleFieldRenderer($this, $ragged);
792  $this->override($field, $label, $renderer);
793  return $renderer;
794  }
795 
801  function group($name)
802  {
803  $group = (array_key_exists($name, $this->groups)) ? $this->groups[$name] : array();
804  for($i = 1; $i < func_num_args(); ++$i)
805  {
806  $group[] = func_get_arg($i);
807  }
808 
809  $this->groups[$name] = $group;
810  return $group;
811  }
812 
817  function addToGroup($name)
818  {
819  if (!array_key_exists($name, $this->groups))
820  {
821  $this->groups[$name] = array();
822  }
823 
824  for($i = 1; $i < func_num_args(); ++$i)
825  {
826  $this->groups[$name][] = func_get_arg($i);
827  }
828  }
829 
837  function groupDescription($name, $description, $position = 'start')
838  {
839  $this->groupDescriptions["{$name}:{$position}"] = $description;
840  }
841 
847  function getGroupDescription($name, $position = 'start')
848  {
849  $key = "{$name}:{$position}";
850  if (array_key_exists($key, $this->groupDescriptions)) return $this->groupDescriptions[$key];
851  return "";
852  }
853 
859  function makeGroupCollapsible($name, $toggleControl)
860  {
861  $this->collapsibleGroups[$name] = $toggleControl;
862  }
863 
869  function setGroupCSSClass($name, $cssClass)
870  {
871  $this->groupCSSClasses[$name] = $cssClass;
872  }
873 
879  function getGroupCSSClass($name)
880  {
881  return array_key_exists($name, $this->groupCSSClasses) ? $this->groupCSSClasses[$name] : "";
882  }
883 
889  function removeGroup($name)
890  {
891  unset($this->groups[$name]);
892  }
893 
897  function hideLabel()
898  {
899  foreach(func_get_args() as $naked)
900  {
901  $this->getRenderer($naked)->hideLabel = true;
902  }
903  }
904 
910  function readonly()
911  {
912  foreach(func_get_args() as $readonly)
913  {
914  $this->readonly[$readonly] = true;
915  }
916  }
917 
923  function isReadOnly($field)
924  {
925  return $this->readonly[$field];
926  }
933  function required()
934  {
935  foreach(func_get_args() as $required)
936  {
937  if ($this->data->hasField($required) || $this->hasAdditional($required))
938  {
939  array_push($this->required, $required);
940  }
941  }
942  }
943 
947  function hasAdditional($field)
948  {
949  foreach($this->additional as $r)
950  {
951  $renderer = $r['renderer'];
952  $rField = $r['field'];
953  trace("## $field == $rField", 3);
954  if($rField == $field)
955  return true;
956  }
957 
958  return $false;
959  }
960 
966  function isRequired($field)
967  {
968  return (array_search($field, $this->required) !== FALSE) ? true : false;
969  }
970 
977  function requiredIfChecked($field, $checkbox, $fieldTitle = "", $checkboxTitle = "", $message = "")
978  {
979  if ($this->data->hasField($field))
980  {
981  $this->validator->add(new RequiredIfCheckedValidator($field, $checkbox,
982  $fieldTitle ? $fieldTitle : $this->prettifyFieldName($field),
983  $checkboxTitle ? $checkboxTitle : $this->prettifyFieldName($checkbox), $message));
984  }
985  }
986 
995  function requiredSubSelect($field, $fieldTitle, $subFieldTitle = "", $message = "")
996  {
997  if ($this->data->hasField($field))
998  {
999  $this->validator->add(new SubSelectFieldRequiredValidator($field,
1000  $fieldTitle ? $fieldTitle : $this->prettifyFieldName($field),
1001  $subFieldTitle, $message));
1002  }
1003  }
1004 
1014  function regexp($field, $expr, $message)
1015  {
1016  if ($this->data->hasField($field))
1017  {
1018  $this->validator->add(new RegularExpressionValidator($field, $this->prettifyFieldName($field), $expr, $message));
1019  }
1020  }
1021 
1035  function dateRange($field, $min = "", $max = "", $message = null)
1036  {
1037  if ($this->data->hasField($field))
1038  {
1039  $this->validator->add(new DateRangeValidator($field, $this->prettifyFieldName($field), $min, $max, $message));
1040  }
1041  }
1042 
1048  function unique()
1049  {
1050  for($i = 0; $i < func_num_args(); $i += 2)
1051  {
1052  $field = func_get_arg($i);
1053  $message = func_get_arg($i + 1);
1054 
1055  if ($this->data->hasField($field))
1056  {
1057  $this->validator->add(new UniqueValidator($field, $this->prettifyFieldName($field), $this->data, $message));
1058  }
1059  }
1060  }
1061 
1062  function uniqueWithConstraint($field, $message, $constraint = "")
1063  {
1064  if ($this->data->hasField($field))
1065  {
1066  $this->validator->add(new UniqueValidator($field, $this->prettifyFieldName($field), $this->data, $message, $constraint));
1067  }
1068  }
1069 
1073  function range($field, $min, $max, $message = null)
1074  {
1075  if ($this->data->hasField($field))
1076  {
1077  $this->validator->add(new RangeValidator($field, $this->prettifyFieldName($field), $min, $max, $message));
1078  }
1079  }
1080 
1090  function match($field, $title, $match, $matchTitle, $caseSensitive = true)
1091  {
1092  $this->validator->add(new MatchValidator($field, $title, $match, $matchTitle, $caseSensitive));
1093  }
1094 
1101  function password($field, $title)
1102  {
1103  $this->validator->add(new PasswordValidator($field, $title, $this->id));
1104  }
1105 
1111  {
1112  $numArgs = func_num_args();
1113 
1114  if ($numArgs == 0)
1115  {
1116  foreach($this->data->getFields() as $field => $type)
1117  {
1118  if ($this->data->hasField($field))
1119  {
1120  $this->getRenderer($field)->autocomplete = false;
1121  }
1122  }
1123  }
1124  else
1125  {
1126  for($i = 0; $i < $numArgs; ++$i)
1127  {
1128  if ($this->data->hasField($field))
1129  {
1130  $this->getRenderer($field)->autocomplete = false;
1131  }
1132  }
1133  }
1134  }
1135 
1146  function button($text, $url, $confirm = null, $isScript = false, $cssClass = null)
1147  {
1148  $this->buttons[] = array('text' => $text, 'url' => $url, 'confirm' => $confirm, 'isScript' => $isScript, 'cssClass' => $cssClass);
1149  }
1150 
1157  function ajaxSubmit($success, $failure = null)
1158  {
1159  if ($failure == null)
1160  {
1161  $failure = "function() {document.id('{$form->id}_error').set('text','Failed to communicate with server'); }";
1162  }
1163 
1164  $this->ajaxSubmitHandler = $success;
1165  $this->ajaxFailureHandler = $failure;
1166  }
1167 
1176  function partialSaveButton($containerID, $label = "Save")
1177  {
1178  $this->allowPartialSave = true;
1179  $this->partialSaveContainerID = $containerID;
1180  $this->partialSaveLabel = $label;
1181  }
1182 
1187  function matchesSubmitted()
1188  {
1189  return (isset($_POST["#FORMID#"]) && $_POST["#FORMID#"] == $this->id);
1190  }
1191 
1196  function drawForm()
1197  {
1198  if ($this->readOnlyForm) return $this->drawReadOnly();
1199 
1200  if ($this->onDrawStart)
1201  {
1202  if (call_user_func_array($this->onDrawStart, array($this)) === false)
1203  {
1204  return;
1205  }
1206  }
1207 
1208  $obj =& $this->data;
1209  $pk = $obj->getPrimaryKey();
1210 
1212  if ($submitLabel == "")
1213  {
1214  $submitLabel = ($obj->get($pk) != "" && $obj->get($pk) != 0) ? "Update ".$obj->prettifyClassName() : "Add ".$obj->prettifyClassName();
1215  }
1216 
1217  //echo "<!--\n";
1218  //print_r($this);
1219  //echo "\n-->\n";
1220 
1221  if (!$this->subordinate)
1222  {
1223  echo "<form id='{$this->id}' method='{$this->method}' action='{$this->action}' enctype='multipart/form-data'";
1224  if (!$this->ajaxSubmitHandler)
1225  {
1226  echo " onsubmit='return onSubmit{$this->id}(this);'";
1227  }
1228  else
1229  {
1230  echo " data-mode='ajax'";
1231  }
1232  echo ">\n";
1233  }
1234 
1235  if ($this->id)
1236  {
1237  echo "<input type='hidden' name='#FORMID#' value='{$this->id}'/>";
1238  }
1239 
1240  $csrfToken = $_SESSION["csrfToken"];
1241  if (!$csrfToken)
1242  {
1243  $csrfToken = plainGUID();
1244  $_SESSION["csrfToken"] = $csrfToken;
1245  }
1246 
1247  echo "<input type='hidden' name='#SESSIONTIE#' value='{$csrfToken}'/>\n";
1248 
1249  foreach(array_keys($this->hidden) as $hidden)
1250  {
1251  echo "<input id='{$this->id}_{$hidden}' type='hidden' name='$hidden' value='".htmlSafe($obj->get($hidden))."'/>\n";
1252  }
1253 
1254  if ($this->layout->externalErrorBox) $this->layout->errorBox();
1255 
1256  $this->layout->startUngrouped();
1257 
1258  if ($this->buttons_at_top && !$this->subordinate && !$this->hideButtons)
1259  {
1260  $this->layout->startButtonLine();
1261 
1262  $this->drawSubmitButtons($obj, $pk, $submitLabel);
1263 
1264  $this->drawButtons();
1265 
1266  $this->layout->endButtonLine();
1267  }
1268 
1269  if (!$this->layout->externalErrorBox) $this->layout->errorBox();
1270 
1271  if ($this->markRequiredFields && $this->validator->hasRequiredFields())
1272  {
1273  $this->layout->requiredFields($this->requiredFieldsText);
1274  }
1275 
1276  $this->renderAllFields($obj);
1277 
1278  if (!$this->subordinate && !$this->hideButtons)
1279  {
1280  $this->layout->startButtonLine();
1281 
1282  $this->drawSubmitButtons($obj, $pk, $submitLabel);
1283  $this->drawButtons();
1284 
1285  $this->layout->endButtonLine();
1286  }
1287 
1288  $this->layout->endUngrouped();
1289 
1290  $this->layout->finalizeLayout();
1291 
1292  if (!$this->subordinate)
1293  {
1294  echo "</form>\n";
1295  }
1296 
1297  if ($this->onDrawComplete)
1298  {
1299  call_user_func_array($this->onDrawComplete, array($this));
1300  }
1301  }
1302 
1303  /*
1304  * JDG 12/17/2010 - break out from drawForm into into function
1305  */
1306  function drawSubmitButtons($obj, $pk, $submitLabel)
1307  {
1308  $submitID = $this->id."_submitButton";
1309 
1310  if ($this->useLinkSubmit)
1311  {
1312  echo "<a id='{$submitID}' class='{$this->buttonCSS}' name='Submit' onclick='if (onSubmit{$this->id}(document.forms.{$this->id})) return document.forms.{$this->id}.submit(); else return false;'>$submitLabel</a>";
1313  }
1314  else
1315  {
1316  echo "<input type='submit' id='{$submitID}' class='{$this->buttonCSS}' name='Submit' value='$submitLabel' ondblclick='return false;'/>";
1317  }
1318 
1319  if ($obj->get($pk) && $this->allowDelete)
1320  {
1321  $deleteLabel = ($this->deleteLabel) ? $this->deleteLabel : "Delete this ".$obj->prettifyClassName();
1322  $deleteMessage = ($this->deleteMessage) ? $this->deleteMessage : "Are you sure you want to delete this ".$obj->prettifyClassName();
1323 
1324  echo "&nbsp;&nbsp;&nbsp;&nbsp;<input type='submit' class='{$this->buttonCSS}' name='{$this->id}_delete'
1325  value='$deleteLabel'
1326  onclick='return confirm(\"{$deleteMessage}\");'/>";
1327  }
1328  }
1329 
1330  function renderAllFields($obj)
1331  {
1332  $this->renderedFields = array();
1333 
1334  if($this->additional_at_top)
1335  $this->renderAdditionalFields($obj);
1336  $this->renderFields($obj);
1337  if(!$this->additional_at_top)
1338  $this->renderAdditionalFields($obj);
1339  }
1340 
1341  /*
1342  * JDG 9/14/2010
1343  * Break out this function to facilitate inheritence
1344  * when fields needs custom layout.
1345  */
1346  function renderFields($obj)
1347  {
1348  $filter = $obj->getFilter();
1349 
1350  if (count($this->groups) > 0)
1351  {
1352  $this->layout->endUngrouped();
1353 
1354  foreach($this->groups as $legend => $fields)
1355  {
1356  $collapsible = array_key_exists($legend, $this->collapsibleGroups);
1357  if ($collapsible)
1358  {
1359  $cf = $this->collapsibleGroups[$legend];
1360  //AJG: Allow direct specification of boolean for collapsed group state
1361  $collapsed = is_bool($cf) ? $cf : !$this->data->get($cf);
1362  }
1363 
1364  $this->layout->startGroup($legend, $collapsible, $collapsed);
1365 
1366  foreach($fields as $field)
1367  {
1368  if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) &&
1369  ($this->hasAdditional($field) || !($filter && $filter->isExcluded($field))))
1370  {
1371  $this->renderOneField($field);
1372  }
1373  }
1374 
1375  $this->layout->endGroup();
1376  }
1377 
1378  $this->layout->startUngrouped();
1379 
1380  }
1381 
1382  foreach($this->fieldOrder as $field)
1383  {
1384  if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) &&
1385  ($this->hasAdditional($field) || !($filter && $filter->isExcluded($field))))
1386  {
1387  $this->renderOneField($field);
1388  }
1389  }
1390 
1391  foreach(array_keys($this->fields) as $field)
1392  {
1393  if ($field != $pk && !array_key_exists($field, $this->hidden) && !array_key_exists($field, $this->renderedFields) &&
1394  ($this->hasAdditional($field) || !($filter && $filter->isExcluded($field))))
1395  {
1396  $this->renderOneField($field);
1397  }
1398  }
1399  }
1400 
1401  function renderOneField($field, $renderScript = false)
1402  {
1403  $renderer = $this->getRenderer($field);
1404 
1405  if ($renderer)
1406  {
1407  if ($this->readonly[$field] || $this->readOnlyForm)
1408  {
1409  if (!$this->hideEmptyFields || !$this->data->hasField($field) || $this->data->get($field))
1410  {
1411  $renderer->renderReadOnly($field);
1412  }
1413  }
1414  else
1415  {
1416  if ($renderScript)
1417  {
1418  $renderer->renderScript($field);
1419  }
1420  $renderer->renderField($field);
1421  }
1422 
1423  $this->renderedFields[$field] = true;
1424  }
1425  }
1426 
1427  /*
1428  * JDG 12/17/2010 - break out into function to allow option
1429  * to render additional fields at the top.
1430  */
1431  function renderAdditionalFields($obj)
1432  {
1433  foreach($this->additional as $r)
1434  {
1435  $renderer = $r['renderer'];
1436  // JDG 5/24/11 - fix get field name
1437  $field = $r['field'];
1438  if(!$field)
1439  $field = $renderer->field;
1440 
1441  if(array_key_exists($field, $this->renderedFields))
1442  continue;
1443 
1444  if ($this->readonly[$field] || $this->readOnlyForm)
1445  {
1446  $renderer->renderReadOnly($field);
1447  }
1448  else
1449  {
1450  $renderer->renderField($field);
1451  }
1452  }
1453  }
1454 
1459  function drawButtons()
1460  {
1461  foreach($this->buttons as $button)
1462  {
1463  $url = ($button['isScript']) ? $button['url'] : "go('{$button['url']}');";
1464 
1465  if ($button['confirm'])
1466  {
1467  $link = "if (confirm('".jsSafe($button['confirm'])."')) $url; return false;";
1468  }
1469  else
1470  {
1471  $link = "$url; return false;";
1472  }
1473 
1474  $css = $this->buttonCSS;
1475  if ($button['cssClass'])
1476  {
1477  $css .= " ".$button['cssClass'];
1478  }
1479 
1480  echo "&nbsp;&nbsp;&nbsp;&nbsp;<input type='button' class='{$css}' onclick=\"$link\" value=\"{$button['text']}\"/>";
1481  }
1482 
1483  }
1484 
1489  function drawReadOnly()
1490  {
1491  $this->readOnlyForm = true;
1492 
1493  $this->layout->startUngrouped();
1494 
1495  $obj =& $this->data;
1496 
1497  $this->renderAllFields($obj);
1498 
1499  $this->layout->endUngrouped();
1500 
1501  $this->layout->finalizeLayout();
1502  }
1503 
1512  function prettifyFieldName($field)
1513  {
1514  if (array_key_exists($field, $this->overrides))
1515  {
1516  $l = $this->overrides[$field]['label'];
1517  if ($l != "") return $l;
1518  }
1519 
1520  $field = preg_replace("/([a-z])([A-Z0-9])/", "$1 $2", $field);
1521  $field = str_replace("_", " ", $field);
1522 
1523  switch($this->capitalizationMode)
1524  {
1525  case "lower":
1526 
1527  $field = strtolower($field);
1528  break;
1529 
1530  case "upper":
1531 
1532  $field = strtoupper($field);
1533  break;
1534 
1535  case "first":
1536 
1537  $field = ucfirst($field);
1538  break;
1539 
1540  case "word":
1541  default:
1542 
1543  $field = ucwords($field);
1544  break;
1545  }
1546 
1547  return $field;
1548  }
1549 
1556  function load($id)
1557  {
1558  $this->data->load($id);
1559  }
1560 
1566  function save()
1567  {
1568  $this->patchUpReferences();
1569 
1570  $this->configureValidators();
1571 
1572  $obj =& $this->data;
1573  $obj->fromPOST();
1574 
1575  $filter = $obj->getFilter();
1576  $pk = $obj->getPrimaryKey();
1577 
1578  if (isset($_POST["#FORMID#"]))
1579  {
1580  trace("FORM ID: {$this->id} - {$_POST["#FORMID#"]}", 3);
1581  $this->id = $_POST["#FORMID#"];
1582  }
1583 
1584  if (!isset($_POST["#SESSIONTIE#"]) || $_POST["#SESSIONTIE#"] != $_SESSION["csrfToken"])
1585  {
1586  trace("Invalid Session Token - {$_POST["#SESSIONTIE#"]} vs {$_SESSION["csrfToken"]}", 3);
1587  throw new FakoliException("Invalid Session Token");
1588  }
1589 
1590  if ($_POST["{$this->id}_delete"])
1591  {
1592  if(!$this->onDelete)
1593  {
1594  $obj->delete(); // no callback function defined
1595  }
1596  else
1597  {
1598  call_user_func_array($this->onDelete, array($obj));
1599  }
1600  $this->deleted = true;
1601  return true;
1602  }
1603 
1604  $this->msg = $this->validator->validate();
1605  if ($this->msg != "") return $this->handlePartialSave(false);
1606 
1607  $this->preProcessFields($pk, $filter);
1608 
1609  // Call the onInsertPreProcess callback if the primary key of the target object is not set (i.e. is a new object)
1610 
1611  if (!$this->data->getPrimaryKeyValue() & $this->onInsertPreProcess)
1612  {
1613  if (call_user_func_array($this->onInsertPreProcess, array($this)) === false)
1614  {
1615  return $this->handlePartialSave(false);
1616  }
1617  }
1618 
1619  // Call the onSavePreProcess callback if set
1620 
1621  if ($this->onSavePreProcess)
1622  {
1623  if (call_user_func_array($this->onSavePreProcess, array($this)) === false)
1624  {
1625  return $this->handlePartialSave(false);
1626  }
1627  }
1628 
1629  // Defer to the customSaveHandler if it has been defined, otherwise tell the target object to save itself
1630 
1631  if ($this->customSaveHandler)
1632  {
1633  if (!call_user_func_array($this->customSaveHandler, array($this)))
1634  {
1635  return $this->handlePartialSave(false);
1636  }
1637  }
1638  else
1639  {
1640  $obj->save();
1641  }
1642 
1643  $this->postProcessFields($pk, $filter);
1644 
1645  // onComplete event is fired once all processing has been completed
1646 
1647  if ($this->onSaveComplete)
1648  {
1649  call_user_func_array($this->onSaveComplete, array($this));
1650  }
1651 
1652  return $this->handlePartialSave(true);
1653  }
1654 
1655  function handlePartialSave($success)
1656  {
1657  // Handle partial saves - return results via AJAX and exit immediately
1658  if ($this->allowPartialSave)
1659  {
1660  $headers = getallheaders();
1661  trace(print_r($headers, true), 3);
1662 
1663  if ($headers["X-Partial-Save"])
1664  {
1665  $result = array("status" => $success ? 'success' : 'error',
1666  "primary_key" => $this->data->getPrimaryKey(),
1667  "primary_key_value" => $this->data->get($this->data->getPrimaryKey()));
1668 
1669  if (!$success)
1670  {
1671  $result["error"] = $this->msg;
1672  }
1673 
1674  ajaxReturn(json_encode($result));
1675  }
1676  }
1677 
1678  return $success;
1679  }
1680 
1681  function preProcessFields($pk, $filter)
1682  {
1683  foreach (array_keys($this->fields) as $field)
1684  {
1685  if ($field != $pk && !array_key_exists($field, $this->hidden) &&
1686  !($filter && $filter->isExcluded($field)))
1687  {
1688  $renderer = $this->getRenderer($field);
1689  if ($renderer)
1690  {
1691  $renderer->preProcess($field);
1692  }
1693  }
1694  }
1695 
1696  foreach($this->additional as $r)
1697  {
1698  $renderer = $r['renderer'];
1699  $field = $r['field'];
1700 
1701  $renderer->preProcess($field);
1702  }
1703  }
1704 
1705  function postProcessFields($pk, $filter)
1706  {
1707  foreach (array_keys($this->fields) as $field)
1708  {
1709  if ($field != $pk && !array_key_exists($field, $this->hidden) &&
1710  !($filter && $filter->isExcluded($field)))
1711  {
1712  $renderer = $this->getRenderer($field);
1713  if ($renderer)
1714  {
1715  $renderer->postProcess($field);
1716  }
1717  }
1718  }
1719 
1720  foreach($this->additional as $r)
1721  {
1722  $renderer = $r['renderer'];
1723  $field = $r['field'];
1724 
1725  $renderer->postProcess($field);
1726  }
1727  }
1728 
1729  function remove(&$obj)
1730  {
1731  $obj->delete();
1732  }
1733 
1746  function validate()
1747  {
1748  $this->patchUpReferences();
1749  $this->msg = $this->validator->validate();
1750  return ($this->msg == "");
1751  }
1752 
1761  {
1762  // Hack for PHP4 compatibility
1763  // Due to the indescribable brain-death that is PHP4's object reference semantics,
1764  // we have to resort to this method to try and ensure consistency within the form's
1765  // constituent objects. Oh, well.
1766 
1767  if (substr(phpVersion(), 0, 2) == "4.")
1768  {
1769  foreach(array_keys($this->renderers) as $renderer)
1770  {
1771  $this->renderers[$renderer]->parent =& $this;
1772  }
1773  foreach(array_keys($this->overrides) as $override)
1774  {
1775  $this->overrides[$override]["renderer"]->parent =& $this;
1776  }
1777  }
1778  }
1779 }
1780 
1781 
1782 ?>
AutoForm automatically creates a form based on an underlying DataItem.
Definition: auto_form.inc:46
$additional
The additional (pseudo) fields collection.
Definition: auto_form.inc:73
getValidationEngine()
Retrieve the validation engine for this AutoForm.
Definition: auto_form.inc:340
$useLinkSubmit
Flag to indicate whether the submit button for the form should be rendered as a link (not common).
Definition: auto_form.inc:81
drawForm()
Renders the form to HTML.
Definition: auto_form.inc:1196
requiredSubSelect($field, $fieldTitle, $subFieldTitle="", $message="")
Make a subselect field required.
Definition: auto_form.inc:995
configureValidators()
Definition: auto_form.inc:353
$formCSS
CSS Class to use for the table containing the form.
Definition: auto_form.inc:47
$validator
The ValidationEngine for this form.
Definition: auto_form.inc:80
$labelCSS
CSS Class to use for label cells.
Definition: auto_form.inc:48
hasAdditional($field)
Check if this field exists as an additional field.
Definition: auto_form.inc:947
save()
Saves the posted values to the database.
Definition: auto_form.inc:1566
radio($field, $label, $options, $onchange=null)
Utility function to add a RadioButtonFieldRenderer.
Definition: auto_form.inc:768
$interstitialMessage
Specifies the message to display in an interstitial while the form is being submitted.
Definition: auto_form.inc:108
regexp($field, $expr, $message)
Validate the user input for the specified field against a regular expression, outputting the supplied...
Definition: auto_form.inc:1014
$onDrawStart
Callback event handler that is fired just prior to drawing the form.
Definition: auto_form.inc:90
$markRequiredFields
Set to true to add an asterisk after required field labels.
Definition: auto_form.inc:100
isHidden($field)
Check whether the specified field is hidden in the form.
Definition: auto_form.inc:658
isReadOnly($field)
Determine whether the specified field is being displayed read-only.
Definition: auto_form.inc:923
postProcessFields($pk, $filter)
Definition: auto_form.inc:1705
checklist($field, $label, $options, $grouped=false)
Utility function to add a CheckListFieldRenderer.
Definition: auto_form.inc:779
$readonly
The read-only fields collection.
Definition: auto_form.inc:75
addDefaultValidators()
Creates default validators for fields in the form.
Definition: auto_form.inc:311
createRenderer($field)
This factory method creates a FieldRender based on the type of the specified field.
Definition: auto_form.inc:278
setLayout($layout)
Override the default layout manager.
Definition: auto_form.inc:255
related($class, $constraint="", $format=null, $field=null, $label=null, $allowAdd=false, $allowNone=true)
Utility function to add a RelatedItemSelectFieldRender.
Definition: auto_form.inc:697
$groupDescriptionCSS
CSS class for group description blocks.
Definition: auto_form.inc:117
addToGroup($name)
Add more fields to the specified group.
Definition: auto_form.inc:817
AutoForm($target, $method="POST", $action="", $id="")
Creates a new AutoForm, based on the supplied target DataItem.
Definition: auto_form.inc:166
$action
Action URL for submitting the form. Generally this can be left blank to submit back to the same page.
Definition: auto_form.inc:68
$readOnlyForm
Specifies whether the entire form is read-only.
Definition: auto_form.inc:120
$checkboxCSS
CSS Class to use for checkbox fields.
Definition: auto_form.inc:53
$passwordEncryptor
Password Encryption method name.
Definition: auto_form.inc:57
dateRange($field, $min="", $max="", $message=null)
Definition: auto_form.inc:1035
getData()
Returns the target data item for the form.
Definition: auto_form.inc:241
groupedDropdown($field, $label, $options, $onchange=null)
Utility function to add a SelectFieldRenderer with grouped options.
Definition: auto_form.inc:755
annotate($field, $text)
Adds an annotation (such as brief explanatory text) to the specified field.
Definition: auto_form.inc:670
$collapsibleGroups
List of collapsible groups and their default states.
Definition: auto_form.inc:114
range($field, $min, $max, $message=null)
Adds a range validator to the specified field.
Definition: auto_form.inc:1073
$fields
Local field cache.
Definition: auto_form.inc:111
load($id)
Loads the underlying DataItem from the database, using the specified primary key value.
Definition: auto_form.inc:1556
add($renderer, $field="", $label="")
Adds an additional (pseudo) field to the form.
Definition: auto_form.inc:594
$valueCSS
CSS Class to use for field/value cells.
Definition: auto_form.inc:49
writeScript()
This method writes any Javascript code that will be required for the generated form to operate,...
Definition: auto_form.inc:374
dropdown($field, $label="", $options=null, $onchange=null, $grouped=false)
Utility function to add a SelectFieldRenderer.
Definition: auto_form.inc:742
unique()
Adds a uniqueness validator to the specified field(s).
Definition: auto_form.inc:1048
drawButtons()
Draws any additional buttons specified in the calling script.
Definition: auto_form.inc:1459
$ajaxSubmitHandler
JavaScript Callback for AJAX Submit mode - called on success.
Definition: auto_form.inc:103
$overrides
The field overrides collection.
Definition: auto_form.inc:71
$deleteLabel
Text to display on the form's delete button. If not specified defaut text will be generated based on ...
Definition: auto_form.inc:64
isRequired($field)
Determine whether the specified field is a required field for the form.
Definition: auto_form.inc:966
uniqueWithConstraint($field, $message, $constraint="")
Definition: auto_form.inc:1062
$hideEmptyFields
Specifies whether to hide empty fields when displaying a read-only form.
Definition: auto_form.inc:122
crossReference($xrefClass, $options, $format, $field, $label=null, $xrefField=null)
Utility function to add a CrossReferenceSelectFieldRenderer.
Definition: auto_form.inc:728
$deleteMessage
Confirmation message to display when the form's delete button is pressed. If not specified defaut tex...
Definition: auto_form.inc:65
setDataSet($params)
Definition: auto_form.inc:246
toggle($field, $label="", $ragged=false)
Utility function to create a ToggleFieldRenderer.
Definition: auto_form.inc:789
$ajaxFailureHandler
JavaScript Callback for AJAX Submit mode - called on failure.
Definition: auto_form.inc:104
$requiredFieldsText
Text prompt to display when a form contains required fields.
Definition: auto_form.inc:107
readonly()
Call this method to make one or more fields read-only in the form's user interface.
Definition: auto_form.inc:910
static $fieldRendererMap
Provides the mapping from Type identifier to FieldRenderer.
Definition: auto_form.inc:134
$allowDelete
If true, the form will display a delete button if editing an existing item.
Definition: auto_form.inc:63
$onDrawComplete
Callback event handler that is fired just after the form been drawn.
Definition: auto_form.inc:91
renderFields($obj)
Definition: auto_form.inc:1346
handlePartialSave($success)
Definition: auto_form.inc:1655
renderOneField($field, $renderScript=false)
Definition: auto_form.inc:1401
renderAllFields($obj)
Definition: auto_form.inc:1330
static registerFieldRendererClass($type, $rendererClass)
Registers a custom type-to-renderer mapping.
Definition: auto_form.inc:299
$onDelete
delete method name
Definition: auto_form.inc:98
makeGroupCollapsible($name, $toggleControl)
Allows a group to be shown or hidden based on the value of another control.
Definition: auto_form.inc:859
$additional_at_top
whether additional fields are rendered above the datamodel's field list; if false,...
Definition: auto_form.inc:74
button($text, $url, $confirm=null, $isScript=false, $cssClass=null)
Adds a custom button to the form.
Definition: auto_form.inc:1146
overrideType($field, $type, $label="")
Override the default type for the specified form field, providing a FieldRenderer based on the suppli...
Definition: auto_form.inc:569
$interstitialSpinner
Set this property to override the default interstitial spinner animation.
Definition: auto_form.inc:109
hideLabel()
Use this method to hide the labels for the specified fields in the form.
Definition: auto_form.inc:897
$buttonCSS
CSS Class to use for buttons.
Definition: auto_form.inc:50
match($field, $title, $match, $matchTitle, $caseSensitive=true)
Specifies that two field values must match (as in a password/confirmation pair, for instance).
Definition: auto_form.inc:1090
$HTMLEditorHideStyleBar
Flag to indicate that Rich Text Editors should be displayed with or without the style editing toolbar...
Definition: auto_form.inc:83
$groupCSSClasses
Additional classes for specific groups.
Definition: auto_form.inc:118
getGroupDescription($name, $position='start')
Retrieves the group description for the specified group.
Definition: auto_form.inc:847
drawReadOnly()
Draws the form in read-only mode.
Definition: auto_form.inc:1489
group($name)
Define a field grouping.
Definition: auto_form.inc:801
required()
Call this method to mark one or more fields as being required fields.
Definition: auto_form.inc:933
$onSavePreProcess
Callback event handler that is fired after fields have been preprocessed, but before the data has bee...
Definition: auto_form.inc:94
validate()
Validate the posted values for the form.
Definition: auto_form.inc:1746
$hidden
The hidden fields collection.
Definition: auto_form.inc:72
$HTMLEditorDefaultWidth
Default width for Rich Text Editor controls.
Definition: auto_form.inc:84
$buttonAlignment
Default Form button alignment.
Definition: auto_form.inc:56
hideExcept()
Call this method to hide all the fields in the form's user interface EXCEPT the fields specified.
Definition: auto_form.inc:641
setGroupCSSClass($name, $cssClass)
Sets a specific CSS class on the specified CSS group.
Definition: auto_form.inc:869
$partialSaveLabel
Label text for the partial save button.
Definition: auto_form.inc:130
$subordinate
Specifies whether this form is a subordinate member of a composite form.
Definition: auto_form.inc:121
getRenderer($field)
Retrieves the FieldRenderer object for the specified field.
Definition: auto_form.inc:512
patchUpReferences()
Definition: auto_form.inc:1760
preProcessFields($pk, $filter)
Definition: auto_form.inc:1681
$HTMLEditorDefaultHeight
Default height for Rich Text Editor controls.
Definition: auto_form.inc:85
$fieldOrder
The order in which to display ungrouped fields.
Definition: auto_form.inc:78
$onInsertPreProcess
Callback event handler that is fired after fields have been preprocessed, but before the data has bee...
Definition: auto_form.inc:93
$allowPartialSave
Whether to allow partial (i.e. in-progress) saves via AJAX.
Definition: auto_form.inc:128
alias()
Use this method to override the display name for fields in the form.
Definition: auto_form.inc:684
setFieldOrder()
Override the display order for ungrouped field.
Definition: auto_form.inc:263
makeSubordinate()
Set this AutoForm to be a subordinate form within a CompositeAutoForm.
Definition: auto_form.inc:348
$confirmPrompt
Specify a confirmation message. This will be shown to the user to have them confirm the form submissi...
Definition: auto_form.inc:97
partialSaveButton($containerID, $label="Save")
Activate partial saves for this form.
Definition: auto_form.inc:1176
$partialSaveContainerID
DOM ID for the element that will contain the partial save button.
Definition: auto_form.inc:129
groupDescription($name, $description, $position='start')
Add a description block to a group.
Definition: auto_form.inc:837
$componentPath
Definition: auto_form.inc:55
renderAdditionalFields($obj)
Definition: auto_form.inc:1431
requiredIfChecked($field, $checkbox, $fieldTitle="", $checkboxTitle="", $message="")
Make a field required if a given checkbox is checked.
Definition: auto_form.inc:977
$method
HTTP method that will be used to submit the form.
Definition: auto_form.inc:67
$capitalizationMode
Capitalization to be used for labels. Can be 'lower', 'upper', 'first' or 'word'.
Definition: auto_form.inc:60
getGroupCSSClass($name)
Gets the CSS class for the specified group, if one has been set.
Definition: auto_form.inc:879
$inputCSS
CSS Class to use for input fields.
Definition: auto_form.inc:52
$passwordConfirmLabel
Text for Password Confirm label.
Definition: auto_form.inc:88
ajaxSubmit($success, $failure=null)
Put the form into AJAX submission mode.
Definition: auto_form.inc:1157
$onSubmitHandler
Javascript Callback for user-defined onsubmit hook.
Definition: auto_form.inc:105
prettifyFieldName($field)
Generates a human-readable label from the given field name.
Definition: auto_form.inc:1512
$hideButtons
Set to true to hide form submission button line(s)
Definition: auto_form.inc:59
$groupDescriptions
List of group descriptions.
Definition: auto_form.inc:115
$onFormatLabel
Label Processing hook.
Definition: auto_form.inc:101
$submitLabel
Text to display on the form's submit button. If not specified defaut text will be generated based on ...
Definition: auto_form.inc:62
$renderers
The field renderers collection.
Definition: auto_form.inc:70
password($field, $title)
Adds a password validator to the specified field.
Definition: auto_form.inc:1101
$onSaveComplete
Callback event handler that is fired after the AutoForm has finished saving data to the database.
Definition: auto_form.inc:95
$layout
Layout handler object.
Definition: auto_form.inc:125
hide()
Call this method to hide one or more fields in the form's user interface.
Definition: auto_form.inc:624
$customSaveHandler
Use this field to override the default save behavior of your form.
Definition: auto_form.inc:99
removeGroup($name)
Remove the specified field grouping from the form.
Definition: auto_form.inc:889
$buttons
The custom buttons collection.
Definition: auto_form.inc:77
$annotations
The field annotations collection.
Definition: auto_form.inc:76
$showAnnotations
Set to false to hide field annotations.
Definition: auto_form.inc:123
matchesSubmitted()
Determine if this form is the one that was submitted.
Definition: auto_form.inc:1187
$required
List of required fields.
Definition: auto_form.inc:106
$groups
List of field groups.
Definition: auto_form.inc:113
drawSubmitButtons($obj, $pk, $submitLabel)
Definition: auto_form.inc:1306
$buttonLineCSS
CSS Class to use for the button line (container for form buttons)
Definition: auto_form.inc:51
$passwordEnterLabel
Text for Password Enter label.
Definition: auto_form.inc:87
disableAutoComplete()
Disable autocomplete for the selected fields.
Definition: auto_form.inc:1110
static create($type, $form)
Field renderer for boolean data fields.
CheckListFieldRenderer: Renders the specified list of options as a list of checkboxes from which mult...
Field renderer for boolean data fields.
Use Currency3 if you want to have 3 decimal places displayed.
Field renderer for currency data fields.
Field renderer for date data fields.
Field renderer for date of birth data fields.
Field renderer for date data fields.
Field renderer for HTML data fields.
Tests whether two fields contain the same value.
Definition: validation.inc:814
Field renderer for numeric data fields.
Field renderer for password data fields.
Field renderer for zipcode data fields.
Field renderer for data fields that must be displayed as a list of choices.
RangeValidator class.
Field renderer for numeric rating data fields.
Tests wheteher a field's value matches the supplied regular expression.
Definition: validation.inc:950
Provides a very simple digital signature implementation.
Field renderer for string data fields.
Field renderer for text data fields.
Field renderer for time data fields.
Field renderer for boolean data fields.
Uniqueness Validator.
Definition: validation.inc:742
The ValidationEngine takes an array of validator objects in its constructor, and is then able to gene...
Field renderer for zipcode data fields.
codify($name)
Takes a text string and converts it into a code-compliant format, suitable for use as a variable name...
Definition: functions.inc:1399
plainGUID()
Generates a version 4 GUID with no punctutation.
Definition: functions.inc:1954
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
Definition: functions.inc:1010
jsSafe($str, $escapeEntities=false)
Utility function to escape a string correctly for use in a Javascript client-side call.
Definition: functions.inc:434
prettify($name)
Takes a variable or field name and converts it into a human-readable version (assuming that the origi...
Definition: functions.inc:1413
ajaxReturn($msg=null)
Returns a string output and exits the script cleanly.
Definition: functions.inc:1783