diff --git a/include/ajax.forms.php b/include/ajax.forms.php
index 47ace2a54aecae50695a91abda04ced0db72ba71..84b2cb3d8da8302fa1ed1fd0ad9600ea8b8fcf4a 100644
--- a/include/ajax.forms.php
+++ b/include/ajax.forms.php
@@ -39,9 +39,10 @@ class DynamicFormsAjaxAPI extends AjaxController {
     function saveFieldConfiguration($field_id) {
         $field = DynamicFormField::lookup($field_id);
         if (!$field->setConfiguration())
-            include(STAFFINC_DIR . 'templates/dynamic-field-config.tmpl.php');
+            return (include STAFFINC_DIR . 'templates/dynamic-field-config.tmpl.php');
         else
             $field->save();
+        Http::response(201, 'Field successfully updated');
     }
 
     function deleteAnswer($entry_id, $field_id) {
@@ -74,9 +75,11 @@ class DynamicFormsAjaxAPI extends AjaxController {
             Http::response(404, 'No such list item');
 
         if (!$item->setConfiguration())
-            include(STAFFINC_DIR . 'templates/list-item-properties.tmpl.php');
+            return (include STAFFINC_DIR . 'templates/list-item-properties.tmpl.php');
         else
             $item->save();
+
+        Http::response(201, 'Successfully updated record');
     }
 }
 ?>
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index bb95d76b3f3cc6295603fc712f35b55a565bf4f8..46c5045c3c867bae66eca202686517d610d610bc 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -696,9 +696,14 @@ class DynamicFormEntry extends VerySimpleModel {
 
     function forTicket($ticket_id, $force=false) {
         static $entries = array();
-        if (!isset($entries[$ticket_id]) || $force)
-            $entries[$ticket_id] = DynamicFormEntry::objects()
+        if (!isset($entries[$ticket_id]) || $force) {
+            $stuff = DynamicFormEntry::objects()
                 ->filter(array('object_id'=>$ticket_id, 'object_type'=>'T'));
+            // If forced, don't cache the result
+            if ($force)
+                return $stuff;
+            $entries[$ticket_id] = &$stuff;
+        }
         return $entries[$ticket_id];
     }
     function setTicketId($ticket_id) {
@@ -936,7 +941,7 @@ class DynamicFormEntryAnswer extends VerySimpleModel {
 }
 
 class SelectionField extends FormField {
-    static $widget = 'SelectionWidget';
+    static $widget = 'ChoicesWidget';
 
     function getListId() {
         list(,$list_id) = explode('-', $this->get('type'));
@@ -950,6 +955,14 @@ class SelectionField extends FormField {
         return $this->_list;
     }
 
+    function getWidget() {
+        $config = $this->getConfiguration();
+        $widgetClass = false;
+        if ($config['widget'] == 'typeahead')
+            $widgetClass = 'TypeaheadSelectionWidget';
+        return parent::getWidget($widgetClass);
+    }
+
     function parse($value) {
 
         if (!($list=$this->getList()))
@@ -958,16 +971,9 @@ class SelectionField extends FormField {
         $config = $this->getConfiguration();
         $choices = $this->getChoices();
         $selection = array();
-        if ($config['typeahead']) {
-            // Entered value
-            $val = $this->getWidget()->getEnteredValue();
-            if (($i=$list->getItem($val)) && $i->getId() == $value)
-                $selection[$i->getId()] = $i->getValue();
-            elseif ($val && isset($choices[$value])) //perhaps old deleted item...
-                $selection[$value] = $choices[$value];
-        } elseif ($value && is_array($value)) {
-            foreach ($value as $v) {
-                if (($i=$list->getItem((int) $v)))
+        if ($value && is_array($value)) {
+            foreach ($value as $k=>$v) {
+                if (($i=$list->getItem((int) $k)))
                     $selection[$i->getId()] = $i->getValue();
                 elseif (isset($choices[$v]))
                     $selection[$v] = $choices[$v];
@@ -978,15 +984,26 @@ class SelectionField extends FormField {
     }
 
     function to_database($value) {
+        $id = null;
+        if (is_array($value)) {
+            reset($value);
+            $id = key($value);
+        }
         if ($value && is_array($value))
             $value = JsonDataEncoder::encode($value);
 
-        return $value;
+        return array($value, $id);
     }
 
     function to_php($value, $id=false) {
-        return ($value && !is_array($value))
+        $value = ($value && !is_array($value))
             ? JsonDataParser::parse($value) : $value;
+        if (!is_array($value)) {
+            $choices = $this->getChoices();
+            if (isset($choices[$value]))
+                $value = $choices[$value];
+        }
+        return $value;
     }
 
     function hasIdValue() {
@@ -1002,10 +1019,9 @@ class SelectionField extends FormField {
         parent::validateEntry($entry);
         if (!$this->errors()) {
             $config = $this->getConfiguration();
-            if (!$entry || count($entry) == 0)
-                $this->_errors[] = __('Select a value from the list');
-            elseif ($config['typeahead']
-                    && !in_array($this->getWidget()->getEnteredValue(), $entry))
+            if ($config['typeahead']
+                    && ($entered = $this->getWidget()->getEnteredValue())
+                    && !in_array($entered, $entry))
                 $this->_errors[] = __('Select a value from the list');
         }
     }
@@ -1043,7 +1059,7 @@ class SelectionField extends FormField {
 
         $config = parent::getConfiguration();
         if ($config['widget'])
-            $config['typeahead'] = isset($config['widget']['typeahead']);
+            $config['typeahead'] = $config['widget'] == 'typeahead';
 
         //Typeahed doesn't support multiselect for now  TODO: Add!
         if ($config['typeahead'])
@@ -1072,6 +1088,18 @@ class SelectionField extends FormField {
         return $this->_choices;
     }
 
+    function getChoice($value) {
+        $choices = $this->getChoices();
+        if ($value && is_array($value)) {
+            $selection = $value;
+        } elseif (isset($choices[$value]))
+            $selection[] = $choices[$value];
+        elseif ($this->get('default'))
+            $selection[] = $choices[$this->get('default')];
+
+        return $selection;
+    }
+
     function export($value) {
         if ($value && is_numeric($value)
                 && ($item = DynamicListItem::lookup($value)))
@@ -1088,23 +1116,15 @@ class SelectionField extends FormField {
     }
 }
 
-class SelectionWidget extends ChoicesWidget {
-    function render($mode=false) {
+class TypeaheadSelectionWidget extends ChoicesWidget {
+    function render($how) {
+        if ($how == 'search')
+            return parent::render($how);
 
-        $config = $this->field->getConfiguration();
-        if (($value=$this->getValue()))
-            $value =  $this->field->parse($value);
-        elseif ($this->value)
-            $value = $this->value;
-
-        if (!$config['typeahead'] || $mode=='search') {
-            $this->value = $value;
-            return parent::render($mode);
-        }
-
-        if ($value && is_array($value)) {
-            $name = current($value);
-            $value = key($value);
+        $name = $this->getEnteredValue();
+        if (is_array($this->value)) {
+            $name = $name ?: current($this->value);
+            $value = key($this->value);
         }
 
         $source = array();
@@ -1117,20 +1137,23 @@ class SelectionWidget extends ChoicesWidget {
             );
         ?>
         <span style="display:inline-block">
-        <input type="text" size="30" name="<?php echo $this->name; ?>"
-            id="<?php echo $this->name; ?>" value="<?php echo $name; ?>"
+        <input type="text" size="30" name="<?php echo $this->name; ?>_name"
+            id="<?php echo $this->name; ?>" value="<?php echo Format::htmlchars($name); ?>"
             placeholder="<?php echo $config['prompt'];
             ?>" autocomplete="off" />
         <input type="hidden" name="<?php echo $this->name;
-            ?>_id" id="<?php echo $this->name; ?>_id" value="<?php echo $value; ?>"/>
+            ?>[<?php echo $value; ?>]" id="<?php echo $this->name;
+            ?>_id" value="<?php echo Format::htmlchars($name); ?>"/>
         <script type="text/javascript">
         $(function() {
             $('input#<?php echo $this->name; ?>').typeahead({
                 source: <?php echo JsonDataEncoder::encode($source); ?>,
                 property: 'info',
                 onselect: function(item) {
-                    $('input#<?php echo $this->name; ?>').val(item['value'])
-                    $('input#<?php echo $this->name; ?>_id').val(item['id'])
+                    $('input#<?php echo $this->name; ?>_name').val(item['value'])
+                    $('input#<?php echo $this->name; ?>_id')
+                      .attr('name', '<?php echo $this->name; ?>[' + item['id'] + ']')
+                      .val(item['value']);
                 }
             });
         });
@@ -1141,14 +1164,16 @@ class SelectionWidget extends ChoicesWidget {
 
     function getValue() {
         $data = $this->field->getSource();
-        // Search for HTML form name first
-        if (isset($data[$this->name.'_id']))
-            return (int) $data[$this->name.'_id'];
+        if (isset($data[$this->name]))
+            return $data[$this->name];
         return parent::getValue();
     }
 
     function getEnteredValue() {
         // Used to verify typeahead fields
+        $data = $this->field->getSource();
+        if (isset($data[$this->name.'_name']))
+            return trim($data[$this->name.'_name']);
         return parent::getValue();
     }
 }
diff --git a/include/class.forms.php b/include/class.forms.php
index c5c93866e9fa35b9404de09a3cf54dc2fe095628..f51a06fdc40950adda8eb7a63ed04f329ccf4c20 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -506,11 +506,11 @@ class FormField {
         $this->_config[$prop] = $value;
     }
 
-    function getWidget() {
+    function getWidget($widgetClass=false) {
         if (!static::$widget)
             throw new Exception(__('Widget not defined for this field'));
         if (!isset($this->_widget)) {
-            $wc = $this->get('widget') ? $this->get('widget') : static::$widget;
+            $wc = $widgetClass ?: $this->get('widget') ?: static::$widget;
             $this->_widget = new $wc($this);
             $this->_widget->parseValue();
         }
@@ -757,37 +757,38 @@ class ChoiceField extends FormField {
     }
 
     function parse($value) {
-
-        if (!$value) return null;
-
-        // Assume multiselect
-        $values = array();
-        $choices = $this->getChoices();
-        if (is_array($value)) {
-            foreach($value as $k => $v)
-                if (isset($choices[$v]))
-                    $values[$v] = $choices[$v];
-        } elseif(isset($choices[$value])) {
-            $values[$value] = $choices[$value];
-        }
-
-        return $values ?: null;
+        return $this->to_php($value ?: null);
     }
 
     function to_database($value) {
-        if ($value && is_array($value))
+        if (!is_array($value)) {
+            $choices = $this->getChoices();
+            if (isset($choices[$value]))
+                $value = array($value => $choices[$value]);
+        }
+        if (is_array($value))
             $value = JsonDataEncoder::encode($value);
 
         return $value;
     }
 
     function to_php($value) {
-        return ($value && !is_array($value))
-            ? JsonDataParser::parse($value) : $value;
+        if (is_string($value))
+            $array = JsonDataParser::parse($value) ?: $value;
+        else
+            $array = $value;
+        $config = $this->getConfiguration();
+        if (is_array($array) && !$config['multiselect'] && count($array) < 2) {
+            reset($array);
+            return key($array);
+        }
+        return $array;
     }
 
     function toString($value) {
-        return (string) $this->getChoice($value);
+        $selection = $this->getChoice($value);
+        return is_array($selection) ? implode(', ', array_filter($selection))
+            : (string) $selection;
     }
 
     function getChoice($value) {
@@ -801,7 +802,7 @@ class ChoiceField extends FormField {
         elseif ($this->get('default'))
             $selection[] = $choices[$this->get('default')];
 
-        return $selection ? implode(', ', array_filter($selection)) : '';
+        return $selection;
     }
 
     function getChoices($verbose=false) {
@@ -1171,7 +1172,6 @@ FormField::addFieldTypes('Dynamic Fields', function() {
     );
 });
 
-
 class Widget {
 
     function __construct($field) {
@@ -1321,10 +1321,10 @@ class ChoicesWidget extends Widget {
             $def_val = $have_def ? $choices[$def_key] : $prompt;
         }
 
-        if (($value=$this->getValue()))
-            $values = $this->field->parse($value);
-        elseif ($this->value)
-             $values = $this->value;
+        $values = $this->value;
+        if (!is_array($values)) {
+            $values = array($values => $this->field->getChoice($values));
+        }
 
         if ($values === null)
             $values = $have_def ? array($def_key => $choices[$def_key]) : array();
@@ -1361,6 +1361,23 @@ class ChoicesWidget extends Widget {
        <?php
         }
     }
+
+    function getValue() {
+        $value = parent::getValue();
+
+        if (!$value) return null;
+
+        // Assume multiselect
+        $values = array();
+        $choices = $this->field->getChoices();
+        if (is_array($value)) {
+            foreach($value as $k => $v) {
+                if (isset($choices[$v]))
+                    $values[$v] = $choices[$v];
+            }
+        }
+        return $values;
+    }
 }
 
 class CheckboxWidget extends Widget {
diff --git a/include/class.list.php b/include/class.list.php
index 31a3dd51938e8f56fd841021b7021d72a1ec3291..86a428c222c1069aa24ef09a781e529e6e0a965d 100644
--- a/include/class.list.php
+++ b/include/class.list.php
@@ -946,8 +946,8 @@ class TicketStatus  extends VerySimpleModel implements CustomListItem {
                     }
                     break;
                 case 'state':
-                    if ($val && is_array($val))
-                        $this->set('state', key($val));
+                    if ($val)
+                        $this->set('state', $val);
                     else
                         $f->addError(__('Unknown or invalid state'), $name);
                     break;
diff --git a/include/staff/dynamic-form.inc.php b/include/staff/dynamic-form.inc.php
index 0f18c7e89d0db018caefbb2aa3b1035309470f99..b160e2c253f9b993701ad18c7ad651bfcd88a358 100644
--- a/include/staff/dynamic-form.inc.php
+++ b/include/staff/dynamic-form.inc.php
@@ -150,13 +150,11 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 <?php } ?>
             </select>
             <?php if ($f->isConfigurable()) { ?>
-                <a class="action-button" style="float:none;overflow:inherit"
+                <a class="action-button field-config" style="float:none;overflow:inherit"
                     href="#ajax.php/form/field-config/<?php
                         echo $f->get('id'); ?>"
                     onclick="javascript:
-                        $('#overlay').show();
-                        $('#field-config .body').empty().load($(this).attr('href').substr(1));
-                        $('#field-config').show();
+                        $.dialog($(this).attr('href').substr(1), [201]);
                         return false;
                     "><i class="icon-edit"></i> <?php echo __('Config'); ?></a>
             <?php } ?>
diff --git a/include/staff/dynamic-list.inc.php b/include/staff/dynamic-list.inc.php
index 280d85eccf1a08609215299b7b1abdeb8b87224c..f25f671135d4302bcbbda52a389e3fa904199d5b 100644
--- a/include/staff/dynamic-list.inc.php
+++ b/include/staff/dynamic-list.inc.php
@@ -339,7 +339,7 @@ $(function() {
         e.preventDefault();
         var $id = $(this).attr('id');
         var url = 'ajax.php/'+$(this).attr('href').substr(1);
-        $.dialog(url, [200], function (xhr) {
+        $.dialog(url, [201], function (xhr) {
             $('a#'+$id+' i').removeAttr('style');
         });
         return false;
diff --git a/scp/js/scp.js b/scp/js/scp.js
index 953712f43b368377454b5ff028b553bb40330c96..83bc2540034237109f99daefc482ca21e7f6d019 100644
--- a/scp/js/scp.js
+++ b/scp/js/scp.js
@@ -534,7 +534,8 @@ $.dialog = function (url, codes, cb, options) {
 
     $('#overlay').show();
     $('div.body', $popup).empty().hide();
-    $('div#popup-loading', $popup).show();
+    $('div#popup-loading', $popup).show()
+        .find('h1').css({'margin-top':function() { return $popup.height()/3-$(this).height()/3}});
     $popup.show();
     $('div.body', $popup).load(url, function () {
         $('div#popup-loading', $popup).hide();
@@ -548,7 +549,8 @@ $.dialog = function (url, codes, cb, options) {
         $(document).on('submit.dialog', '.dialog#popup form', function(e) {
             e.preventDefault();
             var $form = $(this);
-            var $dialog = $form.closest('.dialog');
+            $('div#popup-loading', $popup).show()
+                .find('h1').css({'margin-top':function() { return $popup.height()/3-$(this).height()/3}});
             $.ajax({
                 type:  $form.attr('method'),
                 url: 'ajax.php/'+$form.attr('action').substr(1),
@@ -557,17 +559,19 @@ $.dialog = function (url, codes, cb, options) {
                 success: function(resp, status, xhr) {
                     if (xhr && xhr.status && codes
                         && $.inArray(xhr.status, codes) != -1) {
-                        $('div.body', $dialog).empty();
-                        $dialog.hide();
+                        $('div.body', $popup).empty();
+                        $popup.hide();
                         $('#overlay').hide();
                         if(cb) cb(xhr);
                     } else {
-                        $('div.body', $dialog).html(resp);
-                        $('#msg_notice, #msg_error', $dialog).delay(5000).slideUp();
+                        $('div.body', $popup).html(resp);
+                        $('#msg_notice, #msg_error', $popup).delay(5000).slideUp();
                     }
                 }
             })
-            .done(function() { })
+            .done(function() {
+                $('div#popup-loading', $popup).hide();
+            })
             .fail(function() { });
             return false;
         });