Search code examples
javascriptautocompletepolymerpolymer-1.0web-component

Using datalist from local DOM in polymer


My custom component 'autocomplete-input' should provide an autocomplete functionality. I am using the 'list' attribute of 'paper-input'. The value of the 'list' attribute has to be the 'id' of a 'datalist'.

This works fine, as long as I instantiate only one 'autocomplete-input' element. If there are multiple instances of the 'autocomplete-input' element, they all show the same autocomplete proposals. I guess this is because the 'list' attribute does not use the local DOM and therefore uses the first 'datalist' with that particular 'id'. How can I avoid this?

The 'autocomplete-input' element:

<dom-module id="autocomplete-input">
  <template>
    <datalist id="autocomplete">
      <template is="dom-repeat" items="{{proposals}}">
        <option data-value$="{{item.value}}">{{item.content}}</option>
      </template>
    </datalist>
    <paper-input id="input" list="autocomplete" label="{{header}}" value="{{content::input}}"></paper-input>
  </template>
  <script>
  Polymer({
    is: 'autocomplete-input',
    properties: {
      header: String,
      content: String,
      proposals: Array
    }
  });
  </script>
</dom-module>

Solution

  • Use a global counter and add it to your id

    <dom-module id="autocomplete-input">
      <template>
        <datalist id$="[[autocompleteId]]">
          <template is="dom-repeat" items="{{proposals}}">
            <option data-value$="{{item.value}}">{{item.content}}</option>
          </template>
        </datalist>
        <paper-input id="input" list$="[[autocompleteId]]" label="{{header}}" value="{{content::input}}"></paper-input>
      </template>
      <script>
      Polymer({
        is: 'autocomplete-input',
        properties: {
          header: String,
          content: String,
          proposals: Array,
        }
      }),
      autoCompleteId: function() {
        return this.autocompleteId = this.autocompleteId || ++globalId; 
        // see linke below to figure out how to use globals
      }
      </script>
    </dom-module>
    

    See Polymer 1.0 Global Variables for more details about globals in Polymer (My JS isn't good enough because I use Polymer only from Dart)