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:
data-opion-icon
- if it just a string then will create an icon with this class. If it is in the format off7:icon_name
then it will create a F7-Icons icon. If it is in the format ofmd:icon_name
then it will create a Material Icons icondata-opion-icon-ios
- same asdata-option-icon
but will apply only when iOS theme is activedata-opion-icon-md
- same asdata-option-icon
but will apply only when MD theme is activedata-opion-icon-aurora
- same asdata-option-icon
but will apply only when Aurora theme is active
For example:
<option data-option-icon="my-icon">
will produce the<i class="icon my-icon"></i>
list item icon<option data-option-icon="f7:house_fill">
will produce the<i class="icon f7-icons">house_fill</i>
list item icon<option data-option-icon="material:home">
will produce the<i class="icon material-icons">home</i>
list item icon<option data-option-icon-ios="f7:house" data-option-icon-md="material:home">
will produce:<i class="icon f7-icons">house</i>
- when iOS theme is active<i class="icon material-icons">home</i>
- when MD theme is active
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
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:
Parameter | Type | Default | Description |
---|---|---|---|
el | HTMLElement | Smart Select element. Can be useful if you already have Smart Select element in your HTML and want to create new instance using this element | |
view | object | Link to initialized View instance which is required for Smart Select to work. By default, if not specified, it will be opened in parent View. | |
valueEl | HTMLElement | Visual element where to insert selected value. If not passed then it will look for <div class=”item-after”> element | |
setValueText | boolean | true | When enabled then smart select will automaticall insert value text into specified “valueEl” in format returned by “formatValueText” |
formatValueText | function(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 | |
openIn | string | page | Defines how to open Smart Select. Can be page or popup or popover or sheet |
popupPush | boolean | false | Enables smart select popup to push view/s behind on open |
popupSwipeToClose | boolean | undefined | Enables ability to close smart select popup with swipe. When not specified it inherits app’s Popup swipeToClose parameter |
sheetPush | boolean | false | Enables smart select sheet to push view/s behind on open |
sheetSwipeToClose | boolean | undefined | Enables ability to close smart select sheet with swipe. When not specified it inherits app’s Sheet swipeToClose parameter |
pageTitle | string | Smart select page title. If not passed then it will be the <div class=”item-title”> text | |
pageBackLinkText | string | Back | Smart select Page back link text |
popupCloseLinkText | string | Close | Smart select Popup close link text |
popupTabletFullscreen | boolean | false | When enabled smart select popup will be displayed as full screen on tablets |
sheetCloseLinkText | string | Done | Smart select Sheet close link text |
searchbar | boolean object | false | Enables Searchbar on smart select page. If passed as object then it should be valid Searchbar parameters |
searchbarPlaceholder | string | Search | Searchbar placeholder text |
searchbarDisableText | string | Cancel | Searchbar “cancel” link text. Has effect only in iOS theme |
appendSearchbarNotFound | boolean string HTMLElement | false | Appends block with content that displayed when there are no Searchbar results. If specified as string then it will append:
If specified as
If |
closeOnSelect | boolean | false | If enabled then smart select will be automatically closed after user selectes any option |
virtualList | boolean | false | Enable Virtual List for smart select if your select has a lot (hundreds, thousands) of options |
virtualListHeight | number function | Virtual list item height. If number - list item height in px. If function then function should return item height. | |
scrollToSelectedItem | boolean | false | When enabled it will scroll smart select content to first selected item on open |
formColorTheme | string | Smart select page form color theme. One of the default colors | |
navbarColorTheme | string | Smart select navbar color theme. One of the default colors | |
routableModals | boolean | true | Will 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. |
url | string | select/ | Smart select page/modal URL that will be set as a current route |
cssClass | string | Additional CSS class name to be set on Smart Select container (Page, Popup, Popover or Sheet) | |
Render functions | |||
renderSearchbar | function | Function to render smart select searchbar dropdown, must return searchbar HTML string | |
renderItem | function(item, index) | Function to render smart select item, must return item HTML string | |
renderItems | function(items) | Function to render all smart select items, must return all items HTML string | |
renderPage | function(items) | Function to render smart select page, must return full page HTML string | |
renderPopup | function(items) | Function to render smart select popup, must return full popup HTML string | |
renderSheet | function(items) | Function to render smart select sheet, must return full sheet HTML string | |
renderPopover | function(items) | Function to render smart select popover, must return full popover HTML string | |
Events | |||
on | object | Object with events handlers. For example:
|
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.app | Link to global app instance |
smartSelect.el | Smart select HTML element |
smartSelect.$el | Dom7 instance with smart select HTML element |
smartSelect.valueEl | HTML element used to display value |
smartSelect.$valueEl | Dom7 instance with HTML element used to display value |
smartSelect.selectEl | Child select element <select> |
smartSelect.$selectEl | Dom7 instance with child select element |
smartSelect.url | Smart Select URL (that was passed in url parameter) |
smartSelect.view | Smart Select View (that was passed in view parameter) or found parent view |
smartSelect.params | Smart 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
Event | Target | Description |
---|---|---|
smartselect:beforeopen | Smart 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:open | Smart Select Element<a class=”item-link smart-select”> | Event will be triggered when Smart Select page (or modal) starts its opening animation |
smartselect:opened | Smart Select Element<a class=”item-link smart-select”> | Event will be triggered after Smart Select page (or modal) completes its opening animation |
smartselect:close | Smart Select Element<a class=”item-link smart-select”> | Event will be triggered when Smart Select page (or modal) starts its closing animation |
smartselect:closed | Smart Select Element<a class=”item-link smart-select”> | Event will be triggered after Smart Select page (or modal) completes its closing animation |
smartselect:beforedestroy | Smart 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
.
Event | Target | Arguments | Description |
---|---|---|---|
beforeOpen | smartSelect | (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 |
smartSelectBeforeOpen | app | ||
open | smartSelect | (smartSelect, prevent) | Event will be triggered when Smart Select starts its opening animation. As an argument event handler receives smart select instance |
smartSelectOpen | app | ||
opened | smartSelect | (smartSelect) | Event will be triggered after Smart Select completes its opening animation. As an argument event handler receives smart select instance |
smartSelectOpened | app | ||
close | smartSelect | (smartSelect) | Event will be triggered when Smart Select starts its closing animation. As an argument event handler receives smart select instance |
smartSelectClose | app | ||
closed | smartSelect | (smartSelect) | Event will be triggered after Smart Select completes its closing animation. As an argument event handler receives smart select instance |
smartSelectClosed | app | ||
beforeDestroy | smartSelect | (smartSelect) | Event will be triggered right before Smart Select instance will be destroyed. As an argument event handler receives smart select instance |
smartSelectBeforeDestroy | app |
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
<!-- Default Setup -->
<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>
<!-- Open In Popup + Searchbar + Multiple -->
<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>
<!-- Open In Sheet -->
<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>
<!-- Open In Popover -->
<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>