Smart Select

Smart select allows you to easily convert your usual form selects to dynamic pages with grouped radio or checkbox inputs. You can see such feature in many native iOS apps

Smart Select Layout

Smart select layout is pretty simple. It is a well known List View link with <select> inside and additional smart-select class on item-link:

<div class="list">
  <ul>
    <!-- Smart select item -->
    <li>
      <!-- Additional "smart-select" class -->
      <a href="#" class="item-link smart-select">
        <!-- select -->
        <select name="fruits">
          <option value="apple" selected>Apple</option>
          <option value="pineapple">Pineapple</option>
          ...
        </select>
        <div class="item-content">
          <div class="item-inner">
            <!-- Select label -->
            <div class="item-title">Fruit</div>
            <!-- Selected value, not required -->
            <div class="item-after">Apple</div>
          </div>
        </div>
      </a>
    </li>
    <!-- Another smart selects or list view elements -->
    ...
  </ul>
</div>

Note that smart select works only in initialized Views, because it used Router to load smart select pages or open modals!

Custom Option Icons

We can specify Smart Select page' list view (option) icons by using data-option-icon attributes on <option> elements:

For example:

Custom Option Colors and Images

We can also specify Smart Select page' list view element image or color. We need to use additional data-option-image attributes on smart select <select> (to set default image for all options) or on <option> to set image or icon on single option.

For single option we may also use data-option-color and data-option-class attributes to add specific option color or css class for additional styling

<li>
  <a href="#" class="item-link smart-select">
    <select name="fruits">
      <option value="apple" selected data-option-image="https://cdn.framework7.io/placeholder/abstract-29x29-1.jpg">Apple</option>
      <option value="pineapple" data-option-image="https://cdn.framework7.io/placeholder/abstract-29x29-2.jpg">Pineapple</option>
      <option value="pear" data-option-color="orange" data-option-image="https://cdn.framework7.io/placeholder/abstract-29x29-3.jpg">Pear</option>
      ...
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Fruit</div>
      </div>
    </div>
  </a>
</li>

Multiple Select And <optgroup>

We can also use multiple select and group options using <optgroup>. So if we add multiple attribute to our select then radio buttons on smart select page will be automatically converted to checkboxes:

<li>
  <a href="#" class="item-link smart-select">
    <!-- "multiple" attribute for multiple select-->
    <select name="car" multiple>
      <!-- options grouped within "optgroup" tag-->
      <optgroup label="Japanese">
        <option value="honda" selected>Honda</option>
        <option value="lexus">Lexus</option>
        ...
      </optgroup>
      <optgroup label="German">
        <option value="audi" selected>Audi</option>
        <option value="bmw">BMW</option>
        ...
      </optgroup>
      <optgroup label="American">
        <option value="cadillac">Cadillac</option>
        <option value="chrysler">Chrysler</option>
        ...
      </optgroup>
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Car</div>
      </div>
    </div>
  </a>
</li>

Multiple Select and maxlength

With multiple select we can also use maxlength attribute to limit number of possible selected items:

<li>
  <a href="#" class="item-link smart-select">
    <!-- "maxlength" attribute to limit number of possible selected items -->
    <!-- we won't allow to select more than 3 items -->
    <select name="car" multiple maxlength="3">
      <optgroup label="Japanese">
        <option value="honda" selected>Honda</option>
        <option value="lexus">Lexus</option>
        ...
      </optgroup>
      <optgroup label="German">
        <option value="audi">Audi</option>
        <option value="bmw">BMW</option>
        ...
      </optgroup>
      <optgroup label="American">
        <option value="cadillac">Cadillac</option>
        <option value="chrysler">Chrysler</option>
        ...
      </optgroup>
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Car</div>
      </div>
    </div>
  </a>
</li>

Different Display Value

Using data-display-as attribute on options we can show selected value in different way:

<li>
  <a href="#" class="item-link smart-select">
    <select name="days">
      <option value="monday" selected data-display-as="Mon">Monday</option>
      <option value="tuesday" data-display-as="Tue">Tuesday</option>
      <option value="wednesday" data-display-as="Wed">Wednesday</option>
      <option value="thursday" data-display-as="Thu">Thursday</option>
      <option value="friday" data-display-as="Fri">Friday</option>
      <option value="saturday" data-display-as="Sat">Saturday</option>
      <option value="sunday" data-display-as="Sun">Sunday</option>
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Day</div>
      </div>
    </div>
  </a>
</li>

Smart Select App Methods

Let's look at related App methods to work with Smart Select:

app.smartSelect.create(parameters)- create Smart Select instance

  • parameters - object. Object with smart select parameters

Method returns created Smart Select's instance

