App Preferences
For developers: how to define preferences and preference pages in app
App Preferences/Pages
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("") {
}
}
}
Pages
Arguments
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 name
Block Methods
section("title")- Provides a visual separation of controls separated by the provided title. This is the most commonly used signature.- All sigantures:
section {}section("Title") {}section(Boolean hideable, "Title") {}hideable: determines if section is "collapsible" by selecting heading
section(Boolean hideable, Boolean hidden, "Title") {}hideable: determines if section is "collapsible" by selecting heading (truemeans can be collapsed)hidden: if hideable, determines if is collapsed or expanded by default (truemeans collapsed)
- All sigantures:
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 withapp.updateLabel())
Input
Explanation for parameters on input are provided below.
type
Options for type on input are:
"capability.capabilityName": provides a way for the user to select a device of the specified capability (value is a DeviceWrapper object, or a List of DeviceWrapper objects if multiple selection is enabled)"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": String"textarea": String (from a multi-line re-sizable text box; parameterrowsis 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 parameteroptionsof typeListwith options"bool": aBooleanvalue; in the UI, this is an on/off slider."time": dateTime String (formatted "yyyy-MM-dd'T'HH:mm:ss.sssXX"); in the app user interface, this displays as a time picker"date": date String; in the app user interface, this shows as a date picker"color": color Map; in the app user interface, this shows as a color picker."password": similar to"text"but masks the input value in the app user interface and app status page"button": renders a UI button with the title in the button; generates a callback to a method defined in the app calledappButtonHandler(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, theappButtonHandlermethod 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.)
Other input options
-
The
optionsof anenumcan be either:- a
Listof options; or - a
ListofMaps(all keys and values will be interpreted as aString), 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.
- a
-
For device (capability or driver) and
enuminputs, an optional parameter ofmultiple: trueis allowed, and the setting value will be stored as aListrather than a single element -
For
enuminputs, anofferAll(valuestrueorfalse) parameter is optional and allows to hide/or show an option to select all choices -
A
defaultValue: valuecan 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: trueparameter 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: trueforces an input to be completed before leaving the page. -
Buttons can use
disabled: trueordisabled: falseto enable/disable button -
String or numeric inputs can use
noAutoComplete: falseto prevent browser auto-complete suggestions -
Inputs of
type: "capability"can use theshowFilter: trueparameter (default isfalse) 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)
Paragraph
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!"`
href
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 thishref(should be unique)page:String, thenameof thepageto link toparams:Map, optional; aMapof values that can be passed to the other pagetitle:String, title/heading for thishrefdescription:String; additional text to display on thishrefstate:String, set to"complete"to show in blue text, often indicating completion; ornullto 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).
app
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 itsdefinition)namespace: the namespace of the child app (as specified in itsdefinition)title: text to display on the link/button the user can select to add a new child appmultiple': iftrue, allows multiple child apps to be installed (default isfalse`, i.e., single child only)
Example:
app name: "myChildApps", appName: "My Child App", namespace: "My Namespace",
title: "Create New Child App", multiple: true
Dynamic Pages
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.
Single-Page Apps
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
definitionbut 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.