From ce2be28750ad608be15a59fa1715dc5aa340f4e1 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Thu, 16 Jan 2014 16:45:53 -0600 Subject: [PATCH] forms: Fix ambiguous id / value for typeahead If a dynamic list is displayed as a typeahead box, the value, when saved, will be confused with the corresponding ID field for the list. MySQL supports numeric comparison between the INT id column and the textual value column. Therefore, if a typeahead field has the value of '01 - GooGoo', then record will match the ListItem<id=1>, regardless of which list the item is defined for. This patch resolves the issue by submitting the ID number of the list selection in the HTTP form. --- include/class.dynamic_forms.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php index ccfe4d27e..8e4df839a 100644 --- a/include/class.dynamic_forms.php +++ b/include/class.dynamic_forms.php @@ -878,11 +878,16 @@ class SelectionField extends FormField { } function parse($value) { - return $this->to_php($value); + $config = $this->getConfiguration(); + if (is_int($value) || !$config['typeahead']) + return $this->to_php(null, (int) $value); + else + return $this->to_php($value); } function to_php($value, $id=false) { - $item = DynamicListItem::lookup($id ? $id : $value); + if ($id && is_int($id)) + $item = DynamicListItem::lookup($id); # Attempt item lookup by name too if (!$item) { $item = DynamicListItem::lookup(array( @@ -951,7 +956,7 @@ class SelectionWidget extends ChoicesWidget { $source = array(); foreach ($this->field->getList()->getItems() as $i) $source[] = array( - 'value' => $i->get('value'), + 'value' => $i->get('value'), 'id' => $i->get('id'), 'info' => $i->get('value')." -- ".$i->get('extra'), ); ?> @@ -959,6 +964,8 @@ class SelectionWidget extends ChoicesWidget { <input type="text" size="30" name="<?php echo $this->name; ?>" id="<?php echo $this->name; ?>" value="<?php echo $name; ?>" autocomplete="off" /> + <input type="hidden" name="<?php echo $this->name; + ?>_id" id="<?php echo $this->name; ?>_id" value="<?php echo $value; ?>"/> <script type="text/javascript"> $(function() { $('input#<?php echo $this->name; ?>').typeahead({ @@ -966,6 +973,7 @@ class SelectionWidget extends ChoicesWidget { property: 'info', onselect: function(item) { $('input#<?php echo $this->name; ?>').val(item['value']) + $('input#<?php echo $this->name; ?>_id').val(item['id']) } }); }); @@ -973,5 +981,13 @@ class SelectionWidget extends ChoicesWidget { </span> <?php } + + function getValue() { + $data = $this->field->getSource(); + // Search for HTML form name first + if (isset($data[$this->name.'_id'])) + return (int) $data[$this->name.'_id']; + return parent::getValue(); + } } ?> -- GitLab