Framework  3.9
OptionCrossReferenceFieldRenderer Class Reference

Displays a control that provides a highly styleable set of options from which the user can select a number of items. More...

+ Inheritance diagram for OptionCrossReferenceFieldRenderer:
+ Collaboration diagram for OptionCrossReferenceFieldRenderer:

Public Member Functions

 OptionCrossReferenceFieldRenderer (&$form, $field, $label, $options, $nameField, $xrefClass, $grouped=false)
 
 groupBy ($groupBy, $format="")
 
 renderScript ($field)
 FieldRenderers can override this method to provide any Javascript that their control requires for an edit form. More...
 
 renderField ($field)
 FieldRenderers must override this method to provide the HTML implementation of the control used to edit the field. More...
 
 renderOptions ($field, $options, $selectedItems)
 
 renderReadOnly ($field)
 
 getSelected ($obj, $rc, $pk)
 
 getMatchingPK ($xref, $obj)
 
 postProcess ($field="")
 FieldRenderers can override this method to provide behavior that occurs after the parent form's target object has been saved to the database. More...
 
 clearOutRelations ($obj, $pk, $tx)
 Clear out the current relations stored in the xref class. More...
 
- Public Member Functions inherited from FieldRenderer
 FieldRenderer ($parent)
 Constructor. More...
 
 _printLabel ($field, $colspan=1, $styles="", $annotation="")
 Internal method to generate the HTML for the field label. More...
 
 _getLabel ($field, $addSuffix=true)
 
 _startField ($field, $styles="")
 Internal method to generate the starting HTML for the field (including the label) More...
 
 _endField ($field)
 Internal method to generate the closing HTML for the field. More...
 
 addValidatorsToForm ($field, $required=false)
 This method is called by the AutoForm to add any default input validators that are required by the FieldRenderer. More...
 
 addSearchValidatorsToForm ($field, $mode, $required=false)
 For SearchForm, the validator field needs to match the name tag in the form which is in the format field:mode. More...
 
 formatName ($item, $name)
 Formats the given DataItem based on the supplied format string. More...
 
 renderSearchScript ($field, $mode)
 FieldRenderers can override this method to provide any Javascript that the control requires when being used in a search form. More...
 
 renderSearchField ($field, $mode)
 FieldRenderers must override this method to provide the HTML implementation of the control displayed for the field in a search form. More...
 
 renderOnSubmitHandler ($field)
 FieldRenderers can override this method to provide any Javascript that must be executed when the form is submitted on the client. More...
 
 preProcess ($field="")
 FieldRenderers can override this method to provide behavior that occurs prior to the saving of the parent form's target object to the database. More...
 

Public Attributes

 $options = array()
 
 $cssClass = "options_list"
 
 $separator = ", "
 
 $nameField
 
 $xrefClass
 
 $onStartOption = null
 
 $grouped = false
 
 $groupTag = "h4"
 
 $containerClass = ""
 
- Public Attributes inherited from FieldRenderer
 $parent = null
 
 $labelSuffix = ""
 
 $colspan = 1
 
 $annotateBefore = false
 
 $annotateNextLine = true
 
 $hideLabel = false
 
 $onPreProcess = null
 callback hook for processing prior to saving the form's data object - individual renderers may override with custom processing More...
 
 $onPostProcess = null
 callback hook for processing after saving the form's data object - individual renderers may override with custom processing More...
 

Detailed Description

Displays a control that provides a highly styleable set of options from which the user can select a number of items.

The options are provided as an array of DataItems that are associated with the target item of the form via a cross-reference table that contains foreign keys to both. The options are rendered as an unordered list in HTML, with javascript to provide the selection interaction. Clicking on one of the items will select the associated value. The currently selected list item is given the "selected" CSS class.

Options can be grouped by three distinct mechanisms. Firstly, the array of items passed in can be an associative array with the group headings as the keys. Secondly the options can be automatically grouped by the values in a specified field by calling the groupBy() method with the name of the field and a formatting string for the group heading. Finally the options can be grouped by a secondary list of DataItems by passing an array to the groupBy() method. In this case the options will be grouped by the primary key values of the supplied objects, and must contain a matching foreign key.

Author
Andy

