build() {
    const { values, type, ...data } = this.config
    const keyboardNav = e => {
      const list = e.target.nextSibling.nextSibling
      const hiddenField = e.target.nextSibling
      const activeOption = this.getActiveOption(list)
      const keyCodeMapVals = [
        // up
        [
          38,
          () => {
            const previous = this.getPreviousOption(activeOption)
            if (previous) {
              this.selectOption(list, previous)
            }
          },
        ],
        // down
        [
          40,
          () => {
            const next = this.getNextOption(activeOption)
            if (next) {
              this.selectOption(list, next)
            }
          },
        ],
        // enter
        [
          13,
          () => {
            if (activeOption) {
              e.target.value = activeOption.innerHTML
              hiddenField.value = activeOption.getAttribute('value')
              if (list.style.display === 'none') {
                this.showList(list, activeOption)
              } else {
                this.hideList(list)
              }
            } else {
              // Don't allow a value not in the list
              if (this.config.requireValidOption) {
                if (!this.isOptionValid(list, e.target.value)) {
                  e.target.value = ''
                  e.target.nextSibling.value = ''
                }
              }
            }
            e.preventDefault()
          },
        ],
        // escape
        [
          27,
          () => {
            this.hideList(list)
          },
        ],
      ]
      const keyCodeMap = new Map(keyCodeMapVals)

      let direction = keyCodeMap.get(e.keyCode)
      if (!direction) {
        direction = () => false
      }

      return direction()
    }
    const fauxEvents = {
      focus: evt => {
        const list = evt.target.nextSibling.nextSibling
        const filteredOptions = filter(list.querySelectorAll('li'), evt.target.value)
        evt.target.addEventListener('keydown', keyboardNav)
        if (evt.target.value.length > 0) {
          const selectedOption = filteredOptions.length > 0 ? filteredOptions[filteredOptions.length - 1] : null
          this.showList(list, selectedOption)
        }
      },
      blur: evt => {
        evt.target.removeEventListener('keydown', keyboardNav)
        const blurTimeout = setTimeout(() => {
          evt.target.nextSibling.nextSibling.style.display = 'none'
          clearTimeout(blurTimeout)
        }, 200)
        // Validate the option entered exists
        if (this.config.requireValidOption) {
          const list = evt.target.nextSibling.nextSibling
          if (!this.isOptionValid(list, evt.target.value)) {
            evt.target.value = ''
            evt.target.nextSibling.value = ''
          }
        }
      },
      input: evt => {
        const list = evt.target.nextSibling.nextSibling
        const hiddenField = evt.target.nextSibling
        hiddenField.value = evt.target.value
        const filteredOptions = filter(list.querySelectorAll('li'), evt.target.value)
        if (filteredOptions.length == 0) {
          this.hideList(list)
        } else {
          let activeOption = this.getActiveOption(list)
          if (!activeOption) {
            activeOption = filteredOptions[filteredOptions.length - 1]
          }
          this.showList(list, activeOption)
        }
      },
    }
    const fauxAttrs = Object.assign({}, data, {
      id: `${data.id}-input`,
      autocomplete: 'off',
      events: fauxEvents,
    })
    const hiddenAttrs = Object.assign({}, data, { type: 'hidden' })
    delete fauxAttrs.name
    const field = [this.markup('input', null, fauxAttrs), this.markup('input', null, hiddenAttrs)]

    const options = values.map(optionData => {
      const label = optionData.label
      const config = {
        events: {
          click: evt => {
            const list = evt.target.parentElement
            const field = list.previousSibling.previousSibling
            field.value = optionData.label
            field.nextSibling.value = optionData.value
            this.hideList(list)
          },
        },
        value: optionData.value,
      }
      return this.markup('li', label, config)
    })

    field.push(this.markup('ul', options, { id: `${data.id}-list`, className: `formbuilder-${type}-list` }))
    return field
  }
build a text DOM element, supporting other jquery text form-control's
@return {Object} DOM Element to be injected into the form.