diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index bcd1d7ee32d7a221529545dec900c8735c8af82d..3c8289899b0b036a2dbb4cccf1c9354564d07cce 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -1256,6 +1256,9 @@ class SelectionField extends FormField {
         $widgetClass = false;
         if ($config['widget'] == 'typeahead' && $config['multiselect'] == false)
             $widgetClass = 'TypeaheadSelectionWidget';
+        elseif ($config['widget'] == 'textbox')
+            $widgetClass = 'TextboxSelectionWidget';
+
         return parent::getWidget($widgetClass);
     }
 
@@ -1271,9 +1274,12 @@ class SelectionField extends FormField {
             foreach ($value as $k=>$v) {
                 if (($i=$list->getItem((int) $k)))
                     $selection[$i->getId()] = $i->getValue();
-                elseif (isset($choices[$v]))
-                    $selection[$v] = $choices[$v];
+                elseif (isset($choices[$k]))
+                    $selection[$k] = $choices[$k];
             }
+        } elseif($value) {
+            //Assume invalid textbox input to be validated
+            $selection[] = $value;
         }
 
         // Don't return an empty array
@@ -1339,7 +1345,16 @@ class SelectionField extends FormField {
         parent::validateEntry($entry);
         if (!$this->errors()) {
             $config = $this->getConfiguration();
-            if ($config['typeahead']
+            if ($config['widget'] == 'textbox') {
+                if ($entry && (
+                        !($k=key($entry))
+                     || !($i=$this->getList()->getItem((int) $k))
+                 )) {
+                    $config = $this->getConfiguration();
+                    $this->_errors[] = $this->getLocal('validator-error', $config['validator-error'])
+                        ?: __('Unknown or invalid input');
+                }
+            } elseif ($config['typeahead']
                     && ($entered = $this->getWidget()->getEnteredValue())
                     && !in_array($entered, $entry))
                 $this->_errors[] = __('Select a value from the list');
@@ -1361,7 +1376,8 @@ class SelectionField extends FormField {
                 'required'=>false, 'default' => 'dropdown',
                 'choices'=>array(
                     'dropdown' => __('Drop Down'),
-                    'typeahead' =>__('Typeahead'),
+                    'typeahead' => __('Typeahead'),
+                    'textbox' => __('Text Input'),
                 ),
                 'configuration'=>array(
                     'multiselect' => false,
@@ -1372,6 +1388,17 @@ class SelectionField extends FormField {
                 ),
                 'hint'=>__('Typeahead will work better for large lists')
             )),
+            'validator-error' => new TextboxField(array(
+                'id'=>5, 'label'=>__('Validation Error'), 'default'=>'',
+                'configuration'=>array('size'=>40, 'length'=>80,
+                    'translatable'=>$this->getTranslateTag('validator-error')
+                ),
+                'visibility' => new VisibilityConstraint(
+                    new Q(array('widget__eq'=>'textbox')),
+                    VisibilityConstraint::HIDDEN
+                ),
+                'hint'=>__('Message shown to user if the item entered is not in the list')
+            )),
             'prompt' => new TextboxField(array(
                 'id'=>3,
                 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
@@ -1403,21 +1430,27 @@ class SelectionField extends FormField {
 
     function getChoices($verbose=false) {
         if (!$this->_choices || $verbose) {
-            $this->_choices = array();
+            $choices = array();
             foreach ($this->getList()->getItems() as $i)
-                $this->_choices[$i->getId()] = $i->getValue();
+                $choices[$i->getId()] = $i->getValue();
 
             // Retired old selections
             $values = ($a=$this->getAnswer()) ? $a->getValue() : array();
             if ($values && is_array($values)) {
                 foreach ($values as $k => $v) {
-                    if (!isset($this->_choices[$k])) {
+                    if (!isset($choices[$k])) {
                         if ($verbose) $v .= ' '.__('(retired)');
-                        $this->_choices[$k] = $v;
+                        $choices[$k] = $v;
                     }
                 }
             }
+
+            if ($verbose) // Don't cache
+                return $choices;
+
+            $this->_choices = $choices;
         }
+
         return $this->_choices;
     }
 
@@ -1547,6 +1580,10 @@ class TypeaheadSelectionWidget extends ChoicesWidget {
         <?php
     }
 
+    function parsedValue() {
+        return array($this->getValue() => $this->getEnteredValue());
+    }
+
     function getValue() {
         $data = $this->field->getSource();
         if (isset($data[$this->name]))
diff --git a/include/class.forms.php b/include/class.forms.php
index 3345669da755517199ec6a29d75ac76d8aa0147d..0f89971ec862f548d026beff74155422e94e93bb 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -2274,6 +2274,30 @@ class TextboxWidget extends Widget {
     }
 }
 
+
+class TextboxSelectionWidget extends TextboxWidget {
+    //TODO: Support multi-input e.g comma separated inputs
+    function render($options=array()) {
+
+        if ($this->value && is_array($this->value))
+            $this->value = current($this->value);
+
+        parent::render($options);
+    }
+
+    function getValue() {
+
+        $value = parent::getValue();
+        if (($i=$this->field->getList()->getItem((string) $value)))
+            $value = array($i->getId() => $i->getValue());
+        elseif (($choices=$this->field->getChoices())
+                && ($k=array_search($value, $choices)))
+            $value = array($k => $choices[$k]);
+
+        return $value;
+    }
+}
+
 class PasswordWidget extends TextboxWidget {
     static $input_type = 'password';