38 require_once realpath(dirname(__FILE__)).
"/../field_renderers.inc";
63 var $defaultText =
"";
64 var $defaultReadOnlyText;
66 var $addNewButtonText =
"Add New";
67 var $addNewCancelButtonText =
"Cancel";
70 static $optionsCache = array();
114 function RelatedItemSelectFieldRenderer(&$form, $field, $label, $relatedClass, $constraint, $nameField, $valueField =
"", $allowAdd =
false, $allowNone =
false, $maxChars = 80)
116 $this->relatedClass = $relatedClass;
117 $this->constraint = $constraint;
118 $this->field = $field;
119 $this->nameField = $nameField;
120 $this->valueField = $valueField;
121 $this->allowAdd = $allowAdd;
122 $this->allowNone = $allowNone;
123 $this->max_chars = $maxChars;
124 $this->templateItem =
null;
125 $this->sorted =
false;
126 $this->toggleAddNew =
false;
129 if ($form->data->hasField($field))
131 $form->override($field, $label, $this);
135 $form->add($this, $field);
137 $form->overrides[$field][
'label'] = $label;
141 function allowOther($field)
143 $this->allowAdd =
false;
144 $this->otherField = $field;
152 function showAddNewToggle($addNew =
"Add New", $cancel =
"Cancel")
154 $this->toggleAddNew =
true;
155 $this->addNewButtonText = $addNew;
156 $this->addNewCancelButtonText = $cancel;
161 $id =
"{$this->parent->id}_{$field}";
163 <script type=
'text/javascript'>
164 function <?php echo $id?>_onChange(elt)
166 var addNewButton = document.id(
'<?echo $id?>_addnew_button');
171 addNewButton.setStyle(
'display',
'inline-block');
175 addNewButton.setStyle(
'display',
'none');
182 return <?php echo $this->onChange?>(elt);
188 if ($this->toggleAddNew)
191 function <?php echo $id?>_showAddNew()
193 var addNew = document.id(
'<?php echo $id?>_addnew');
194 var select = document.id(
'<?php echo $id?>_select');
195 var text = document.id(
'<?php echo $id?>_addnew_text');
196 addNew.setStyle(
'display',
'inline-block');
197 select.setStyle(
'display',
'none');
201 function <?php echo $id?>_hideAddNew()
203 var addNew = document.id(
'<?php echo $id?>_addnew');
204 var select = document.id(
'<?php echo $id?>_select');
205 var elt = document.id(
'<?php echo $id?>');
206 addNew.setStyle(
'display',
'none');
207 select.setStyle(
'display',
'inline-block');
219 $this->getRelatedItems();
222 $style =
"style='width: {$this->width}'";
225 $id =
"{$this->parent->id}_{$field}";
229 echo
"<span id='{$id}_select'>";
231 echo
"<select $style id='{$id}' name='$field'";
233 echo
" onchange='{$id}_onChange(this);'";
238 foreach($this->items as $item)
240 $name = $this->
formatName($item, $this->nameField);
241 $valueField = ($this->valueField !=
"") ? $this->valueField : $item->getPrimaryKey();
242 $value = $item->get($valueField);
243 if (!$value) $name = $this->defaultText;
245 $vals[$name] = $value;
250 ksort($vals, SORT_LOCALE_STRING);
253 $current = $this->parent->data->get($field);
255 foreach($vals as $name => $value)
258 $name = htmlSafe($name);
259 $trunced = $this->max_chars ?
ellipsis($name, $this->max_chars,
true) : $name;
262 echo
"<option value='{$value}'";
264 if ($trunced != $name) echo
" title='$name'";
272 if (($current != NULL) AND ($value == $current))
274 elseif (($current == NULL) AND ($value != NULL) AND ($value == $default))
276 echo
">$trunced</option>\n";
282 if ($this->toggleAddNew)
284 echo
" <a id='{$this->parent->id}_{$field}_addnew_button' href='#' class='button' onclick='{$id}_showAddNew(); return false'>{$this->addNewButtonText}</a></span>";
285 echo
"<span id='{$this->parent->id}_{$field}_addnew' style='display: none; white-space: nowrap'><input type='text' id='{$id}_addnew_text' name='autoform_add_$field' value='' size='30'>";
286 echo
" <a id='{$this->parent->id}_{$field}_cancel_button' href='#' class='button' onclick='{$id}_hideAddNew(); return false'>{$this->addNewCancelButtonText}</a></span>";
291 echo
"<span id={$this->parent->id}_{$field}_addnew' style='white-space: nowrap'> or add new: <input type='text' name='autoform_add_$field' value='' size='30'></span>";
294 else if ($this->otherField)
296 $otherField = $this->otherField;
297 $filter = $this->parent->data->getFilter();
299 $value = $this->parent->data->get($otherField);
301 $pkField = $this->parent->data->getPrimaryKey();
302 if ($this->parent->data->get($pkField) &&
304 $filter->isExcluded($this->otherField))
306 $obj = clone($this->parent->data);
307 $obj->setFilter(
new InclusionFilter($obj->getPrimaryKey(), $this->otherField));
309 $value = $obj->get($otherField);
313 $value = $this->parent->data->get($otherField);
316 echo
"<span style='white-space: nowrap'> if other, please specify: <input type='text' name='{$otherField}' value='{$value}' size='30'/></span>";
323 if ($mode !=
"equal")
return;
325 $this->getRelatedItems();
330 $style =
"style='width: {$this->width}'";
332 echo
"<select name='{$field}:$mode' $style>\n";
335 if (!$this->allowNone)
337 echo
"<option value=''></option>\n";
340 $value = $this->parent->params->get($field, $mode);
342 foreach($this->items as $item)
344 $valueField = ($this->valueField !=
"") ? $this->valueField : $item->getPrimaryKey();
345 $name = $this->
formatName($item, $this->nameField);
347 echo
"<option value='{$item->get($valueField)}'";
348 if ($item->get($valueField) == $value) echo
" selected";
349 echo
">".ellipsis($name, $this->max_chars).
"</option>\n";
356 function renderReadOnly($field)
358 $item = $this->getSelectedItem($field);
362 trace(
"RelatedItemSelectFieldRenderer renderReadOnly name field is {$this->nameField} field is $field and item is {$item->role}", 3);
363 if (!$item->getPrimaryKeyValue())
365 trace(
"Using default readonly text '{$this->defaultReadOnlyText}'", 3);
366 $name = $this->defaultReadOnlyText;
370 $name = $this->
formatName($item, $this->nameField);
373 if (!$this->parent->readOnlyForm)
375 $valueField = ($this->valueField !=
"") ? $this->valueField : $item->getPrimaryKey();
376 $value = $item->get($valueField);
377 echo
"<input type='hidden' id='{$this->parent->id}_{$field}' name='$field' value='$value'/>";
386 function getRelatedItems($readonly =
false)
388 $cacheKey =
"$this->relatedClass, $this->constraint";
390 if (array_key_exists($cacheKey, RelatedItemSelectFieldRenderer::$optionsCache))
392 $this->items = RelatedItemSelectFieldRenderer::$optionsCache[$cacheKey];
396 $this->items =
query($this->relatedClass, $this->constraint);
397 RelatedItemSelectFieldRenderer::$optionsCache[$cacheKey] = $this->items;
400 if ($this->allowNone)
402 $none =
new $this->relatedClass;
403 if (is_string($this->allowNone))
405 $nameField = $this->nameField;
408 $none->set($nameField, $this->defaultReadOnlyText);
410 else if ($this->defaultText)
412 $none->set($nameField, $this->defaultText);
416 $none->set($nameField, $this->allowNone);
419 $this->items = array_merge(array($none), $this->items);
424 function getSelectedItem($field)
426 $item =
new $this->relatedClass;
427 $valueField = $this->valueField ? $this->valueField : $item->getPrimaryKey();
428 $value = $this->parent->data->get($field);
432 $item =
Query::create($this->relatedClass,
"WHERE {$valueField}=:v")
438 $item =
new $this->relatedClass;
446 trace(
"RelatedItemSelectFieldRenderer::process()", 3);
448 $item =
new $this->relatedClass;
450 if ($this->otherField)
452 $filter = $this->parent->data->getFilter();
457 $filter->includeField($this->otherField);
458 $otherField = $this->otherField;
459 $this->parent->data->set($otherField, isset($_POST[$otherField]) ? $_POST[$otherField] :
"");
463 if (!$this->allowAdd)
return;
464 $valueField = $valueField ? $this->valueField : $item->getPrimaryKey();
465 $field =
"autoform_add_{$this->field}";
466 $val = $_POST[$field];
468 trace(
"Checking for value '$val' in field $field", 3);
472 foreach($this->items as $item)
474 if ($val == $this->
formatName($item, $this->nameField))
476 $this->data->set($valueField, $item->get($valueField));
481 $obj = ($this->templateItem) ? $this->templateItem :
new $this->relatedClass;
482 $pk = $obj->getPrimaryKey();
484 $nameField = $this->nameField;
486 $obj->set($nameField, $val);
489 if ($this->onItemAdded)
491 call_user_func($this->onItemAdded, $this->parent, $obj);
494 $this->parent->data->set($this->field, $obj->get($pk));
501 if (is_callable($this->onPostProcess))
503 trace(
"*** Calling RelatedItemSelectFieldRenderer::\$onPostProcess", 3);
504 call_user_func($this->onPostProcess, $this->parent);
FieldRenderer is the abstract base class for all FieldRenderers.
_startField($field, $styles="")
Internal method to generate the starting HTML for the field (including the label)
preProcess($field="")
FieldRenderers can override this method to provide behavior that occurs prior to the saving of the pa...
renderField($field)
FieldRenderers must override this method to provide the HTML implementation of the control used to ed...
formatName($item, $name)
Formats the given DataItem based on the supplied format string.
_endField($field)
Internal method to generate the closing HTML for the field.
renderScript($field)
FieldRenderers can override this method to provide any Javascript that their control requires for an ...
renderSearchField($field, $mode)
FieldRenderers must override this method to provide the HTML implementation of the control displayed ...
$onPostProcess
callback hook for processing after saving the form's data object - individual renderers may override ...
FieldRenderer($parent)
Constructor.
postProcess($field="")
FieldRenderers can override this method to provide behavior that occurs after the parent form's targe...
Used to place a filter on the contents of a DataItem-derived object.
static create($class, $constraints="")
Static factory method to create a new Query.
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
ellipsis($txt, $max, $wholeWord=false)
Truncate the supplied text at the given maximum length.
query($class)
Performs a query against the database, returning an array of DataItem objects of the specified class.