carbon-web-components icon indicating copy to clipboard operation
carbon-web-components copied to clipboard

Dynamic combo box items

Open tpluscode opened this issue 3 years ago • 4 comments

The problem

I would like to dynamically populate the combo box items by user input, such as when searching a large collection, retrieved from a remote resource

The solution

Looking at the storybook, it does nota appear possible to hack the combo box web component currently.

A minimal change would require that there is a value-changed kind of event which I could listen to and load matching elements for rendering from an API etc.

Application/website

private

Business priority

Low Priority = release date is not dependent on fix or not upcoming

What time frame would this ideally be needed by (if applicable)

No response

Examples

No response

Code of Conduct

tpluscode avatar Jan 27 '22 19:01 tpluscode

@emyarod to investigate

ljcarot avatar Feb 01 '22 18:02 ljcarot

@tpluscode would listening to the input event fit your use case? if not can you elaborate on the changes you are expecting?

emyarod avatar Feb 02 '22 22:02 emyarod

Sorry for coming back to this after much time.

It does not have to be super complicated. I thought I would go with manually replacing the bx-combo-box-item elements. Here's how that could be

class MyDynamicComboBox {
  @property({ type:Array }) items = []

  render() {
    return html`
      <bx-combo-box @bx-combo-box-filtered="${this.loadItems}">
        ${this.items.map(this.renderItem)}
      </bx-combo-box>
    `
  }

  renderItem(item) {
    return html`<bx-combo-box-item value=${item.value}>${item.label}</bx-combo-box-item>`
  }

  async __loadItems(e) {
    this.items = await fetchItems(e.detail.searchText)
  }
}

As long as I can listen for user input in the text field (bx-combo-box-filtered), I'm good to go.

One small necessary detail would be to debounce the fetchItems call. This could be part of the combo itself but not sure.

tpluscode avatar May 28 '22 19:05 tpluscode

Additionally, in case of large collections to search, I know I will be fetching the data in pages.

In such scenario, it would be nice to have an event triggered when the menu-body is scrolled to the bottom. Something in the lines of

<menu-body @scroll=${this.notifyBottom}>

notifyBottom(e) {
  if (e.target.scrollTop + e.target.getBoundingClientRect().height == e.target.scrollHeight) {
    this.dispatchEvent(new CustomEvent('bx-combo-box-scrolled-to-bottom'))
  }
}

I could then handle this event to fetch subsequent pages dynamically in an infinite scroll fashion. WDYT?

tpluscode avatar May 28 '22 19:05 tpluscode