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:
Steve Vlaminck
2015-12-14 13:57:02 -06:00

View File

@@ -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:
@@ -24,158 +24,367 @@ definition(
)
preferences {
// landing page
page(name: "firstPage")
page(name: "inputPage")
page(name: "appPage")
page(name: "labelPage")
page(name: "modePage")
page(name: "paragraphPage")
page(name: "iconPage")
page(name: "hrefPage")
// 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'")
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: "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() {
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}"
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")
}
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
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()
]
]
],
[
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
]
]
]
])
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: "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")
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: "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")
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: "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")
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: "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")
input(type: "decimal", name: "decimal", title: "This has an numeric keyboard with decimal point", description: "no special formatting", required: false)
}
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("number") {
input(type: "number", name: "number", title: "This has an numeric keyboard without decimal point", description: "no special formatting", required: false)
}
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("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..*"
}
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")
}
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)
}
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")
}
/// 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("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)
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")
}
}
}
@@ -210,6 +419,8 @@ def appPage() {
def labelPage() {
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")
@@ -220,6 +431,9 @@ def labelPage() {
def modePage() {
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)
@@ -231,57 +445,44 @@ def modePage() {
def paragraphPage() {
dynamicPage(name: "paragraphPage", title: "Every 'paragraph' type") {
section("paragraph") {
paragraph "This us how you should make a paragraph element"
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 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")
}
}
}
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",)
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("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/")
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: [
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: "buttonsRequired", title: "required:true", required: true, multiple: false, buttons: [
buttons(name: "buttons3", title: "3 buttons", buttons: [
[label: "foo", action: "foo"],
[label: "bar", action: "bar"]
[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", required: false, image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", buttons: [
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"]
])
@@ -310,28 +511,33 @@ 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")
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
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://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")
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") {
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
@@ -340,7 +546,7 @@ def flattenedPage() {
def foo() {
dynamicPage(name: "deadEnd") {
section { }
}
}