UI elements in subroutines

I have some UI code I'd like to use in two different places. By the principle of DRY, this should be in a function that I call from both places. However, simply calling the function and having the function declare the inputs doesn't appear to work; I'm guessing because it's not directly inside a section{} inside a dynamicPage{}. What's the best way to do this?

For example, I'd like to....

private drawPicker(inputKey, pickerSuffix = "") {
    def inputId = "settings[${inputKey}]";
    def colorOptions = COLORS.
        collect{ "<option value=\"${it.value}\">${it.key}</option>" }.
        join("\n");

    // First, the actual ColorMap input for a literal selection
    // Everything else transfers its value here.
    input inputKey, "COLOR_MAP", title: "", required: true

    // Next, inject a color picker (and its scripts) to help with setting
    // the map:
    def pickerId = "colorPicker${pickerSuffix}"
    paragraph """
<input type="color" id="${pickerId}" style="width: 95%;" onChange="
    let mapElement = document.getElementById('${inputId}');
    mapElement.value = '';
    syncColors('${pickerId}', '${inputId}');
">
<script type="text/javascript">
\$(document).ready(function() {
syncColors("${pickerId}", "${inputId}");
document.getElementById("${inputId}").addEventListener("change", function () {
        syncColors("${pickerId}", "${inputId}");
    });
})
</script>
                """, width: 5

    // Then the preset options
    paragraph """
<select name="${presetKey}" onChange="
    let mapElement = document.getElementById('${pickerId});
    mapElement.value = this.value;
    syncColors('${pickerId}', '${inputId}');">
${colorOptions}
</select>
    """,width: 4
}

...then invoke this inside a section and have the input and paragraph populate on that page.

Normal way to do this is have a section just inside the dynamic page declaration. Code within that section calls methods such as this one. We use methods such as this all over the built-in apps.

Bah, looks like I was encountering a bug in my own code that caused it not to populate. Putting the input calls in subroutines works fine. Maybe it's just time for bed....

LOL. Wait til you make an edit and when you do the input, the page goes blank, with nothing in the logs... That's a fun one to figure out!

Think I've already got a thread along those lines. :wink:

href of a non-declared page will do it. It used to crash the app with no clue, now it just gives a blank page with no clue. Now that's progress!

5 Likes

Download the Hubitat app