app.smartSelect.destroy(smartSelectEl)- destroy Smart Select instance

  • smartSelectEl - HTMLElement or string (with CSS Selector) or object. Smart Select element or Smart Select instance to destroy.

app.smartSelect.get(smartSelectEl)- get Smart Select instance by HTML element

  • smartSelectEl - HTMLElement or string (with CSS Selector). Smart Select element.

Method returns Smart Select's instance

app.smartSelect.open(smartSelectEl)- opens Smart Select

  • smartSelectEl - HTMLElement or string (with CSS Selector). Smart Select element to open.

Method returns Smart Select's instance

app.smartSelect.close(smartSelectEl)- closes Smart Select

  • smartSelectEl - HTMLElement or string (with CSS Selector). Smart Select element to close.

Method returns Smart Select's instance

Smart Select Parameters

Now let's look at list of available parameters we need to create Smart Select:

ParameterTypeDefaultDescription
elHTMLElementSmart Select element. Can be useful if you already have Smart Select element in your HTML and want to create new instance using this element
viewobjectLink to initialized View instance which is required for Smart Select to work. By default, if not specified, it will be opened in parent View.
valueElHTMLElementVisual element where to insert selected value. If not passed then it will look for <div class="item-after"> element
setValueTextbooleantrueWhen enabled then smart select will automatically insert value text into specified "valueEl" in format returned by "formatValueText"
formatValueTextfunction(values)Custom function to format smart select text value that appears on list item (in <div class="item-after">). values is the array of current values
openInstringpageDefines how to open Smart Select. Can be page or popup or popover or sheet
popupPushbooleanfalseEnables smart select popup to push view/s behind on open
popupSwipeToClosebooleanundefinedEnables ability to close smart select popup with swipe. When not specified it inherits app's Popup swipeToClose parameter
sheetPushbooleanfalseEnables smart select sheet to push view/s behind on open
sheetSwipeToClosebooleanundefinedEnables ability to close smart select sheet with swipe. When not specified it inherits app's Sheet swipeToClose parameter
sheetBackdropbooleanfalseEnables smart select sheet backdrop
pageTitlestringSmart select page title. If not passed then it will be the <div class="item-title"> text
pageBackLinkTextstringBackSmart select Page back link text
popupCloseLinkTextstringCloseSmart select Popup close link text
popupTabletFullscreenbooleanfalseWhen enabled smart select popup will be displayed as full screen on tablets
sheetCloseLinkTextstringDoneSmart select Sheet close link text
searchbarboolean
object
falseEnables Searchbar on smart select page. If passed as object then it should be valid Searchbar parameters
searchbarPlaceholderstringSearchSearchbar placeholder text
searchbarDisableTextstringCancelSearchbar "cancel" link text. Has effect only in iOS theme
searchbarSpellcheckbooleanfalseSets value of spellcheck attribute on Searchbar's input element
appendSearchbarNotFoundboolean
string
HTMLElement
falseAppends block with content that displayed when there are no Searchbar results.

If specified as string then it will append:

<div class="block searchbar-not-found">{{appendSearchbarNotFound}}</div>

If specified as true then:

<div class="block searchbar-not-found">Nothing found</div>

If HTMLElement passed then it will add that element.

closeOnSelectbooleanfalseIf enabled then smart select will be automatically closed after user selectes any option
virtualListbooleanfalseEnable Virtual List for smart select if your select has a lot (hundreds, thousands) of options
virtualListHeightnumber
function
Virtual list item height. If number - list item height in px. If function then function should return item height.
scrollToSelectedItembooleanfalseWhen enabled it will scroll smart select content to first selected item on open
formColorThemestringSmart select page form color theme. One of the default colors
navbarColorThemestringSmart select navbar color theme. One of the default colors
routableModalsbooleanfalseWill add opened smart select modal (when openIn is popup, popover or sheet) to router history which gives ability to close smart select by going back in router history and set current route to the smart select modal.
urlstringselect/Smart select page/modal URL that will be set as a current route
cssClassstringAdditional CSS class name to be set on Smart Select container (Page, Popup, Popover or Sheet)
closeByBackdropClickbooleantrueWhen enabled, Smart Select modal (Popover, Popup, Sheet) will be closed on backdrop click
inputIconPositionstring'start'Select option checkbox or radio icon position. Can be 'start' or 'end'. Also can be set on each option via data-input-icon-position attribute
optionIconstringSelect option icon to be set on all options. If it just a string then will create an icon with this class. If it is in the format of f7:icon_name then it will create a F7-Icons icon. If it is in the format of md:icon_name then it will create a Material Icons icon
optionIconIosstringSame as optionIcon but will apply only when iOS theme is active
optionIconMdstringSame as optionIcon but will apply only when MD theme is active
Render functions
renderSearchbarfunctionFunction to render smart select searchbar dropdown, must return searchbar HTML string
renderItemfunction(item, index)Function to render smart select item, must return item HTML string
renderItemsfunction(items)Function to render all smart select items, must return all items HTML string
renderPagefunction(items)Function to render smart select page, must return full page HTML string
renderPopupfunction(items)Function to render smart select popup, must return full popup HTML string
renderSheetfunction(items)Function to render smart select sheet, must return full sheet HTML string
renderPopoverfunction(items)Function to render smart select popover, must return full popover HTML string
Events
onobject