Definition at line 21 of file option_cross_reference_field_renderer.inc.

Member Function Documentation

◆ clearOutRelations()

OptionCrossReferenceFieldRenderer::clearOutRelations (   $obj,
  $pk,
  $tx 
)

Clear out the current relations stored in the xref class.

Parameters
Object$obj
String$pk

Definition at line 311 of file option_cross_reference_field_renderer.inc.

312  {
313  $xref = new $this->xrefClass;
314  $xref->joinTransaction($tx);
315  $xref->delete("WHERE {$pk}=".$obj->get($pk));
316  }

◆ getMatchingPK()

OptionCrossReferenceFieldRenderer::getMatchingPK (   $xref,
  $obj 
)

Definition at line 245 of file option_cross_reference_field_renderer.inc.

246  {
247  $pks = $obj->getPrimaryKeyList();
248  foreach($pks as $pk)
249  {
250  if ($xref->hasField($pk)) return $pk;
251  }
252 
253  throw new DataItemException("No matching foreign key in xref table");
254  }

◆ getSelected()

OptionCrossReferenceFieldRenderer::getSelected (   $obj,
  $rc,
  $pk 
)

Definition at line 240 of file option_cross_reference_field_renderer.inc.

241  {
242  return ($obj->get($pk) != "") ? indexedQuery($this->xrefClass, "WHERE {$pk}={$obj->get($pk)}", $rc->getPrimaryKey()) : array();
243  }
indexedQuery($class)
Performs a query against the database, returning an array of DataItem objects of the specified class,...

◆ groupBy()

OptionCrossReferenceFieldRenderer::groupBy (   $groupBy,
  $format = "" 
)

Definition at line 53 of file option_cross_reference_field_renderer.inc.

54  {
55  $this->groupBy = $groupBy;
56  $this->groupByFormat = $format;
57  }

◆ OptionCrossReferenceFieldRenderer()

OptionCrossReferenceFieldRenderer::OptionCrossReferenceFieldRenderer ( $form,
  $field,
  $label,
  $options,
  $nameField,
  $xrefClass,
  $grouped = false 
)

Definition at line 33 of file option_cross_reference_field_renderer.inc.

34  {
35  $this->options = $options;
36  $this->nameField = $nameField;
37  $this->xrefClass = $xrefClass;
38  $this->grouped = $grouped;
39 
40  $this->FieldRenderer($form);
41  if ($form->data->hasField($field))
42  {
43  $form->override($field, $label, $this);
44  }
45  else
46  {
47  $form->add($this, $field);
48  if ($label) $form->alias($field, $label);
49  }
50  }
FieldRenderer($parent)
Constructor.

◆ postProcess()

OptionCrossReferenceFieldRenderer::postProcess (   $field = "")

FieldRenderers can override this method to provide behavior that occurs after the parent form's target object has been saved to the database.

For example, the CrossReferenceSelectFieldRenderer overrides this method to update crossference tables based on the user's selection.

Parameters
string$field

Reimplemented from FieldRenderer.

Definition at line 256 of file option_cross_reference_field_renderer.inc.

257  {
258  if (count($this->options) == 0) return;
259 
260  $xref = new $this->xrefClass;
261 
262  $obj = $this->parent->data;
263  $pk = $this->getMatchingPK($xref, $obj);
264 
265  if (is_array($this->groupBy) && count($this->groupBy) > 0)
266  {
267  $keys = array_keys($this->options);
268  $rc = $this->options[$keys[0]][0];
269  }
270  else
271  {
272  $rc = $this->options[0];
273  }
274 
275  $optpk = $this->getMatchingPK($xref, $rc);
276 
277  $tx = new DataTransaction();
278  try
279  {
280  $this->clearOutRelations($obj, $pk, $tx);
281 
282  if (isset($_POST[$field]))
283  {
284  $ids = explode(",", $_POST[$field]);
285 
286  foreach($ids as $id)
287  {
288  $xref = new $this->xrefClass;
289  $xref->joinTransaction($tx);
290  $xref->set($pk, $obj->get($pk));
291  $xref->set($optpk, $id);
292  $xref->save();
293  }
294  }
295 
296  $tx->commit();
297  }
298  catch (Exception $e)
299  {
300  $tx->rollback();
301  throw $e;
302  }
303  }
The DataTransaction class wraps the underlying database's transaction model.
Definition: transaction.inc:48
clearOutRelations($obj, $pk, $tx)
Clear out the current relations stored in the xref class.

