A preference page is used within a preferences block to define a page which the user interacts with your app. The preferences
block can contain one or more pages
.
If you are new to Hubitat app development, start with App Overview to see how preferences and pages are used.
Example:
preferences {
page(name: "mainPage", title: "Title", install: true, uninstall: true) {
section("") {
}
}
}
These named arguments are available for page()
, and at least a name and title are typically provided, though all are optional:
name
- (identifier string) The name of the page, within code.title
- (HTML string) The display text at the top of the page.install
- (boolean) controls display of the Install button on this page (if the app is newly added)uninstall
- (boolean) controls display of the Remove (app name) button on this pagenextPage
- (string) for multi-page apps, replaces Done with Next and directs user to specified page namesection("title")
- Provides a visual separation of controls separated by the provided title. This is the most commonly used signature.
section {}
section("Title") {}
section(Boolean hideable, "Title") {}
hideable
: determines if section is "collapsible" by selecting headingsection(Boolean hideable, Boolean hidden, "Title") {}
hideable
: determines if section is "collapsible" by selecting heading (true
means can be collapsed)hidden
: if hideable, determines if is collapsed or expanded by default (true
means collapsed)input
- Renders a user input widget (of specified name, type, etc.); see below for more details.paragraph
- Renders the specified text (or HTML string); see below for more details.href
- Renders a link to another app page or URL; see below for more details.label
- Renders a text input for the user to provide a display name for your app (can also be set by code with app.updateLabel()
)Explanation for parameters on input
are provided below.
Options for type
on input
are:
capability.capabilityName
: provides a way for the user to select a device of the specified capability (obtains reference to DeviceWrapper object)device.DriverName
: provides a way for the user to select a device using the specified driver name (matched by driver name with spaces removed). Selecting by capability instead is generally recommended.text
: Stringtextarea
: String (from a multi-line re-sizable text box; parameter rows
is optional, for number of rows, with 2 the default)number
: an integer number (Long
)decimal
: a floating point number (Double
)enum
: List; presents a drop-down list of options; requires a parameter options
of type List
with optionsbool
: a Boolean
; in the UI, this is an on/off slider.time
: dateTime String (formatted "yyyy-MM-dd'T'HH:mm:ss.sssXX"); this pulls up a time picker.date
: date String; this pulls up a date picker.color
: color Map; this pulls up a color picker.button
: renders a UI button with the title in the button; generates a callback to a method defined in the app called appButtonHandler(String buttonName)
, which is passed the String name of the input when the UI button is pressed, which also causes a page refresh. (As a callback, the appButtonHandler
method is not called within the page where the button is rendered, so it cannot render anything itself, but can only set state to be dealt with by the page method upon its refresh.)input
optionsThe options
of an enum
can be either:
List
of options; orList
of Maps
(all keys and values will be interpreted as a String
), where the key of the map element is saved as the value of the selection while the value for that key is displayed in the pull-down menu.For device (capability or driver) and enum
inputs, an optional parameter of multiple: true
is allowed, and the setting value will be stored as a List
rather than a single element
For enum
inputs, an offerAll
(values true
or false
) parameter is optional and allows to hide/or show an option to select all choices
A defaultValue: value
can be specified for an input, which will display in the UI on load but will not be saved to the corresponding setting until the page is refreshed or saved (like other inputs).
There is rudimentary formatting available for inputs, including width: number
, where the width can be 1 to 12, with 12 being the full width for a desktop screen, and 4 for a mobile device screen.
The submitOnChange: true
parameter the page to be refreshed upon completion of (selection away from) the input by the user. This is often used for inputs in dynamic pages because it allows for the progression of the UI as the user interacts with the app.
Adding required: true
forces an input to be completed before leaving the page.
Buttons can use disabled: true
or disabled: false
to enable/disable button
String or numeric inputs can use noAutoComplete: false
to prevent browser auto-complete suggestions
Inputs of type: "capability"
can use the showFilter: true
parameter (default is false
) to show a search box above the list of devices, allowing the user to filter the list of devices (may be useful if the list is likely to be large)
The paragraph(String paragraphText)
method will display text output (rather than a field for user input) in the app. This may include HTML to create tables, or other presentation elements. It is also possible to use limited JavaScript in the paragraph text, though this is not necessary for most apps. This is used in the example app above to display text:
paragraph "Hello, world!"`
It possible to link to other app pages using href()
, and it is possible to pass parameters to those other pages. Parameters for href()
include:
name
: String
, name of this href
(should be unique)page
: String
, the name
of the page
to link toparams
: Map
, optional; a Map
of values that can be passed to the other pagetitle
: String
, title/heading for this href
description
: String
; additional text to display on this href
state
: String
, set to "complete"
to show in blue text, often indicating completion; or null
to show in gray (default)Example:
href name: "myHref", page: "MyOtherPage", title: "Go to other page!"
A rarely used alternate set of parameters allows specifying url
instead of page
, which will direct the user's browser to the specified URL. Use of url
allows use of an additional optional parameter style
, with possible values "internal"
(URL opens in same window/tab) or "external"
(URL opens in pop-up window).
Used in parent app to display child apps or allow creation of a new child app (see Parent/Child Apps). Parameters:
name
: name of this input (should be unique, but unlike others, you normally don't need to refer to this one)appName
: the name of the child app (as specified in its definition
)namespace
: the namespace of the child app (as specified in its definition
)title
: text to display on the link/button the user can select to add a new child appmultiple': if
true, allows multiple child apps to be installed (default is
false`, i.e., single child only)Example:
app name: "myChildApps", appName: "My Child App", namespace: "My Namespace",
title: "Create New Child App", multiple: true
For more control over page content, you may wish to use dynamicPage
instead of page
. These pages are defined by returning a page from a Groovy method rather than defining them inside preferences
. They also allow passing parameters to the page by passing a parameter to this method, ultimately providing more control over page contents that some apps may require.
Sections, inputs, etc. available in dynamic pages are the same as those in regular pages, above.
For an example of dynamic pages, see: Building a Multi-Page App.
For apps with only a single preferences page, the page
block can be omitted entirely and replaced directly with one or more section
blocks. (The example above is a single-page app, though it included page
for the sake of a complete demonstration.) This can be a handy shortcut when writing small apps.
If page
is omitted, two default features are provided for you:
an input for the user to provide a "label," or name, for your app (this will default to the app name specified in your definition
but allows the user to change it) — e.g., how the app appears in the Apps list
an input for the user to select "only in certain mode(s)" as a means to restrict execution of your app when outside the selected mode(s); selecting no modes will run in all modes
Apps that explicitly define one or more pages will not automatically have these features added, but developers can implement similar features manually if it makes sense for the app.