nn-input-text-class.js

nn-input-text-class.js

This element is a thin wrap to <input type=text>.

Designers

This is a simple text input element. Use it instead of <input type="text">.

This element implements the validation API, extending it. It allows you to set custom validators, as well as custom error messages for native regexp-based validation.

For example:

<nn-input-text id="group" name="group"></nn-input-text>
<script>
  group.validator = () => {
    const value = document.querySelector('#group').value
    if (group.value.startsWith('a')) return 'No group can start with "a"'
  }
</script>

This will ensure that upon validation the field will display the error No group can start with "a" if the field starts with “a”.

Note that validation will happen before form submission.

Default themes:

Developers

Mixins

  • NativeReflectorMixin - It reflects every attribute and every API property/method from the native element to the outer element.

  • InputMixin - Will skip reflection for the type attribute (since type is always text), and will reflect all of the properties and methods of <input> elements according to the HTMLInputElement API

  • LabelsMixin - Implements labels for form elements.

  • StyleableMixin - Allows designers to add custom styles to the element by having a <style slot="style"> defined in the element’ light DOM.

  • NativeValidatorMixin - Implements the full Contraint Validation API.

  • FormElementMixin - Assigns the correct form property to form elements; form is a reference to the containing form element. This needs to be done artificially since HTML will only assign the form property automatically if both form and element are in the same shadow DOM.

import { LitElement, html } from 'lit'
import { NativeReflectorMixin } from '../mixins/NativeReflectorMixin.js'
import { InputMixin } from '../mixins/InputMixin.js'
import { FormElementMixin } from '../mixins/FormElementMixin.js'
import { NativeValidatorMixin } from '../mixins/NativeValidatorMixin.js'
import { LabelsMixin } from '../mixins/LabelsMixin.js'
import { StyleableMixin } from '../mixins/StyleableMixin.js'
import tpeRegistry from '../tpeRegistry'

export class NnInputText extends FormElementMixin(NativeValidatorMixin(StyleableMixin(LabelsMixin(InputMixin(NativeReflectorMixin(LitElement)))))) {
  render () {
    
    return html`
      ${this.ifLabelBefore}
      ${this.ifValidationMessageBefore}
      <input type="text" id="native" real-time-event="input" >
      ${this.ifValidationMessageAfter}
      ${this.ifLabelAfter}
      <slot id="datalist-slot" name="datalist"></slot>
    `
  }

  constructor () {
    super()
    this._boundKeyEventListener = this._eventListener.bind(this)
  }

  static get properties () {
    return {
      submitOnEnter: { type: Boolean, attribute: 'submit-on-enter' }
    }
  }

Submit on enter with forms with only one element

  _eventListener (e) {
    if (this.form && e.keyCode === 13 && (this.form.elements.length === 1 || this.submitOnEnter)) {
      this.form.submit()
    }
  }

  afterSettingProperty (prop, newValue) {
    super.afterSettingProperty(prop, newValue)

Update the form parent value if prop is value

    if (prop === 'value' && this.internals) {
      this.internals.setFormValue(this.value)
    }
  }

  firstUpdated () {
    super.firstUpdated()

    this.addEventListener('keydown', this._boundKeyEventListener)

    const slot = this.shadowRoot.querySelector('#datalist-slot')
    const slotFirstAssignedElement = slot && slot.assignedElements()[0]
    const datalistOptions = slotFirstAssignedElement && slotFirstAssignedElement.children
    if (datalistOptions && datalistOptions.length) {
      const datalistElement = document.createElement('datalist')
      datalistElement.setAttribute('id', '_datalist')
      this.setAttribute('list', '_datalist')
      for (const el of datalistOptions) {
        const optionElement = document.createElement('option')
        optionElement.setAttribute('value', el.getAttribute('value'))
        datalistElement.appendChild(optionElement)
      }
      this.shadowRoot.appendChild(datalistElement)
    }
  }
}
tpeRegistry.register('nn-input-text', NnInputText)