◆ renderField()

OptionCrossReferenceFieldRenderer::renderField (   $field)

FieldRenderers must override this method to provide the HTML implementation of the control used to edit the field.

Parameters
string$fieldthe field name

Reimplemented from FieldRenderer.

Definition at line 100 of file option_cross_reference_field_renderer.inc.

101  {
102  $this->_startField($field);
103 
104  trace("# of Options: ".count($this->options), 3);
105 
106  if (count($this->options))
107  {
108  if ($this->containerClass) { echo "<div class='{$this->containerClass}'>\n"; }
109 
110  $obj = $this->parent->data;
111 
112  if (is_array($this->groupBy) && count($this->groupBy) > 0)
113  {
114  $keys = array_keys($this->options);
115  $rc = $this->options[$keys[0]][0];
116  }
117  else if ($this->grouped)
118  {
119  $keys = array_keys($this->options);
120  $rc = $this->options[$keys[0]][0];
121  }
122  else
123  {
124  $rc = $this->options[0];
125  }
126  $pk = $obj->getPrimaryKey();
127 
128  if (!$rc)
129  {
130  $this->_endField($field);
131  return;
132  }
133 
134  $selectedItems = $this->getSelected($obj, $rc, $pk);
135 
136 
137  $value = implode(",", array_keys($selectedItems));
138 
139  $id = "{$this->parent->id}_{$field}";
140 
141  echo "<input type='hidden' id='{$id}' name='{$field}' value='{$value}'/>";
142 
143  if (is_array($this->groupBy) && count($this->groupBy) > 0)
144  {
145  $gpk = $this->groupBy[0]->getPrimaryKey();
146 
147  foreach($this->groupBy as $group)
148  {
149  if (array_key_exists($group->get($gpk), $this->options))
150  {
151  echo $group->format($this->groupByFormat);
152  $this->renderOptions($field, $this->options[$group->get($gpk)], $selectedItems);
153  }
154  }
155  }
156  else if (is_string($this->groupBy))
157  {
158  trace("Rendering grouped by", 3);
159  $options = regroupList($this->options, $this->groupBy);
160 
161  foreach($options as $group => $choices)
162  {
163  echo "<{$this->groupTag}>$group</{$this->groupTag}>";
164  $this->renderOptions($field, $choices, $selectedItems);
165  }
166  }
167  else if ($this->grouped)
168  {
169  trace("Rendering grouped", 3);
170  foreach($this->options as $group => $choices)
171  {
172  echo "<{$this->groupTag}>$group</{$this->groupTag}>";
173  $this->renderOptions($field, $choices, $selectedItems);
174  }
175  }
176  else
177  {
178  trace("Rendering simple", 3);
179  $this->renderOptions($field, $this->options, $selectedItems);
180  }
181 
182  if ($this->containerClass) { echo "</div>\n"; }
183  }
184  $this->_endField($field);
185  }
_startField($field, $styles="")
Internal method to generate the starting HTML for the field (including the label)
_endField($field)
Internal method to generate the closing HTML for the field.
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
Definition: functions.inc:1010
regroupList($list, $field)
Regroup an indexed or grouped query result by a different field.
Definition: data_item.inc:1948

◆ renderOptions()

OptionCrossReferenceFieldRenderer::renderOptions (   $field,
  $options,
  $selectedItems 
)

Definition at line 187 of file option_cross_reference_field_renderer.inc.

188  {
189  $id = "{$this->parent->id}_{$field}";
190 
191  echo "<ul class='{$id}_list {$this->cssClass}'>";
192  foreach($options as $option)
193  {
194  $val = $option->get($option->getPrimaryKey());
195  $classes = array();
196  if (array_key_exists($val, $selectedItems)) $classes[] = "selected";
197 
198  if ($this->onStartOption)
199  {
200  $flag = call_user_func($this->onStartOption, $option);
201  if ($flag === false) continue;
202  if ($flag) $classes[] = $flag;
203  }
204 
205  $classes = implode(" ", $classes);
206 
207  $description = $this->formatName($option, $this->nameField);
208  echo "<li class='{$classes}' data-value='{$val}' onclick='{$id}_update(this); return false;'>{$description}</li>\n";
209  }
210  echo "</ul>";
211  }
formatName($item, $name)
Formats the given DataItem based on the supplied format string.

