mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-08 05:31:56 +00:00
Merge pull request #366 from vlaminck/every-element-update
Updated the every element app to better represent what each element can and can't do
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Every Element
|
||||
*
|
||||
* Copyright 2014 SmartThings
|
||||
* Copyright 2015 SmartThings
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at:
|
||||
@@ -14,349 +14,555 @@
|
||||
*
|
||||
*/
|
||||
definition(
|
||||
name: "Every Element",
|
||||
namespace: "smartthings/examples",
|
||||
author: "SmartThings",
|
||||
description: "Every element demonstration app",
|
||||
category: "SmartThings Internal",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
|
||||
name: "Every Element",
|
||||
namespace: "smartthings/examples",
|
||||
author: "SmartThings",
|
||||
description: "Every element demonstration app",
|
||||
category: "SmartThings Internal",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
|
||||
)
|
||||
|
||||
preferences {
|
||||
page(name: "firstPage")
|
||||
page(name: "inputPage")
|
||||
page(name: "appPage")
|
||||
page(name: "labelPage")
|
||||
page(name: "modePage")
|
||||
page(name: "paragraphPage")
|
||||
page(name: "iconPage")
|
||||
page(name: "hrefPage")
|
||||
page(name: "buttonsPage")
|
||||
page(name: "imagePage")
|
||||
page(name: "videoPage")
|
||||
page(name: "deadEnd", title: "Nothing to see here, move along.", content: "foo")
|
||||
page(name: "flattenedPage")
|
||||
// landing page
|
||||
page(name: "firstPage")
|
||||
|
||||
// PageKit
|
||||
page(name: "buttonsPage")
|
||||
page(name: "imagePage")
|
||||
page(name: "inputPage")
|
||||
page(name: "inputBooleanPage")
|
||||
page(name: "inputIconPage")
|
||||
page(name: "inputImagePage")
|
||||
page(name: "inputDevicePage")
|
||||
page(name: "inputCapabilityPage")
|
||||
page(name: "inputRoomPage")
|
||||
page(name: "inputModePage")
|
||||
page(name: "inputSelectionPage")
|
||||
page(name: "inputHubPage")
|
||||
page(name: "inputContactBookPage")
|
||||
page(name: "inputTextPage")
|
||||
page(name: "inputTimePage")
|
||||
page(name: "appPage")
|
||||
page(name: "hrefPage")
|
||||
page(name: "paragraphPage")
|
||||
page(name: "videoPage")
|
||||
page(name: "labelPage")
|
||||
page(name: "modePage")
|
||||
|
||||
// Every element helper pages
|
||||
page(name: "deadEnd", title: "Nothing to see here, move along.", content: "foo")
|
||||
page(name: "flattenedPage")
|
||||
}
|
||||
|
||||
def firstPage() {
|
||||
dynamicPage(name: "firstPage", title: "Where to first?", install: true, uninstall: true) {
|
||||
section() {
|
||||
href(page: "inputPage", title: "Element: 'input'")
|
||||
href(page: "appPage", title: "Element: 'app'")
|
||||
href(page: "labelPage", title: "Element: 'label'")
|
||||
href(page: "modePage", title: "Element: 'mode'")
|
||||
href(page: "paragraphPage", title: "Element: 'paragraph'")
|
||||
href(page: "iconPage", title: "Element: 'icon'")
|
||||
href(page: "hrefPage", title: "Element: 'href'")
|
||||
href(page: "buttonsPage", title: "Element: 'buttons'")
|
||||
href(page: "imagePage", title: "Element: 'image'")
|
||||
href(page: "videoPage", title: "Element: 'video'")
|
||||
}
|
||||
section() {
|
||||
href(page: "flattenedPage", title: "All of the above elements on a single page")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "firstPage", title: "Where to first?", install: true, uninstall: true) {
|
||||
section {
|
||||
href(page: "appPage", title: "Element: 'app'")
|
||||
href(page: "buttonsPage", title: "Element: 'buttons'")
|
||||
href(page: "hrefPage", title: "Element: 'href'")
|
||||
href(page: "imagePage", title: "Element: 'image'")
|
||||
href(page: "inputPage", title: "Element: 'input'")
|
||||
href(page: "labelPage", title: "Element: 'label'")
|
||||
href(page: "modePage", title: "Element: 'mode'")
|
||||
href(page: "paragraphPage", title: "Element: 'paragraph'")
|
||||
href(page: "videoPage", title: "Element: 'video'")
|
||||
}
|
||||
section {
|
||||
href(page: "flattenedPage", title: "All of the above elements on a single page")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def inputPage() {
|
||||
dynamicPage(name: "inputPage", title: "Every 'input' type") {
|
||||
section("enum") {
|
||||
input(type: "enum", name: "enumRefresh", title: "submitOnChange:true", required: false, multiple: true, options: ["one", "two", "three"], submitOnChange: true)
|
||||
if (enumRefresh) {
|
||||
paragraph "${enumRefresh}"
|
||||
}
|
||||
input(type: "enum", name: "enumSegmented", title: "style:segmented", required: false, multiple: true, options: ["one", "two", "three"], style: "segmented")
|
||||
input(type: "enum", name: "enum", title: "required:false, multiple:false", required: false, multiple: false, options: ["one", "two", "three"])
|
||||
input(type: "enum", name: "enumRequired", title: "required:true", required: true, multiple: false, options: ["one", "two", "three"])
|
||||
input(type: "enum", name: "enumMultiple", title: "multiple:true", required: false, multiple: true, options: ["one", "two", "three"])
|
||||
input(type: "enum", name: "enumWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, options: ["one", "two", "three"], image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
input(type: "enum", name: "enumWithGroupedOptions", title: "groupedOptions", description: "This enum has grouped options", required: false, multiple: true, groupedOptions: [
|
||||
[
|
||||
title : "the group title that is displayed",
|
||||
order : 0, // the order of the group; 0-based
|
||||
image : "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", // not yet supported
|
||||
values: [
|
||||
[
|
||||
key : "the value that will be placed in SmartApp settings.", // such as a device id
|
||||
value: "the title of the selectable option that is displayed", // such as a device name
|
||||
order: 0 // the order of the option
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
title : "the second group title that is displayed",
|
||||
order : 1, // the order of the group; 0-based
|
||||
image : null, // not yet supported
|
||||
values: [
|
||||
[
|
||||
key : "some_device_id",
|
||||
value: "some_device_name",
|
||||
order: 1 // the order of the option. This option will appear second in the list even though it is the first option defined in this map
|
||||
],
|
||||
[
|
||||
key : "some_other_device_id",
|
||||
value: "some_other_device_name",
|
||||
order: 0 // the order of the option. This option will appear first in the list even though it is not the first option defined in this map
|
||||
]
|
||||
]
|
||||
]
|
||||
])
|
||||
}
|
||||
section("text") {
|
||||
input(type: "text", name: "text", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "text", name: "textRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "text", name: "textWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("number") {
|
||||
input(type: "number", name: "number", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "number", name: "numberRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "number", name: "numberWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("boolean") {
|
||||
input(type: "boolean", name: "boolean", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "boolean", name: "booleanWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("password") {
|
||||
input(type: "password", name: "password", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "password", name: "passwordRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "password", name: "passwordWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("phone") {
|
||||
input(type: "phone", name: "phone", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "phone", name: "phoneRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "phone", name: "phoneWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("email") {
|
||||
input(type: "email", name: "email", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "email", name: "emailRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "email", name: "emailWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("decimal") {
|
||||
input(type: "decimal", name: "decimal", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "decimal", name: "decimalRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "decimal", name: "decimalWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("mode") {
|
||||
input(type: "mode", name: "mode", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "mode", name: "modeRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "mode", name: "modeMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
input(type: "mode", name: "iconWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("icon") {
|
||||
input(type: "icon", name: "icon", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "icon", name: "iconRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "icon", name: "iconWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("capability") {
|
||||
input(type: "capability.switch", name: "capability", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "capability.switch", name: "capabilityRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "capability.switch", name: "capabilityMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
input(type: "capability.switch", name: "capabilityWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("hub") {
|
||||
input(type: "hub", name: "hub", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "hub", name: "hubRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "hub", name: "hubMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
input(type: "hub", name: "hubWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("device") {
|
||||
input(type: "device.switch", name: "device", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "device.switch", name: "deviceRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "device.switch", name: "deviceMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
input(type: "device.switch", name: "deviceWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("time") {
|
||||
input(type: "time", name: "time", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
input(type: "time", name: "timeRequired", title: "required:true", required: true, multiple: false)
|
||||
input(type: "time", name: "timeWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
section("contact-book") {
|
||||
input("recipients", "contact", title: "Notify", description: "Send notifications to") {
|
||||
input(type: "phone", name: "phone", title: "Send text message to", required: false, multiple: false)
|
||||
input(type: "boolean", name: "boolean", title: "Send push notification", required: false, multiple: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "inputPage", title: "Links to every 'input' element") {
|
||||
section {
|
||||
href(page: "inputBooleanPage", title: "to boolean page")
|
||||
href(page: "inputIconPage", title: "to icon page")
|
||||
href(page: "inputImagePage", title: "to image page")
|
||||
href(page: "inputSelectionPage", title: "to selection page")
|
||||
href(page: "inputTextPage", title: "to text page")
|
||||
href(page: "inputTimePage", title: "to time page")
|
||||
}
|
||||
section("subsets of selection input") {
|
||||
href(page: "inputDevicePage", title: "to device selection page")
|
||||
href(page: "inputCapabilityPage", title: "to capability selection page")
|
||||
href(page: "inputRoomPage", title: "to room selection page")
|
||||
href(page: "inputModePage", title: "to mode selection page")
|
||||
href(page: "inputHubPage", title: "to hub selection page")
|
||||
href(page: "inputContactBookPage", title: "to contact-book selection page")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def inputBooleanPage() {
|
||||
dynamicPage(name: "inputBooleanPage") {
|
||||
section {
|
||||
paragraph "The `required` and `multiple` attributes have no effect because the value will always be either `true` or `false`"
|
||||
}
|
||||
section {
|
||||
input(type: "boolean", name: "booleanWithoutDescription", title: "without description", description: null)
|
||||
input(type: "boolean", name: "booleanWithDescription", title: "with description", description: "This has a description")
|
||||
}
|
||||
section("defaultValue: 'true'") {
|
||||
input(type: "boolean", name: "booleanWithDefaultValue", title: "", description: "", defaultValue: "true")
|
||||
}
|
||||
section("with image") {
|
||||
input(type: "boolean", name: "booleanWithoutDescriptionWithImage", title: "without description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", description: null)
|
||||
input(type: "boolean", name: "booleanWithDescriptionWithImage", title: "with description", description: "This has a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputIconPage() {
|
||||
dynamicPage(name: "inputIconPage") {
|
||||
section {
|
||||
paragraph "`description` is not displayed for icon elements"
|
||||
paragraph "`multiple` has no effect because you can only choose a single icon"
|
||||
}
|
||||
section("required: true") {
|
||||
input(type: "icon", name: "iconRequired", title: "without description", required: true)
|
||||
input(type: "icon", name: "iconRequiredWithDescription", title: "with description", description: "this is a description", required: true)
|
||||
}
|
||||
section("with image") {
|
||||
paragraph "The image specified will be replaced after an icon is selected"
|
||||
input(type: "icon", name: "iconwithImage", title: "without description", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputImagePage() {
|
||||
dynamicPage(name: "inputImagePage") {
|
||||
section {
|
||||
paragraph "This only exists in DeviceTypes. Someone should do something about that. (glares at MikeDave)"
|
||||
paragraph "Go to the device preferences of a Mobile Presence device to see it in action"
|
||||
paragraph "If you try to set the value of this, it will not behave as it would in Device Preferences"
|
||||
input(type: "image", title: "This is kind of what it looks like", required: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def optionsGroup(List groups, String title) {
|
||||
def group = [values:[], order: groups.size()]
|
||||
group.title = title ?: ""
|
||||
groups << group
|
||||
return groups
|
||||
}
|
||||
def addValues(List groups, String key, String value) {
|
||||
def lastGroup = groups[-1]
|
||||
lastGroup["values"] << [
|
||||
key: key,
|
||||
value: value,
|
||||
order: lastGroup["values"].size()
|
||||
]
|
||||
return groups
|
||||
}
|
||||
def listToMap(List original) {
|
||||
original.inject([:]) { result, v ->
|
||||
result[v] = v
|
||||
return result
|
||||
}
|
||||
}
|
||||
def addGroup(List groups, String title, values) {
|
||||
if (values instanceof List) {
|
||||
values = listToMap(values)
|
||||
}
|
||||
|
||||
values.inject(optionsGroup(groups, title)) { result, k, v ->
|
||||
return addValues(result, k, v)
|
||||
}
|
||||
return groups
|
||||
}
|
||||
def addGroup(values) {
|
||||
addGroup([], null, values)
|
||||
}
|
||||
/* Example usage of options builder
|
||||
|
||||
// Creating grouped options
|
||||
def newGroups = []
|
||||
addGroup(newGroups, "first group", ["foo", "bar", "baz"])
|
||||
addGroup(newGroups, "second group", [zero: "zero", one: "uno", two: "dos", three: "tres"])
|
||||
|
||||
// simple list
|
||||
addGroup(["a", "b", "c"])
|
||||
|
||||
// simple map
|
||||
addGroup(["a": "yes", "b": "no", "c": "maybe"])
|
||||
*/
|
||||
|
||||
|
||||
def inputSelectionPage() {
|
||||
|
||||
def englishOptions = ["One", "Two", "Three"]
|
||||
def spanishOptions = ["Uno", "Dos", "Tres"]
|
||||
def groupedOptions = []
|
||||
addGroup(groupedOptions, "English", englishOptions)
|
||||
addGroup(groupedOptions, "Spanish", spanishOptions)
|
||||
|
||||
dynamicPage(name: "inputSelectionPage") {
|
||||
|
||||
section("options variations") {
|
||||
paragraph "tap these elements and look at the differences when selecting an option"
|
||||
input(type: "enum", name: "selectionSimple", title: "Simple options", description: "no separators in the selectable options", groupedOptions: addGroup(englishOptions + spanishOptions))
|
||||
input(type: "enum", name: "selectionGrouped", title: "Grouped options", description: "separate groups of options with headers", groupedOptions: groupedOptions)
|
||||
}
|
||||
|
||||
section("list vs map") {
|
||||
paragraph "These should be identical in UI, but are different in code and will produce different settings"
|
||||
input(type: "enum", name: "selectionList", title: "Choose a device", description: "settings will be something like ['Device1 Label']", groupedOptions: addGroup(["Device1 Label", "Device2 Label"]))
|
||||
input(type: "enum", name: "selectionMap", title: "Choose a device", description: "settings will be something like ['device1-id']", groupedOptions: addGroup(["device1-id": "Device1 Label", "device2-id": "Device2 Label"]))
|
||||
}
|
||||
|
||||
section("segmented") {
|
||||
paragraph "segmented should only work if there are either 2 or 3 options to choose from"
|
||||
input(type: "enum", name: "selectionSegmented1", style: "segmented", title: "1 option", groupedOptions: addGroup(["One"]))
|
||||
input(type: "enum", name: "selectionSegmented4", style: "segmented", title: "4 options", groupedOptions: addGroup(["One", "Two", "Three", "Four"]))
|
||||
|
||||
paragraph "multiple and required will have no effect on segmented selection elements. There will always be exactly 1 option selected"
|
||||
input(type: "enum", name: "selectionSegmented2", style: "segmented", title: "2 options", options: ["One", "Two"])
|
||||
input(type: "enum", name: "selectionSegmented3", style: "segmented", title: "3 options", options: ["One", "Two", "Three"])
|
||||
|
||||
paragraph "specifying defaultValue still works with segmented selection elements"
|
||||
input(type: "enum", name: "selectionSegmentedWithDefault", title: "defaulted to 'two'", groupedOptions: addGroup(["One", "Two", "Three"]), defaultValue: "Two")
|
||||
}
|
||||
|
||||
section("required: true") {
|
||||
input(type: "enum", name: "selectionRequired", title: "This is required", description: "It should look different when nothing is selected", groupedOptions: addGroup(["only option"]), required: true)
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "enum", name: "selectionMultiple", title: "This allows multiple selections", description: "It should look different when nothing is selected", groupedOptions: addGroup(["an option", "another option", "no way, one more?"]), multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "enum", name: "selectionWithImage", title: "This has an image", description: "and a description", groupedOptions: addGroup(["an option", "another option", "no way, one more?"]), image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputTextPage() {
|
||||
dynamicPage(name: "inputTextPage", title: "Every 'text' variation") {
|
||||
section("style and functional differences") {
|
||||
input(type: "text", name: "textRequired", title: "required: true", description: "This should look different when nothing has been entered", required: true)
|
||||
input(type: "text", name: "textWithImage", title: "with image", description: "This should look different when nothing has been entered", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", required: false)
|
||||
}
|
||||
section("text") {
|
||||
input(type: "text", name: "text", title: "This has an alpha-numeric keyboard", description: "no special formatting", required: false)
|
||||
}
|
||||
section("password") {
|
||||
input(type: "password", name: "password", title: "This has an alpha-numeric keyboard", description: "masks value", required: false)
|
||||
}
|
||||
section("email") {
|
||||
input(type: "email", name: "email", title: "This has an email-specific keyboard", description: "no special formatting", required: false)
|
||||
}
|
||||
section("phone") {
|
||||
input(type: "phone", name: "phone", title: "This has a numeric keyboard", description: "formatted for phone numbers", required: false)
|
||||
}
|
||||
section("decimal") {
|
||||
input(type: "decimal", name: "decimal", title: "This has an numeric keyboard with decimal point", description: "no special formatting", required: false)
|
||||
}
|
||||
section("number") {
|
||||
input(type: "number", name: "number", title: "This has an numeric keyboard without decimal point", description: "no special formatting", required: false)
|
||||
}
|
||||
|
||||
section("specified ranges") {
|
||||
paragraph "You can limit number and decimal inputs to a specific range."
|
||||
input(range: "50..150", type: "decimal", name: "decimalRange50..150", title: "only values between 50 and 150 will pass validation", description: "no special formatting", required: false)
|
||||
paragraph "Negative limits will add a negative symbol to the keyboard."
|
||||
input(range: "-50..50", type: "number", name: "numberRange-50..50", title: "only values between -50 and 50 will pass validation", description: "no special formatting", required: false)
|
||||
paragraph "Specify * to not limit one side or the other."
|
||||
input(range: "*..0", type: "decimal", name: "decimalRange*..0", title: "only negative values will pass validation", description: "no special formatting", required: false)
|
||||
input(range: "*..*", type: "number", name: "numberRange*..*", title: "only positive values will pass validation", description: "no special formatting", required: false)
|
||||
paragraph "If you don't specify a range, it defaults to 0..*"
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputTimePage() {
|
||||
dynamicPage(name: "inputTimePage") {
|
||||
section {
|
||||
input(type: "time", name: "timeWithDescription", title: "a time picker", description: "with a description", required: false)
|
||||
input(type: "time", name: "timeWithoutDescription", title: "without a description", description: null, required: false)
|
||||
input(type: "time", name: "timeRequired", title: "required: true", required: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// selection subsets
|
||||
def inputDevicePage() {
|
||||
|
||||
dynamicPage(name: "inputDevicePage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "device.switch", name: "deviceRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "device.switch", name: "deviceMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "device.switch", name: "deviceRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputCapabilityPage() {
|
||||
|
||||
dynamicPage(name: "inputCapabilityPage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "capability.switch", name: "capabilityRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "capability.switch", name: "capabilityMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "capability.switch", name: "capabilityRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputRoomPage() {
|
||||
|
||||
dynamicPage(name: "inputRoomPage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "room", name: "roomRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "room", name: "roomMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "room", name: "roomRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputModePage() {
|
||||
|
||||
dynamicPage(name: "inputModePage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "mode", name: "modeRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "mode", name: "modeMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "mode", name: "modeRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputHubPage() {
|
||||
|
||||
dynamicPage(name: "inputHubPage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "hub", name: "hubRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "hub", name: "hubMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "hub", name: "hubRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
def inputContactBookPage() {
|
||||
|
||||
dynamicPage(name: "inputContactBookPage") {
|
||||
|
||||
section("required: true") {
|
||||
input(type: "contact", name: "contactRequired", title: "This is required", description: "It should look different when nothing is selected")
|
||||
}
|
||||
|
||||
section("multiple: true") {
|
||||
input(type: "contact", name: "contactMultiple", title: "This is required", description: "It should look different when nothing is selected", multiple: true)
|
||||
}
|
||||
|
||||
section("with image") {
|
||||
input(type: "contact", name: "contactRequired", title: "This has an image", description: "and a description", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def appPage() {
|
||||
dynamicPage(name: "appPage", title: "Every 'app' type") {
|
||||
section {
|
||||
paragraph "These won't work unless you create a child SmartApp to link to... Sorry."
|
||||
}
|
||||
section("app") {
|
||||
app(
|
||||
name: "app",
|
||||
title: "required:false, multiple:false",
|
||||
required: false,
|
||||
multiple: false,
|
||||
namespace: "Steve",
|
||||
appName: "Child SmartApp"
|
||||
)
|
||||
app(name: "appRequired", title: "required:true", required: true, multiple: false, namespace: "Steve", appName: "Child SmartApp")
|
||||
app(name: "appComplete", title: "state:complete", required: false, multiple: false, namespace: "Steve", appName: "Child SmartApp", state: "complete")
|
||||
app(name: "appWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
section("multiple:true") {
|
||||
app(name: "appMultiple", title: "multiple:true", required: false, multiple: true, namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
section("multiple:true with image") {
|
||||
app(name: "appMultipleWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "appPage", title: "Every 'app' type") {
|
||||
section {
|
||||
paragraph "These won't work unless you create a child SmartApp to link to... Sorry."
|
||||
}
|
||||
section("app") {
|
||||
app(
|
||||
name: "app",
|
||||
title: "required:false, multiple:false",
|
||||
required: false,
|
||||
multiple: false,
|
||||
namespace: "Steve",
|
||||
appName: "Child SmartApp"
|
||||
)
|
||||
app(name: "appRequired", title: "required:true", required: true, multiple: false, namespace: "Steve", appName: "Child SmartApp")
|
||||
app(name: "appComplete", title: "state:complete", required: false, multiple: false, namespace: "Steve", appName: "Child SmartApp", state: "complete")
|
||||
app(name: "appWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
section("multiple:true") {
|
||||
app(name: "appMultiple", title: "multiple:true", required: false, multiple: true, namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
section("multiple:true with image") {
|
||||
app(name: "appMultipleWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", namespace: "Steve", appName: "Child SmartApp")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def labelPage() {
|
||||
dynamicPage(name: "labelPage", title: "Every 'Label' type") {
|
||||
section("label") {
|
||||
label(name: "label", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
label(name: "labelRequired", title: "required:true", required: true, multiple: false)
|
||||
label(name: "labelWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "labelPage", title: "Every 'Label' type") {
|
||||
section("label") {
|
||||
paragraph "The difference between a label element and a text input element is that the label element will effect the SmartApp directly by setting the label. An input element will place the set value in the SmartApp's settings."
|
||||
paragraph "There are 3 here as an example. Never use more than 1 label element on a page."
|
||||
label(name: "label", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
label(name: "labelRequired", title: "required:true", required: true, multiple: false)
|
||||
label(name: "labelWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def modePage() {
|
||||
dynamicPage(name: "modePage", title: "Every 'mode' type") { // TODO: finish this
|
||||
section("mode") {
|
||||
mode(name: "mode", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
mode(name: "modeRequired", title: "required:true", required: true, multiple: false)
|
||||
mode(name: "modeMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
mode(name: "modeWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "modePage", title: "Every 'mode' type") { // TODO: finish this
|
||||
section("mode") {
|
||||
paragraph "The difference between a mode element and a mode input element is that the mode element will effect the SmartApp directly by setting the modes it executes in. A mode input element will place the set value in the SmartApp's settings."
|
||||
paragraph "Another difference is that you can select 'All Modes' when choosing which mode the SmartApp should execute in. This is the same as selecting no modes. When a SmartApp does not have modes specified, it will execute in all modes."
|
||||
paragraph "There are 4 here as an example. Never use more than 1 mode element on a page."
|
||||
mode(name: "mode", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
mode(name: "modeRequired", title: "required:true", required: true, multiple: false)
|
||||
mode(name: "modeMultiple", title: "multiple:true", required: false, multiple: true)
|
||||
mode(name: "modeWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, multiple: true, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def paragraphPage() {
|
||||
dynamicPage(name: "paragraphPage", title: "Every 'paragraph' type") {
|
||||
section("paragraph") {
|
||||
paragraph "This us how you should make a paragraph element"
|
||||
paragraph image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", "This is a long description, blah, blah, blah."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def iconPage() {
|
||||
dynamicPage(name: "iconPage", title: "Every 'icon' type") { // TODO: finish this
|
||||
section("icon") {
|
||||
icon(name: "icon", title: "required:false, multiple:false", required: false, multiple: false)
|
||||
icon(name: "iconRequired", title: "required:true", required: true, multiple: false)
|
||||
icon(name: "iconWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "paragraphPage", title: "Every 'paragraph' type") {
|
||||
section("paragraph") {
|
||||
paragraph "This is how you should make a paragraph element"
|
||||
paragraph image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", "This is a long description, blah, blah, blah."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def hrefPage() {
|
||||
dynamicPage(name: "hrefPage", title: "Every 'href' type") {
|
||||
section("page") {
|
||||
href(name: "hrefPage", title: "required:false, multiple:false", required: false, multiple: false, page: "deadEnd")
|
||||
href(name: "hrefPageRequired", title: "required:true", required: true, multiple: false, page: "deadEnd", description: "Don't make hrefs required")
|
||||
href(name: "hrefPageComplete", title: "state:complete", required: false, multiple: false, page: "deadEnd", state: "complete")
|
||||
href(name: "hrefPageWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", page: "deadEnd",)
|
||||
}
|
||||
section("external") {
|
||||
href(name: "hrefExternal", title: "required:false, multiple:false", required: false, multiple: false, style: "external", url: "http://smartthings.com/")
|
||||
href(name: "hrefExternalRequired", title: "required:true", required: true, multiple: false, style: "external", url: "http://smartthings.com/", description: "Don't make hrefs required")
|
||||
href(name: "hrefExternalComplete", title: "state:complete", required: false, multiple: true, style: "external", url: "http://smartthings.com/", state: "complete")
|
||||
href(name: "hrefExternalWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", url: "http://smartthings.com/")
|
||||
}
|
||||
section("embedded") {
|
||||
href(name: "hrefEmbedded", title: "required:false, multiple:false", required: false, multiple: false, style: "embedded", url: "http://smartthings.com/")
|
||||
href(name: "hrefEmbeddedRequired", title: "required:true", required: true, multiple: false, style: "embedded", url: "http://smartthings.com/", description: "Don't make hrefs required")
|
||||
href(name: "hrefEmbeddedComplete", title: "state:complete", required: false, multiple: true, style: "embedded", url: "http://smartthings.com/", state: "complete")
|
||||
href(name: "hrefEmbeddedWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", url: "http://smartthings.com/")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "hrefPage", title: "Every 'href' variation") {
|
||||
section("stylistic differences") {
|
||||
href(page: "deadEnd", title: "state: 'complete'", description: "gives the appearance of an input that has been filled out", state: "complete")
|
||||
href(page: "deadEnd", title: "with image", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
href(page: "deadEnd", title: "with image and description", description: "and state: 'complete'", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", state: "complete")
|
||||
}
|
||||
section("functional differences") {
|
||||
href(page: "deadEnd", title: "to a page within the app")
|
||||
href(url: "http://www.google.com", title: "to a url using all defaults")
|
||||
href(url: "http://www.google.com", title: "external: true", description: "takes you outside the app", external: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def buttonsPage() {
|
||||
dynamicPage(name: "buttonsPage", title: "Every 'button' type") {
|
||||
section("buttons") {
|
||||
buttons(name: "buttons", title: "required:false, multiple:false", required: false, multiple: false, buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"]
|
||||
])
|
||||
buttons(name: "buttonsRequired", title: "required:true", required: true, multiple: false, buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"]
|
||||
])
|
||||
buttons(name: "buttonsWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"]
|
||||
])
|
||||
}
|
||||
section("Colored Buttons") {
|
||||
buttons(name: "buttonsColoredSpecial", title: "special strings", description: "SmartThings highly recommends using these colors", buttons: [
|
||||
[label: "complete", action: "bar", backgroundColor: "complete"],
|
||||
[label: "required", action: "bar", backgroundColor: "required"]
|
||||
])
|
||||
buttons(name: "buttonsColoredHex", title: "hex values work", buttons: [
|
||||
[label: "bg: #000dff", action: "foo", backgroundColor: "#000dff"],
|
||||
[label: "fg: #ffac00", action: "foo", color: "#ffac00"],
|
||||
[label: "both fg and bg", action: "foo", color: "#ffac00", backgroundColor: "#000dff"]
|
||||
])
|
||||
buttons(name: "buttonsColoredString", title: "strings work too", buttons: [
|
||||
[label: "green", action: "foo", backgroundColor: "green"],
|
||||
[label: "red", action: "foo", backgroundColor: "red"],
|
||||
[label: "both fg and bg", action: "foo", color: "red", backgroundColor: "green"]
|
||||
])
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "buttonsPage", title: "Every 'button' type") {
|
||||
section("Simple Buttons") {
|
||||
paragraph "If there are an odd number of buttons, the last button will span the entire view area."
|
||||
buttons(name: "buttons1", title: "1 button", buttons: [
|
||||
[label: "foo", action: "foo"]
|
||||
])
|
||||
buttons(name: "buttons2", title: "2 buttons", buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"]
|
||||
])
|
||||
buttons(name: "buttons3", title: "3 buttons", buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"],
|
||||
[label: "baz", action: "baz"]
|
||||
])
|
||||
buttons(name: "buttonsWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", buttons: [
|
||||
[label: "foo", action: "foo"],
|
||||
[label: "bar", action: "bar"]
|
||||
])
|
||||
}
|
||||
section("Colored Buttons") {
|
||||
buttons(name: "buttonsColoredSpecial", title: "special strings", description: "SmartThings highly recommends using these colors", buttons: [
|
||||
[label: "complete", action: "bar", backgroundColor: "complete"],
|
||||
[label: "required", action: "bar", backgroundColor: "required"]
|
||||
])
|
||||
buttons(name: "buttonsColoredHex", title: "hex values work", buttons: [
|
||||
[label: "bg: #000dff", action: "foo", backgroundColor: "#000dff"],
|
||||
[label: "fg: #ffac00", action: "foo", color: "#ffac00"],
|
||||
[label: "both fg and bg", action: "foo", color: "#ffac00", backgroundColor: "#000dff"]
|
||||
])
|
||||
buttons(name: "buttonsColoredString", title: "strings work too", buttons: [
|
||||
[label: "green", action: "foo", backgroundColor: "green"],
|
||||
[label: "red", action: "foo", backgroundColor: "red"],
|
||||
[label: "both fg and bg", action: "foo", color: "red", backgroundColor: "green"]
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def imagePage() {
|
||||
dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish thise
|
||||
section("image") {
|
||||
image "http://f.cl.ly/items/1k1S0A0m3805402o3O12/20130915-191127.jpg"
|
||||
image(name: "imageWithImage", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish thise
|
||||
section("image") {
|
||||
image "http://f.cl.ly/items/1k1S0A0m3805402o3O12/20130915-191127.jpg"
|
||||
image(name: "imageWithMultipleImages", title: "This element has an image and a long title.", description: "I am setting long title and descriptions to test the offset", required: false, images: ["https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", "http://f.cl.ly/items/1k1S0A0m3805402o3O12/20130915-191127.jpg"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def videoPage() {
|
||||
dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish this
|
||||
section("video") {
|
||||
// TODO: update this when there is a videoElement method
|
||||
element(name: "videoElement", element: "video", type: "video", title: "this is a video!", description: "I am setting long title and descriptions to test the offset", required: false, image: "http://ec2-54-161-144-215.compute-1.amazonaws.com:8081/jesse/cam1/54aafcd1c198347511c26321.jpg", video: "http://ec2-54-161-144-215.compute-1.amazonaws.com:8081/jesse/cam1/54aafcd1c198347511c2631f.mp4")
|
||||
}
|
||||
}
|
||||
dynamicPage(name: "videoPage", title: "Every 'video' type") { // TODO: finish this
|
||||
section("video") {
|
||||
// TODO: update this when there is a videoElement method
|
||||
element(name: "videoElement", element: "video", type: "video", title: "this is a video!", description: "I am setting long title and descriptions to test the offset", required: false, image: "http://f.cl.ly/items/0w0D1p0K2D0d190F3H3N/Image%202015-12-14%20at%207.57.27%20AM.jpg", video: "http://f.cl.ly/items/3O2L03471l2K3E3l3K1r/Zombie%20Kid%20Likes%20Turtles.mp4")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def flattenedPage() {
|
||||
def allSections = []
|
||||
firstPage().sections.each { section ->
|
||||
section.body.each { hrefElement ->
|
||||
if (hrefElement.page != "flattenedPage") {
|
||||
allSections += "${hrefElement.page}"().sections
|
||||
}
|
||||
}
|
||||
}
|
||||
def flattenedPage = dynamicPage(name: "flattenedPage", title: "All elements in one page!") {}
|
||||
flattenedPage.sections = allSections
|
||||
return flattenedPage
|
||||
def allSections = []
|
||||
firstPage().sections[0].body.each { hrefElement ->
|
||||
if (hrefElement.name != "inputPage") {
|
||||
// inputPage is a bunch of hrefs
|
||||
allSections += "${hrefElement.page}"().sections
|
||||
}
|
||||
}
|
||||
// collect the input elements
|
||||
inputPage().sections.each { section ->
|
||||
section.body.each { hrefElement ->
|
||||
allSections += "${hrefElement.page}"().sections
|
||||
}
|
||||
}
|
||||
def flattenedPage = dynamicPage(name: "flattenedPage", title: "All elements in one page!") {}
|
||||
flattenedPage.sections = allSections
|
||||
return flattenedPage
|
||||
}
|
||||
|
||||
def foo() {
|
||||
dynamicPage(name: "deadEnd") {
|
||||
|
||||
}
|
||||
dynamicPage(name: "deadEnd") {
|
||||
section { }
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
|
||||
initialize()
|
||||
initialize()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
|
||||
unsubscribe()
|
||||
initialize()
|
||||
unsubscribe()
|
||||
initialize()
|
||||
}
|
||||
|
||||
def initialize() {
|
||||
// TODO: subscribe to attributes, devices, locations, etc.
|
||||
// TODO: subscribe to attributes, devices, locations, etc.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user