Object with events handlers. For example:

var smartSelect = app.smartSelect.create({
  ...
  on: {
    opened: function () {
      console.log('Smart select opened')
    }
  }
})

Note that all following parameters can be used in global app parameters under smartSelect property to set defaults for all smart selects. For example:

var app = new Framework7({
  smartSelect: {
    pageTitle: 'Select Option',
    openIn: 'popup',
  }
});

Smart Select Methods & Properties

So to create Smart Select we have to call:

var smartSelect = app.smartSelect.create({ /* parameters */ })

After that we have its initialized instance (like smartSelect variable in example above) with useful methods and properties:

Properties
smartSelect.appLink to global app instance
smartSelect.elSmart select HTML element
smartSelect.$elDom7 instance with smart select HTML element
smartSelect.valueElHTML element used to display value
smartSelect.$valueElDom7 instance with HTML element used to display value
smartSelect.selectElChild select element <select>
smartSelect.$selectElDom7 instance with child select element
smartSelect.urlSmart Select URL (that was passed in url parameter)
smartSelect.viewSmart Select View (that was passed in view parameter) or found parent view
smartSelect.paramsSmart Select parameters
Methods
smartSelect.open()Open smart select
smartSelect.close()Close smart select
smartSelect.getValue()Returns smart select value. In case of select is multiple it returns array with selected values
smartSelect.setValue(newValue)Set new smart select value. In case of select is multiple it must be an array with new values
smartSelect.unsetValue()Unset smart select value
smartSelect.scrollToSelectedItem()Scroll smart select content to first selected item (when opened)
smartSelect.destroy()Destroy smart select
smartSelect.on(event, handler)Add event handler
smartSelect.once(event, handler)Add event handler that will be removed after it was fired
smartSelect.off(event, handler)Remove event handler
smartSelect.off(event)Remove all handlers for specified event
smartSelect.emit(event, ...args)Fire event on instance

Smart Select Events

Smart Select will fire the following DOM events on smart select element and events on app and smart select instance:

DOM Events

EventTargetDescription
smartselect:beforeopenSmart Select Element<a class="item-link smart-select">Event will be triggered before Smart Select open. event.detail.prevent contains function that will prevent Smart Select from opening when called
smartselect:openSmart Select Element<a class="item-link smart-select">Event will be triggered when Smart Select page (or modal) starts its opening animation
smartselect:openedSmart Select Element<a class="item-link smart-select">Event will be triggered after Smart Select page (or modal) completes its opening animation
smartselect:closeSmart Select Element<a class="item-link smart-select">Event will be triggered when Smart Select page (or modal) starts its closing animation
smartselect:closedSmart Select Element<a class="item-link smart-select">Event will be triggered after Smart Select page (or modal) completes its closing animation
smartselect:beforedestroySmart Select Element<a class="item-link smart-select">Event will be triggered right before Smart Select instance will be destroyed

App and Smart Select Instance Events

Smart Select instance emits events on both self instance and app instance. App instance events has same names prefixed with smartSelect.

EventTargetArgumentsDescription
beforeOpensmartSelect(smartSelect, prevent)Event will be triggered before Smart Select open. As an argument event handler receives smart select instance and function that will prevent Smart Select from opening when called
smartSelectBeforeOpenapp
opensmartSelect(smartSelect)Event will be triggered when Smart Select starts its opening animation. As an argument event handler receives smart select instance
smartSelectOpenapp
openedsmartSelect(smartSelect)Event will be triggered after Smart Select completes its opening animation. As an argument event handler receives smart select instance
smartSelectOpenedapp
closesmartSelect(smartSelect)Event will be triggered when Smart Select starts its closing animation. As an argument event handler receives smart select instance
smartSelectCloseapp
closedsmartSelect(smartSelect)Event will be triggered after Smart Select completes its closing animation. As an argument event handler receives smart select instance
smartSelectClosedapp
beforeDestroysmartSelect(smartSelect)Event will be triggered right before Smart Select instance will be destroyed. As an argument event handler receives smart select instance
smartSelectBeforeDestroyapp

