I just added a feature request and placed in my #1 Top Cases slot at 156th place. If you like this idea, please add it to your Top Cases in the Feedback App.
<https://xojo.com/issue/47404>: Web App - Add running JavaScript before Event Handler or Method
This is needed in Web Apps when the user does something that runs a Method or Event Handler that takes a bit of time to show the result. Currently, there is no way to update the UI to let the user know that the code is running.
If we could call javascript before the Method or Event Handler, you could show a spinner or whatever before the Method or Event Handler is processed on the server. Something like calling this:
myWebControl.ExecuteJavaScript( theJavaScript, myWebControl.LostFocus, "Before" )
This would require a fundamental change in how responses are sent to the browser, and would likely break everything.
What you are suggesting is no different than putting your long running code in a WebThread and then just doing two things:
Spinner.Visible = True
LongRunningCodeThread.Run
It’s just as fast? I’ll try it out today.
It should be. And it’ll be much nicer to the other sessions that way because you can control the processing priority.
Note that precisely because JavaScript is its own language, you can already very well trigger execution of a script from the DOM itself, before even the Xojo app has received anything.
The typical example is to use JavaScript onclick in a button to start a script, which will take place in the DOM while the round trip takes place to trigger the Action event in the Xojo app.
[quote=321364:@Greg O’Lone]This would require a fundamental change in how responses are sent to the browser, and would likely break everything.
What you are suggesting is no different than putting your long running code in a WebThread and then just doing two things:
Spinner.Visible = True
LongRunningCodeThread.Run
[/quote]
Unless I’m really unclear on how Xojo web works, I don’t think this is necessarily a fair comparison.
In Xojoweb’s browser-side javascript library, it would seem that a shim could be inserted where, if desired by the app developer, a javascript command could be called immediately prior to the normal call back to the server.
I could see how there’s an increased risk to stability if the call did something unexpected. But a browser-side call is much more immediate and a better form of user feedback that waiting for a loop back from the server (which we find disappointingly slow sometimes - the delay is just on the edge of ‘did it get my click’ timing). Your suggestion also requires a more complicated thread or timer-based response when in many cases we could do a normal DB lookup or something in a reasonable amount of time.
If specifying a javascript call is inadvisable, perhaps an option within the framework where a developer could specify a busy indicator control/element of some sort (provided by the developer) and the browser-side framework could show it when calling back to the server and hide it when a response is received? - though I guess this might not work based on the long-pull technique Xojo uses…
In a WebButton :
Sub MouseDown(X As Integer, Y As Integer, Details As REALbasic.MouseEvent) Handles MouseDown
ProgressWheel1.Visible = True
End Sub
Sub Action() Handles Action
dim start as double = ticks
while ticks < start + 360
wend
me.Enabled = True
ProgressWheel1.visible = False
End Sub
Zero JavaScript…
Example of code that triggers a MsgBox in JavaScript within the DOM, before the Action event takes place, using the JavaScript onclick event :
Sub Open() Handles Open
self.ExecuteJavaScript("document.getElementById('"+me.controlId+"').setAttribute('onclick','alert(""Hello World"")');")
End Sub
The Xojo spinner does not lend itself to be manipulated in JavaScript. But one could use a Font Awesome spinner.
[quote=321472:@Steve Upton]Unless I’m really unclear on how Xojo web works, I don’t think this is necessarily a fair comparison.
In Xojoweb’s browser-side javascript library, it would seem that a shim could be inserted where, if desired by the app developer, a javascript command could be called immediately prior to the normal call back to the server.[/quote]
That what I was trying to describe in the feature request. WebButtons have this built in for AutoDisable where the WebButton can disable itself when clicked before the round trip.
I can understand how difficult it would be to let us run Xojo code locally, but adding the ability to run javascript before the round trip via a shim, like Steve suggested, would provide that power.
[quote=321364:@Greg O’Lone]This would require a fundamental change in how responses are sent to the browser, and would likely break everything.
What you are suggesting is no different than putting your long running code in a WebThread and then just doing two things:[/quote]
How does the WebButton AutoDisable work? Doesn’t that run a bit of Javascript right before the round trip?
As Steve said, the Javascript would run immediately, but the round trip to show a spinner and kick off a thread does take more time.
Sigh. The code to do what you describe is just above.
All this does is install the very small event handler that launches a script :
Here alert("hello World")
Sub Open() Handles Open
self.ExecuteJavaScript("document.getElementById('"+me.controlId+"').setAttribute('onclick','alert(""Hello World"")');")
End Sub
You could instead have something like
document.getElementById('mySpinner').style.visibility = 'visible';
And, there, you already have your JavaScript that executes without, and before the round trip.
However, we have left the realm of Xojo code.
[quote=321502:@Hal Gumbert]How does the WebButton AutoDisable work? Doesn’t that run a bit of Javascript right before the round trip?
As Steve said, the Javascript would run immediately, but the round trip to show a spinner and kick off a thread does take more time.[/quote]
Well it does, but you’ll notice that it’s a Boolean which enables a predefined action to occur on a very specific control and event. Doing this generically for every control leaves users open to a scenario where they could easily break their projects if they don’t know JavaScript.
FWIW, I’ve been thinking about it this weekend and there seem to be only a few things that you’d really need to be able to do anyway:
- Enable/Disable a control
- Show/Hide a control
- Apply a style
And the #1 trigger at this point is that if a button click.
Thanks for thinking about this Greg!
Besides buttons, I also need to provide feedback to users when they change data in controls. For the most part, I use LostFocus on WebTextFields and SelectionChanged on WebPopupMenus and WebRadioGroups. Being able to provide feedback to users before any Event Handler would be amazing.
I don’t think that running local Javascript as we’re discussing is any more dangerous than running ExecuteJavascript.
That said, your three points regarding Enabled, Visible, and Style in addition to able to move the control for the purpose of placing a spinner close to the control that LostFocus or SelectionChanged are probably all I would need to provide feedback to the user.
If I’m thinking what you’re thinking, being able to specify the Enabled, Visible, Style, and Position for one or many controls to any Event Handler would be even better than my feature request. I’d rather not code JavaScript directly.
If that’s what you are thinking, I love it!
What would you do with Position?
I think Hal’s using position to move the overlay div back into view.
I had recommended moving it out of the viewable space (negative top) for good measure.
I also have many TextFields in my apps that detect when the user presses enter. Being able to instantly clear the TextField or at least stop the user from entering any more text (pressing enter when the UI doesn’t respond instantly) would be a welcome improvement.
Maybe an AutoClear toggle for TextFields just like the AutoDisable for buttons could be added?
Coincidentally, I have been thinking about this very same issue recently.
[quote=321711:@Hal Gumbert]
If I’m thinking what you’re thinking, being able to specify the Enabled, Visible, Style, and Position for one or many controls to any Event Handler would be even better than my feature request. I’d rather not code JavaScript directly.
If that’s what you are thinking, I love it![/quote]
This would be a wonderful addition to the web framework! Although I’d imagine most users who would be interested in this feature would also use SDK controls. Opt in support on for the webcontrolwrapper would be fantastic. I found the Xojo spin wheel can be used provided you lay off settings its visibility to false with Xojo.
Bellow is JavaScript method. It isn’t really a way forward but using this example shows how useful said feature would be.
Shown event of button
//Hide Contect Menu
Dim js() as string
js.append("document.getElementById('"+ProgressWheel1.ControlID+"').style.setProperty('top', '-100px');")//Wheel must be set to visible in the IDE
js.append("function ShowWheel() {document.getElementById('"+ProgressWheel1.ControlID+"').style.setProperty('top', '"+str(ProgressWheel1.Top)+"px');}")
js.Append("document.getElementById('"+me.controlId+"').addEventListener('click', ShowWheel);")
self.ExecuteJavaScript(Join(js,EndOfLine))
Action event of button
//Do stuff
Dim i as integer
do until i >= 10000000
i = i + 1
loop
//Turn progress wheel off
ExecuteJavaScript("document.getElementById('"+ProgressWheel1.ControlID+"').style.setProperty('top', '-100px');")
Playing with the browser’s developer mode throttling shows how unresponsive a xojo web app could feel over a slow network.
Hey Greg,
It would allow for the placement of one small spinner on the page which could be moved next to the control that triggered the event.
<https://xojo.com/issue/36865> Implement AutoDisable for WebToolbarButton and WebToolbarMenu
<https://xojo.com/issue/47404> Web App - Add running JavaScript before Event Handler or Method
@Greg O’Lone Implementing these types of feature requests would be greatly appreciated and enable us to easily improve our web apps, especially for users with high latency connections. Instantly disabling controls and instantly providing visual feedback would be very helpful.
@Greg O’Lone , do you need us to create a Feedback case for what you described?