The list

The list

If there's a key area of the component that must be absolutely customizable, it's the dropdown with the list. This is probably the most dense chapter so far so we recommend that you read it cover to cover.

Position and destination

The dropdown in Ember Power Select is pretty smart. By default this component inserts the dropdown not next the the trigger but in the a placeholder element in the root of your app (typically the <body>) using the awesome ember-wormhole addon and then absolutely positions it.

This is a safe default because by default it won't be affected by the overflow constraints of the element where the component lives in. However, there are a few situations where this is not practical, so you can tune this in two different ways.

You can configure Ember Basic Dropdown (the addon used internally by EPS) to use a different element as destination for the dropdown. By default an <div id="ember-basic-dropdown-wormhole"></div> div is added to the root of your app and used as destination, but you can specify a different one globally:

  // config/environment.js

  ENV['ember-basic-dropdown'] = {
    destination: '<id-of-destination-element>'

If you customize the destination element, then it is up to you to add that element somewhere in your app.

You can also specify a destination div on a per component basis, using the destination property.

(Looks the same but inspect the DOM to see the difference)

The second option is to opt-out to render the dropdown in a different place. Just pass renderInPlace=true and the dropdown will be placed next to the trigger element in the DOM.

(Looks the same but inspect the DOM to see the difference)

When the component is not rendered in place the dropdown can be configured to be added below or above the trigger using the verticalPosition option. The possible values are below, above and auto (the default).

The auto mode will detect the best strategy based on the available space around the component and also will take care of repositioning it when you scroll or change the orientation of the device so you will rarely need to worry about this option.

(This list of options will always be on top regardless of how much available space there is around)

The empty state

What happens when the collection you pass to the component is empty? By default the component will render a helpful message. This message is the same that will appear after performing a search when there are no matching results.

You can pass a different message using noMatchesMessage="My message"

Or you can just use the {{else}} block to just customize a totally different HTML content just like the {{each}} helper.

The loading state

In the first chapter we mentioned that the options of this component can be any collection, including Ember-data collections resulting from store.find, store.query, asynchronous relationships and just plain old promises that resolve to a collection of some sort.

That means that while the promise doesn't resolve you are in some kind of loading state where you don't have options yet (but you will have results) so you don't want to show the "No results" messages.

The component will show a default message but you can also customize passing loadingMessage="Some text"

Default loading message

Custom loading message (press the Refresh Collection button and open this select)

Disabling specific options or groups

In The trigger we saw how to disable the entire component, but you can also disable specific options. Options that have a disabled property set to true will automatically be considered disabled and styled as such.

Note that those disabled items, although displayed in the list, do not react to mouse events nor can be highlighted using arrow navigation.

This also works with groups. If a group has a property disabled: true, all options inside that group, including nested groups are considered disabled, without having to mark every option as disabled.

You might have noticed that there is a part of the dropdown that wasn't mentioned in this chapter: The search. This is because it deserves an entire chapter of its own.

Prevent click propagation inside the list

The options inside the list are selected with mousedown, a good way to prevent the selection is intercepting onmouseup and calling stopPropagation on the element "e.stopPropagation()"

This is particularly useful if you want to add some kind of link or button inside the list of options and prevent the selection of the item when the user clicks on the link.