Select from a list and allow freeform text in one control?

I have a list of common selections my users can make, but they also need to be able to enter a text item not in the list. I would prefer to do this in 1 control, rather than having an “Other” option with a separate field to save their input.

Is there a control that can provide this functionality?

Hi Matt

The easiest implementation (fewest lines of code) is the separate text-input, but you can achieve what you want by using a single-cell <object-table/> with an <edit-type-ahead/> column and a nested <action/> tag. To edit a single object in an object-table simply push the object into an array and then bind the array to the object table

Below is a basic example of selecting an asset condition and allowing a freeform other option. Reference docs here

View XML

<var name="asset" type="asset" />
    <var name="asset_array" type="array:asset" />


    <object-table query="asset_array" empty-message="Your items will appear here">
        <column heading="Asset Condition" display="{condition}">
            <edit-typeahead empty-message="No results" on-search="$:onSearch($object, searchValue)" on-change="$:handleEdit(@$object, newValue, oldValue)">
                <action label="Add other" on-press="$:addOther($object, searchValue)" icon="fa-plus" />
            </edit-typeahead>
        </column>
    </object-table>

View JS

// This function is called when the app navigates to this view (using a link)
function init() {
  // initialize any data here that should be available when the view is shown
  view.asset = DB.asset.first();
  view.asset_array = [view.asset];
  
}

/**
 * @param {DB.asset} asset
 * @param {string} searchValue
 * @returns {object}
 */
function onSearch(asset, searchValue){
   return [
     {label: "Very Good", key: "Very Good"},
     {label: "Good", key: "Good"},
     {label: "Average", key: "Average"},
     {label: "Poor", key: "Poor"},
     {label: "Very Poor", key: "Very Poor"},
   ];
 }

/**
 * @param {DB.asset} asset
 * @param {string} searchValue
 */
function addOther(asset, searchValue){
    asset.condition = searchValue;
}
/**
 * @param {DB.asset} asset
 * @param {string} newValue
 * @param {string} oldValue
 */
function handleEdit(asset, newValue, oldValue) {
    asset.condition = newValue;
    asset.save();
}

Thanks Tielman, I’ll give it a try