Smart Select Auto Initialization

If you don't need to use Smart Select API and your Smart Select is inside of the page and presented in DOM on moment of page initialization then it can be auto initialized with just adding additional smart-select-init class:

<li>
  <!-- Add smart-select-init class -->
  <a href="#" class="item-link smart-select smart-select-init">
    <!-- select -->
    <select name="fruits">
      <option value="apple" selected>Apple</option>
      <option value="pineapple">Pineapple</option>
      ...
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Fruit</div>
        <div class="item-after">Apple</div>
      </div>
    </div>
  </a>
</li>

In this case if you need to access created Smart Select instance you can use the app.smartSelect.get app method:

var smartSelect = app.smartSelect.get('.smart-select');

When using auto init you may need to pass additional parameters. In this case you may pass all additional parameters via data- attributes on smart select element:

<li>
  <!-- Pass parameters as kebab-case data attributes -->
  <a href="#" class="item-link smart-select smart-select-init" data-open-in="popup" data-virtual-list="true" data-page-back-link-text="Go back">
    <!-- select -->
    <select name="fruits">
      <option value="apple" selected>Apple</option>
      <option value="pineapple">Pineapple</option>
      ...
    </select>
    <div class="item-content">
      <div class="item-inner">
        <div class="item-title">Fruit</div>
        <div class="item-after">Apple</div>
      </div>
    </div>
  </a>
</li>

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

Note that commented variables are not specified by default and their values is what they fallback to in this case.

:root {
  /*
  --f7-smart-select-sheet-bg: var(--f7-list-bg-color);
  --f7-smart-select-sheet-toolbar-border-color: var(--f7-bars-border-color);
  */
}

Examples

smart-select.html
<div class="page">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner sliding">
      <div class="title">Smart Select</div>
    </div>
  </div>
  <div class="page-content">
    <div class="block">
      Framework7 allows you to easily convert your usual form selects to dynamic pages with radios:
    </div>
    <div class="list list-strong-ios list-outline-ios list-dividers-ios">
      <ul>
        <li>
          <a class="item-link smart-select smart-select-init">
            <select name="fruits">
              <option value="apple" selected>Apple</option>
              <option value="pineapple">Pineapple</option>
              <option value="pear">Pear</option>
              <option value="orange">Orange</option>
              <option value="melon">Melon</option>
              <option value="peach">Peach</option>
              <option value="banana">Banana</option>
            </select>
            <div class="item-content">
              <div class="item-inner">
                <div class="item-title">Fruit</div>
              </div>
            </div>
          </a>
        </li>
        <li>
          <a class="item-link smart-select smart-select-init" data-open-in="popup" data-searchbar="true"
            data-searchbar-placeholder="Search car">
            <select name="car" multiple>
              <optgroup label="Japanese">
                <option value="honda" selected>Honda</option>
                <option value="lexus">Lexus</option>
                <option value="mazda">Mazda</option>
                <option value="nissan">Nissan</option>
                <option value="toyota">Toyota</option>
              </optgroup>
              <optgroup label="German">
                <option value="audi" selected>Audi</option>
                <option value="bmw">BMW</option>
                <option value="mercedes">Mercedes</option>
                <option value="vw">Volkswagen</option>
                <option value="volvo">Volvo</option>
              </optgroup>
              <optgroup label="American">
                <option value="cadillac">Cadillac</option>
                <option value="chrysler">Chrysler</option>
                <option value="dodge">Dodge</option>
                <option value="ford" selected>Ford</option>
              </optgroup>
            </select>
            <div class="item-content">
              <div class="item-inner">
                <div class="item-title">Car</div>
              </div>
            </div>
          </a>
        </li>
        <li>
          <a class="item-link smart-select smart-select-init" data-open-in="sheet">
            <select name="mac-windows">
              <option value="mac" selected>Mac</option>
              <option value="windows">Windows</option>
            </select>
            <div class="item-content">
              <div class="item-inner">
                <div class="item-title">Mac or Windows</div>
              </div>
            </div>
          </a>
        </li>
        <li>
          <a class="item-link smart-select smart-select-init" data-open-in="popover">
            <select name="superhero" multiple>
              <option value="Batman" selected>Batman</option>
              <option value="Superman">Superman</option>
              <option value="Hulk">Hulk</option>
              <option value="Spiderman">Spiderman</option>
              <option value="Ironman">Ironman</option>
              <option value="Thor">Thor</option>
              <option value="Wonder Woman">Wonder Woman</option>
            </select>
            <div class="item-content">
              <div class="item-inner">
                <div class="item-title">Super Hero</div>
              </div>
            </div>
          </a>
        </li>
      </ul>
    </div>
  </div>
</div>