◆ renderReadOnly()

OptionCrossReferenceFieldRenderer::renderReadOnly (   $field)

Definition at line 213 of file option_cross_reference_field_renderer.inc.

214  {
215  $this->_startField($field);
216 
217  if (count($this->options))
218  {
219 
220  $obj = $this->parent->data;
221 
222  $rc = $this->options[0];
223  $pk = $obj->getPrimaryKey();
224 
225  $selectedItems = $this->getSelected($obj, $rc, $pk);
226 
227  $selected = array();
228  foreach($this->options as $option)
229  {
230  $val = $option->get($option->getPrimaryKey());
231  if (array_key_exists($val, $selectedItems)) $selected[] = $option;
232  }
233 
234  echo formatItems($selected, "{".$this->nameField."}", $this->separator);
235  }
236 
237  $this->_endField($field);
238  }
formatItems($items, $template, $separator="")
Format a list of DataItems using the specified templated.
Definition: data_item.inc:2176

◆ renderScript()

OptionCrossReferenceFieldRenderer::renderScript (   $field)

FieldRenderers can override this method to provide any Javascript that their control requires for an edit form.

Parameters
string$fieldthe field name

Reimplemented from FieldRenderer.

Definition at line 59 of file option_cross_reference_field_renderer.inc.

60  {
61  if ($this->parent->readOnlyForm || $this->parent->isReadOnly($field)) return;
62  $id = "{$this->parent->id}_{$field}";
63  ?>
64  <script type='text/javascript'>
65  function <?echo $id?>_update(sel)
66  {
67  if (sel.hasClass("selected"))
68  {
69  sel.removeClass("selected");
70  }
71  else
72  {
73  sel.addClass("selected");
74  }
75 
76  var values = [];
77 
78  $$('.<?echo $id?>_list > li').each(function(elt)
79  {
80  if (elt.hasClass('selected'))
81  {
82  var v = elt.get('data-value');
83  values.push(v);
84  }
85  });
86 
87  var hidden = document.id('<?echo $id?>');
88  var v = hidden.value;
89  hidden.value = values.join(",");
90  var f = document.id('<?echo $this->parent->id?>');
91  if (v != hidden.value && f && f.manager)
92  {
93  f.manager.dirty();
94  }
95  }
96  </script>
97 <?
98  }

Member Data Documentation

◆ $containerClass

OptionCrossReferenceFieldRenderer::$containerClass = ""

Definition at line 31 of file option_cross_reference_field_renderer.inc.

◆ $cssClass

OptionCrossReferenceFieldRenderer::$cssClass = "options_list"

Definition at line 24 of file option_cross_reference_field_renderer.inc.

◆ $grouped

OptionCrossReferenceFieldRenderer::$grouped = false

Definition at line 29 of file option_cross_reference_field_renderer.inc.

◆ $groupTag

OptionCrossReferenceFieldRenderer::$groupTag = "h4"

Definition at line 30 of file option_cross_reference_field_renderer.inc.

◆ $nameField

OptionCrossReferenceFieldRenderer::$nameField

Definition at line 26 of file option_cross_reference_field_renderer.inc.

◆ $onStartOption

OptionCrossReferenceFieldRenderer::$onStartOption = null

Definition at line 28 of file option_cross_reference_field_renderer.inc.

◆ $options

OptionCrossReferenceFieldRenderer::$options = array()

Definition at line 23 of file option_cross_reference_field_renderer.inc.

◆ $separator

OptionCrossReferenceFieldRenderer::$separator = ", "

Definition at line 25 of file option_cross_reference_field_renderer.inc.

◆ $xrefClass

OptionCrossReferenceFieldRenderer::$xrefClass

Definition at line 27 of file option_cross_reference_field_renderer.inc.


The documentation for this class was generated from the following file: