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 * 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 * 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: * in compliance with the License. You may obtain a copy of the License at:
@@ -24,158 +24,367 @@ definition(
) )
preferences { preferences {
// landing page
page(name: "firstPage") page(name: "firstPage")
page(name: "inputPage")
page(name: "appPage") // PageKit
page(name: "labelPage")
page(name: "modePage")
page(name: "paragraphPage")
page(name: "iconPage")
page(name: "hrefPage")
page(name: "buttonsPage") page(name: "buttonsPage")
page(name: "imagePage") 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: "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: "deadEnd", title: "Nothing to see here, move along.", content: "foo")
page(name: "flattenedPage") page(name: "flattenedPage")
} }
def firstPage() { def firstPage() {
dynamicPage(name: "firstPage", title: "Where to first?", install: true, uninstall: true) { dynamicPage(name: "firstPage", title: "Where to first?", install: true, uninstall: true) {
section() { section {
href(page: "inputPage", title: "Element: 'input'")
href(page: "appPage", title: "Element: 'app'") 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: "labelPage", title: "Element: 'label'")
href(page: "modePage", title: "Element: 'mode'") href(page: "modePage", title: "Element: 'mode'")
href(page: "paragraphPage", title: "Element: 'paragraph'") 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'") href(page: "videoPage", title: "Element: 'video'")
} }
section() { section {
href(page: "flattenedPage", title: "All of the above elements on a single page") href(page: "flattenedPage", title: "All of the above elements on a single page")
} }
} }
} }
def inputPage() { def inputPage() {
dynamicPage(name: "inputPage", title: "Every 'input' type") { dynamicPage(name: "inputPage", title: "Links to every 'input' element") {
section("enum") { section {
input(type: "enum", name: "enumRefresh", title: "submitOnChange:true", required: false, multiple: true, options: ["one", "two", "three"], submitOnChange: true) href(page: "inputBooleanPage", title: "to boolean page")
if (enumRefresh) { href(page: "inputIconPage", title: "to icon page")
paragraph "${enumRefresh}" 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") section("subsets of selection input") {
input(type: "enum", name: "enum", title: "required:false, multiple:false", required: false, multiple: false, options: ["one", "two", "three"]) href(page: "inputDevicePage", title: "to device selection page")
input(type: "enum", name: "enumRequired", title: "required:true", required: true, multiple: false, options: ["one", "two", "three"]) href(page: "inputCapabilityPage", title: "to capability selection page")
input(type: "enum", name: "enumMultiple", title: "multiple:true", required: false, multiple: true, options: ["one", "two", "three"]) href(page: "inputRoomPage", title: "to room selection page")
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") href(page: "inputModePage", title: "to mode selection page")
input(type: "enum", name: "enumWithGroupedOptions", title: "groupedOptions", description: "This enum has grouped options", required: false, multiple: true, groupedOptions: [ href(page: "inputHubPage", title: "to hub selection page")
[ href(page: "inputContactBookPage", title: "to contact-book selection page")
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: [
[ def inputBooleanPage() {
key : "the value that will be placed in SmartApp settings.", // such as a device id dynamicPage(name: "inputBooleanPage") {
value: "the title of the selectable option that is displayed", // such as a device name section {
order: 0 // the order of the option 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) {
title : "the second group title that is displayed", original.inject([:]) { result, v ->
order : 1, // the order of the group; 0-based result[v] = v
image : null, // not yet supported return result
values: [ }
[ }
key : "some_device_id", def addGroup(List groups, String title, values) {
value: "some_device_name", if (values instanceof List) {
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 values = listToMap(values)
], }
[
key : "some_other_device_id", values.inject(optionsGroup(groups, title)) { result, k, v ->
value: "some_other_device_name", return addValues(result, k, v)
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 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") { section("text") {
input(type: "text", name: "text", title: "required:false, multiple:false", required: false, multiple: false) input(type: "text", name: "text", title: "This has an alpha-numeric keyboard", description: "no special formatting", required: 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") { section("password") {
input(type: "password", name: "password", title: "required:false, multiple:false", required: false, multiple: false) input(type: "password", name: "password", title: "This has an alpha-numeric keyboard", description: "masks value", required: 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") { section("email") {
input(type: "email", name: "email", title: "required:false, multiple:false", required: false, multiple: false) input(type: "email", name: "email", title: "This has an email-specific keyboard", description: "no special formatting", required: 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("phone") {
input(type: "phone", name: "phone", title: "This has a numeric keyboard", description: "formatted for phone numbers", required: false)
} }
section("decimal") { section("decimal") {
input(type: "decimal", name: "decimal", title: "required:false, multiple:false", required: false, multiple: false) input(type: "decimal", name: "decimal", title: "This has an numeric keyboard with decimal point", description: "no special formatting", required: 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") { section("number") {
input(type: "mode", name: "mode", title: "required:false, multiple:false", required: false, multiple: false) input(type: "number", name: "number", title: "This has an numeric keyboard without decimal point", description: "no special formatting", required: 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) section("specified ranges") {
input(type: "icon", name: "iconRequired", title: "required:true", required: true, multiple: false) paragraph "You can limit number and decimal inputs to a specific range."
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") 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")
} }
section("device") { def inputTimePage() {
input(type: "device.switch", name: "device", title: "required:false, multiple:false", required: false, multiple: false) dynamicPage(name: "inputTimePage") {
input(type: "device.switch", name: "deviceRequired", title: "required:true", required: true, multiple: false) section {
input(type: "device.switch", name: "deviceMultiple", title: "multiple:true", required: false, multiple: true) input(type: "time", name: "timeWithDescription", title: "a time picker", description: "with a description", required: false)
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") input(type: "time", name: "timeWithoutDescription", title: "without a description", description: null, required: false)
input(type: "time", name: "timeRequired", title: "required: true", required: true)
} }
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)
} }
/// 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")
} }
} }
} }
@@ -210,6 +419,8 @@ def appPage() {
def labelPage() { def labelPage() {
dynamicPage(name: "labelPage", title: "Every 'Label' type") { dynamicPage(name: "labelPage", title: "Every 'Label' type") {
section("label") { 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: "label", title: "required:false, multiple:false", required: false, multiple: false)
label(name: "labelRequired", title: "required:true", required: true, 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") 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() { def modePage() {
dynamicPage(name: "modePage", title: "Every 'mode' type") { // TODO: finish this dynamicPage(name: "modePage", title: "Every 'mode' type") { // TODO: finish this
section("mode") { 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: "mode", title: "required:false, multiple:false", required: false, multiple: false)
mode(name: "modeRequired", title: "required:true", required: true, multiple: false) mode(name: "modeRequired", title: "required:true", required: true, multiple: false)
mode(name: "modeMultiple", title: "multiple:true", required: false, multiple: true) mode(name: "modeMultiple", title: "multiple:true", required: false, multiple: true)
@@ -231,57 +445,44 @@ def modePage() {
def paragraphPage() { def paragraphPage() {
dynamicPage(name: "paragraphPage", title: "Every 'paragraph' type") { dynamicPage(name: "paragraphPage", title: "Every 'paragraph' type") {
section("paragraph") { 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." 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() { def hrefPage() {
dynamicPage(name: "hrefPage", title: "Every 'href' type") { dynamicPage(name: "hrefPage", title: "Every 'href' variation") {
section("page") { section("stylistic differences") {
href(name: "hrefPage", title: "required:false, multiple:false", required: false, multiple: false, page: "deadEnd") href(page: "deadEnd", title: "state: 'complete'", description: "gives the appearance of an input that has been filled out", state: "complete")
href(name: "hrefPageRequired", title: "required:true", required: true, multiple: false, page: "deadEnd", description: "Don't make hrefs required") href(page: "deadEnd", title: "with image", image: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png")
href(name: "hrefPageComplete", title: "state:complete", required: false, multiple: false, page: "deadEnd", state: "complete") 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")
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") { section("functional differences") {
href(name: "hrefExternal", title: "required:false, multiple:false", required: false, multiple: false, style: "external", url: "http://smartthings.com/") href(page: "deadEnd", title: "to a page within the app")
href(name: "hrefExternalRequired", title: "required:true", required: true, multiple: false, style: "external", url: "http://smartthings.com/", description: "Don't make hrefs required") href(url: "http://www.google.com", title: "to a url using all defaults")
href(name: "hrefExternalComplete", title: "state:complete", required: false, multiple: true, style: "external", url: "http://smartthings.com/", state: "complete") href(url: "http://www.google.com", title: "external: true", description: "takes you outside the app", external: true)
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/")
} }
} }
} }
def buttonsPage() { def buttonsPage() {
dynamicPage(name: "buttonsPage", title: "Every 'button' type") { dynamicPage(name: "buttonsPage", title: "Every 'button' type") {
section("buttons") { section("Simple Buttons") {
buttons(name: "buttons", title: "required:false, multiple:false", required: false, multiple: false, 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: "foo", action: "foo"],
[label: "bar", action: "bar"] [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: "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: "foo", action: "foo"],
[label: "bar", action: "bar"] [label: "bar", action: "bar"]
]) ])
@@ -310,28 +511,33 @@ def imagePage() {
dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish thise dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish thise
section("image") { section("image") {
image "http://f.cl.ly/items/1k1S0A0m3805402o3O12/20130915-191127.jpg" 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() { def videoPage() {
dynamicPage(name: "imagePage", title: "Every 'image' type") { // TODO: finish this dynamicPage(name: "videoPage", title: "Every 'video' type") { // TODO: finish this
section("video") { section("video") {
// TODO: update this when there is a videoElement method // 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 flattenedPage() {
def allSections = [] def allSections = []
firstPage().sections.each { section -> firstPage().sections[0].body.each { hrefElement ->
section.body.each { hrefElement -> if (hrefElement.name != "inputPage") {
if (hrefElement.page != "flattenedPage") { // inputPage is a bunch of hrefs
allSections += "${hrefElement.page}"().sections 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!") {} def flattenedPage = dynamicPage(name: "flattenedPage", title: "All elements in one page!") {}
flattenedPage.sections = allSections flattenedPage.sections = allSections
@@ -340,7 +546,7 @@ def flattenedPage() {
def foo() { def foo() {
dynamicPage(name: "deadEnd") { dynamicPage(name: "deadEnd") {
section { }
} }
} }