diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php
index 3d93e9a9cf3585d38189e8c705dafe54246fa2aa..31776edb86d683629b1eeafa7915151d68172b80 100644
--- a/include/ajax.tickets.php
+++ b/include/ajax.tickets.php
@@ -208,13 +208,16 @@ class TicketsAjaxAPI extends AjaxController {
         $cdata_search = false;
         foreach (TicketForm::getInstance()->getFields() as $f) {
             if (isset($req[$f->getFormName()])
-                    && ($val = $req[$f->getFormName()])
-                    && strlen(trim($val))) {
+                    && ($val = $req[$f->getFormName()])) {
                 $name = $f->get('name') ? $f->get('name')
                     : 'field_'.$f->get('id');
-                if ($f->getImpl()->hasIdValue() && is_numeric($val)) {
-                    $cwhere = "cdata.`{$name}_id` = ".db_input($val);
-                    $criteria["cdata.{$name}_id"] = $val;
+                if (is_array($val)) {
+                    $cwhere = '(' . implode(' OR ', array_map(
+                        function($k) use ($name) {
+                            return sprintf('FIND_IN_SET(%s, `%s`)', db_input($k), $name);
+                        }, $val)
+                    ) . ')';
+                    $criteria["cdata.{$name}"] = $val;
                 }
                 else {
                     $cwhere = "cdata.`$name` LIKE '%".db_real_escape($val)."%'";
diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index 1add7ca244e2b2d4d6a844cc7f9264dc51df53ec..c5133c9d6a40e81df5c47406c13e6fe38565f617 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -196,16 +196,19 @@ class DynamicForm extends VerySimpleModel {
             if (!$impl->hasData() || $impl->isPresentationOnly())
                 continue;
 
+            $id = $f->get('id');
             $name = ($f->get('name')) ? $f->get('name')
-                : 'field_'.$f->get('id');
+                : 'field_'.$id;
 
-            $fields[] = sprintf(
-                'MAX(IF(field.name=\'%1$s\',ans.value,NULL)) as `%1$s`',
-                $name);
-            if ($impl->hasIdValue()) {
+            if ($impl instanceof ChoiceField || $impl instanceof SelectionField) {
                 $fields[] = sprintf(
-                    'MAX(IF(field.name=\'%1$s\',ans.value_id,NULL)) as `%1$s_id`',
-                    $name);
+                    'MAX(CASE WHEN field.id=\'%1$s\' THEN REPLACE(REPLACE(REPLACE(REPLACE(coalesce(ans.value_id, ans.value), \'{\', \'\'), \'}\', \'\'), \'"\', \'\'), \':\', \',\') ELSE NULL END) as `%2$s`',
+                    $id, $name);
+            }
+            else {
+                $fields[] = sprintf(
+                    'MAX(IF(field.id=\'%1$s\',coalesce(ans.value_id, ans.value),NULL)) as `%2$s`',
+                    $id, $name);
             }
         }
         return $fields;
@@ -321,10 +324,8 @@ class TicketForm extends DynamicForm {
         $f = $answer->getField();
         $name = $f->get('name') ? $f->get('name')
             : 'field_'.$f->get('id');
-        $ids = $f->hasIdValue();
-        $fields = sprintf('`%s`=', $name) . db_input($answer->get('value'));
-        if ($f->hasIdValue())
-            $fields .= sprintf(',`%s_id`=', $name) . db_input($answer->getIdValue());
+        $fields = sprintf('`%s`=', $name) . db_input(
+            implode(',', $answer->getSearchKeys()));
         $sql = 'INSERT INTO `'.TABLE_PREFIX.'ticket__cdata` SET '.$fields
             .', `ticket_id`='.db_input($answer->getEntry()->get('object_id'))
             .' ON DUPLICATE KEY UPDATE '.$fields;
@@ -944,6 +945,14 @@ class DynamicFormEntryAnswer extends VerySimpleModel {
         );
     }
 
+    function getSearchKeys() {
+        $val = $this->getField()->to_php($this->getValue());
+        if (is_array($val))
+            return array_keys($val);
+
+        return [$val];
+    }
+
     function asVar() {
         return (is_object($this->getValue()))
             ? $this->getValue() : $this->toString();
@@ -1004,15 +1013,13 @@ 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 array($value, $id);
+        return $value;
     }
 
     function to_php($value, $id=false) {
@@ -1023,13 +1030,11 @@ class SelectionField extends FormField {
             if (isset($choices[$value]))
                 $value = $choices[$value];
         }
+        // Don't set the ID here as multiselect prevents using exactly one
+        // ID value. Instead, stick with the JSON value only.
         return $value;
     }
 
-    function hasIdValue() {
-        return true;
-    }
-
     function hasSubFields() {
         return true;
     }
diff --git a/include/class.forms.php b/include/class.forms.php
index 018c5b76535a1d9db12c32d5653e46e34b066751..040cd255425d55c5a24140bbda9da0cffa463606 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1688,7 +1688,7 @@ class ChoicesWidget extends Widget {
 
     function render($mode=false) {
 
-        if ($mode && $mode == 'view') {
+        if ($mode == 'view') {
             if (!($val = (string) $this->field))
                 $val = sprintf('<span class="faded">%s</span>', __('None'));
 
@@ -1697,6 +1697,10 @@ class ChoicesWidget extends Widget {
         }
 
         $config = $this->field->getConfiguration();
+        if ($mode == 'search') {
+            $config['multiselect'] = true;
+        }
+
         // Determine the value for the default (the one listed if nothing is
         // selected)
         $choices = $this->field->getChoices(true);
diff --git a/include/class.search.php b/include/class.search.php
index 270e0322055ae05714954431ae8c7a812ff2bcf2..9e3a380efbfc081c42fe27ddf5b32a95f7f244d4 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -331,7 +331,17 @@ class MysqlSearchBackend extends SearchBackend {
                             // Search ticket CDATA table
                             $cdata_search = true;
                             $name = substr($name, 6);
-                            $where[] = sprintf("cdata.%s = %s", $name, db_input($value));
+                            if (is_array($value)) {
+                                $where[] = '(' . implode(' OR ', array_map(
+                                    function($k) use ($name) {
+                                        return sprintf('FIND_IN_SET(%s, cdata.`%s`)',
+                                            db_input($k), $name);
+                                    }, $value)
+                                ) . ')';
+                            }
+                            else {
+                                $where[] = sprintf("cdata.%s = %s", $name, db_input($value));
+                            }
                         }
                     }
                 }
diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php
index ee55d4152a2444cfeb97a5db94049501be4d18e8..671600b785e20d90df39173482da78c8a5803d9f 100644
--- a/include/staff/tickets.inc.php
+++ b/include/staff/tickets.inc.php
@@ -255,7 +255,7 @@ $qselect.=' ,IF(ticket.duedate IS NULL,IF(sla.id IS NULL, NULL, DATE_ADD(ticket.
          .' ,ticket.created as ticket_created, CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team '
          .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned '
          .' ,IF(ptopic.topic_pid IS NULL, topic.topic, CONCAT_WS(" / ", ptopic.topic, topic.topic)) as helptopic '
-         .' ,cdata.priority_id, cdata.subject, pri.priority_desc, pri.priority_color';
+         .' ,cdata.priority as priority_id, cdata.subject, pri.priority_desc, pri.priority_color';
 
 $qfrom.=' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON (ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW()
                AND tlock.staff_id!='.db_input($thisstaff->getId()).') '
@@ -265,7 +265,7 @@ $qfrom.=' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON (ticket.ticket_id=tlock.ticke
        .' LEFT JOIN '.TOPIC_TABLE.' topic ON (ticket.topic_id=topic.topic_id) '
        .' LEFT JOIN '.TOPIC_TABLE.' ptopic ON (ptopic.topic_id=topic.topic_pid) '
        .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) '
-       .' LEFT JOIN '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority_id)';
+       .' LEFT JOIN '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority)';
 
 TicketForm::ensureDynamicDataView();