Is there any way to update a value on an App screen while waiting for input

I've created an app that uses a "paragraph" to display an informational message to the user. The paragraph is simply set to the value of a variable (@Field static String). There are times when, due to the app receiving an event notification, I'd like to update this message while the screen is sitting there waiting for user input. I can't find any way to make that happen.

This snippet below will do that. However, be very careful not to get this into a loop inadvertently.

paragraph "<script>{changeSubmit(this)}</script>"

However, this probably will not work for your case, as it has to be on a dynamic page. The external event is not on the page. The page itself would need to be refreshed periodically. which can be done on some schedule, like once a minute.

@bravenel, thanks very much for the advice, but I must be doing something wrong. For testing purposes, I've got my message being set in exactly 1 place in the program, and there is currently nothing to set it back to null. The app starts and gets its initial input as usual. It then sets the message variable and waits for the user to hit one of a few buttons. (Note that this isn't the event-driven case I was talking about - this is just a normal message that gets set in between getting two different inputs from the user.) Anyway, when I set that variable, the message appears, but the program goes into a loop and becomes unresponsive.

Here is a snippet from my page - maybe this isn't the right way to use it:

if (myMsg != null) {
    section ("") {
        paragraph "<script>{changeSubmit(this)}</script>${myMsg}",  width: 4
    }
}

In your reply, you also said something about refreshing the entire page (which I also don't know how to do). Perhaps another solution would be to go back to the old simple way of displaying the message and then on those few occasions where I want to update it in an event, I could refresh the page from the event handler?

The loop is because refreshing the page (changeSubmit(this)) is going to cause all of the code for that page to execute again.

To get a single refresh only (absolutely necessary), you would do something like set a state variable to true -- the message to the page to do a refresh.

Then your code would look like this

if (myMsg != null && state.wantsRefresh) {
    section {
        state.wantsRefresh = false
        paragraph "<script>{changeSubmit(this)}</script>${myMsg}"
    }
}

This stuff is tricky to pull off. An external event couldn't possibly work as a means to cause a page to refresh, unless the page is already looping somehow. Think of it this way: the page code runs to completion, and then the app is no longer running at all. An input might be pending, and if it has submitOnChange: true the page will run again once the input is completed -- then it will sit there again not doing anything at all.

There is an optional parameter for a dynamic page definition that causes it to refresh periodically. But that's very tricky, and pretty much undesirable. It's also possible to cause the page to refresh after some interval, with this:

paragraph "<script>setTimeout(function() {changeSubmit(this)},$timeForRefresh)</script>"

But for that to work, it has to be protected against looping as well, and the variable timeForRefresh (in milliseconds) has to be managed by the page.

You can see an example of these things at work in Hubitat Safety Monitor. If you set delayed Arming, and arm from the page UI, it will display a countdown in seconds in the UI.

Also, width on these script paragraphs isn't meaningful. They aren't rendering anything to the page.

Thank you for the comprehensive answer. I'd already thought about doing something like your state variable, but it's a catch-22 since, as you said, at the time I want to use it the page is already sitting there doing nothing, so the variable doesn't get looked at.

I guess what would really be nice is a simple command to the page to refresh itself!

And, FWIW, the width command does appear to do exactly what I intend it to: limits the paragraph to about 1/3 of a computer screen and the paragraph does line wrapping nicely within that width.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.