Key Events needed in WebApp

Hi Guys,
for a WebApp i need the possibility to navigate through the UI by using the arrow-keys.

But since Web2.0 the KeyPressed events are deleted.

Is there a solution or workaround to react to KeyPress Events?
Maybe I just overlooked something.

Thanks for your help :)))
Marc

1 Like

Anthony just added a workaround to capture the missing events to GraffitiSuite:

https://twitter.com/graffitisuite/status/1603604567803170817

He may have a pre-release available to current customers.

3 Likes

Hi Tim, thanks to your answer. This could be an interesting workaround :))

But that would mean that such elementary features are not provided in the Xojo Web Edition at all? Can that be?

The reason that key events are no longer included has to do with the amount of traffic that’s generated. If a user typed 120 wpm, you’re talking about 5-10 requests per second per active session that the server needs to handle and respond to because all of your logic is written as Xojo code.

Xojo web will become great when Xojo could implement the separation of frontend and backend codes and some intercomm under request between them. So people could create apps that could basically run almost entirely in the frontend for example and sometimes just load or save some data from/to the backend. People would code for example a playable “Asteroids” game for web, or some agile interface based on clicks and drags and key presses, something impossible right now due to all the current round-trip. What about a Web3 ? :sweat_smile: People will kill me because of the joke :rofl:

How exactly is the compiler supposed to know which side you intend your code to run on? Pragmas right? Ok, let’s say they did that, how does the developer know?

You guys with this “oh Web 3 fixes everything” idea have never explored beyond saying that it does. Once you start looking at how things would need to be implemented, things get very, very complicated.

The example I like to use is database access. Xojo users are used to being able to do this:

Var rs as RowSet = db.SelectSQL("...")

That could be converted into something that runs on a browser, but because it’s no longer on the machine where the database is and possibly separated from it by thousands of miles, the request now has to be asynchronous. Well now the next statements that iterate through the records don’t work. Yes you could use async await, but that makes the code even more complicated because again, the compiler needs to figure out how much code needs to wait. Oh right, more pragmas, got it. People gripe about using Workers now, which have some of the same issues as this does, so I’m not going to hold my breath that anyone would be able to write this kind of code.

…and don’t get me started on how any of that would be debugged.

3 Likes

I don’t know. A new navigator view? An UI page can be switched to frontend or backend mode and we can see separated code and events? Lots of options. Few engineers sitting to think about it can design a project for such thing in… a week? I mean just a doc with the base lines. The design can be enhanced after few meetings.

You probably are aware the there are systems like that. ASPX pages have separated code, server side and client side, basically C# code compiled to run on the server and client side code transpiled to JS to the browser. They call the source of such views as “Code Behind” and you mark blocks of code with <runat=“server”> or <runat=“client”> on each block of code and a logic from the framework behind makes the glue sending data back and forth.

I’m not saying to follow something like that, but things like that exists, engineers sitting to think about it in details can find a Xojo way enabling both sides, differently than Spider Basic that opted just to make the client side, that’s not enough.

1 Like

All functions and abilities missing in Web2 can be added using WebSDKUIControl Or WebSDKControl.

This code will detect just the enter key but can easily be expanded to return any key. Modify the JSModule code below.

The following blocks of code are String Constants

JSCode

var Company;
(function (Company) {
    class KeyEventObj extends XojoWeb.XojoControl {
        constructor(target, events) {
            super(target, events);
        }
        callback(eventName, datum) {
	    datum = { data : datum };
            this.triggerServerEvent(eventName, datum, true);
        }
    }
    Company.KeyEventObj = KeyEventObj;
})(Company || (Company = {}));

JSModule

KeyEventModule = {
	Init: function (idstr, controlid) {
		$('#' + controlid + '_field').keyup(function(event) {
			if (event.keyCode === 13) {
				XojoWeb.getNamedControl(idstr).callback('EnterKey', XojoWeb.EncodeBase64(XojoWeb.getNamedControl(controlid).mValue));
			}
		});
	}
};
Function ExecuteEvent(name as string, parameters as JSONItem) Handles ExecuteEvent as Boolean
  Select Case EventName
    Case "EnterKey"
      RaiseEvent EnterKey(Data)
      Return True
  End Select
End Function
Function JavaScriptClassName() Handles JavaScriptClassName as String
  Return "Company.KeyEventObj"
End Function

JSWebFile As WebFile Shared Property

Function SessionHead(session as WebSession) Handles SessionHead as String
  Dim 
  Dim HTMLHeader As String
  
  If JSWebFile = Nil Then
    JSWebFile = New WebFile
    JSWebFile.MIMEType = "text/javascript"
    JSWebFile.Session = Nil
    JSWebFile.Filename = "WebKeyJS.js"
    JSWebFile.Data = JSCode //String constant
  End If
  
  HTMLHeader = "<script id=" + Chr(34) + "WebKeyJS" + Chr(34) + " src=" + Chr(34) + _
  JSWebFile.URL + Chr(34) + " type=" + Chr(34) + "text/javascript" + Chr(34) + "></script>"
  
  Return HTMLHeader
End Function

MainJSWebFile As WebFile Shared Property

Function SessionJavascriptURLs(session as WebSession) Handles SessionJavascriptURLs as String()
  #pragma Unused session
  
  Dim URLS(-1) As String
  
  If MainJSWebFile = Nil Then
    MainJSWebFile = New WebFile
    MainJSWebFile.MIMEType = "text/javascript"
    MainJSWebFile.Session = Nil
    MainJSWebFile.Filename = "WebKeyJSFunctions.js"
    MainJSWebFile.Data = JSModule //String constant
  End If
  
  URLS.Append(MainJSWebFile.URL)
  
  Return URLS
End Function

Sub Shown() Handles Shown
  Dim CMDToSend As String
  
  CMDToSend = "KeyEventModule.Init(" + Chr(39) + Self.ControlID + Chr(39) + "," + _
  Chr(39) + Self.ControlID + Chr(39) + ");"
  Self.ExecuteJavaScript(CMDToSend)
End Sub

I have used this to extend a WebTextField to add the ability to return the data in the text field when the enter key is pressed. Web2 is the best!

Working project with extended WebTextField.

2 Likes

If I need to write this much Javascript just to read a key press, I would remove Xojo from the equation and write everything else too.

2 Likes

Haha. It isn’t even that much. Most gets reused. Eg/ setting up the WebSDKControl
Then just a little javascript

The amount of javascript that is actually included if you ignore bracket lines and WebSDK method is 3 lines and I don’t have to complain about not having key events

Any JS coder don’t have to complain about not having key events either, but it would be better just setting a Xojo client side event keypressed() and writing some Xojo client side code and declaring some client side functions too. No round-trip necessary, no need to touch another language too. But as I said, it would be a case for a distant future, a “Web3” put on a wish list to be visited years from now. Web2 is still being developed.

1 Like

Literally what WebSDKControls are for. Yes there will still be comms to server side to run xojo code but you can minimize data transfer to keep it fast. You can move code over to javascript and get the best of both worlds. I’ve used lots of IDEs and I think Xojo is the best.
I created a datatable (https://datatables.net/) in a WebSDKUIControl. All the search and printing/pdf creation is in the javascript library. No need for comms to the server. My previous Web1 table had to do the searching via Xojo events and was slow. There is probably always going to be a little tinkering with other languages when using Xojo especially on new features. Knowing javascript and css when making webapps is a must anyway, doesn’t matter the IDE you use

3 Likes

@Marc_Simon With a slight modification you can extend any Xojo object and add key events. Let me know if you need help with the change

1 Like

Dear @Liam_Sawrey
thank you very much for your detailed description and the code example to integrate key events into Xojo objects :slight_smile:

Due to my lack of JS skills (That’s why I use the Xojo web edition :slight_smile: ) it would be great to know what modifications I would have to make to the code to be able to read the arrow keys and the letters A - H as key events.

1 Like

No worries at all

Here you go:

Left the original WebTextField and The SDKControlClass. That only check the enter key with no options.

WebCanvasKeyEvent and WebTextFieldKeyEvent use the modified SDKMultiKeyControlClass.
This adds inspector options to allow selection of the keys you want. I added ArrowKeys, Numbers 0 - 9, NumPad 0 - 9, a - z. Anyone know how to change these booleans into a table on the inspector window?

WebTextFieldKeyEvent1 on WebPage1 will show the KeyName, KeyCode, and Data in ListBox2 when the Enter key is pressed
WebCanvasKeyEvent1 on WebPage1 will show the KeyName, KeyCode in ListBox1 when any other keys are pressed.

In order to capture the arrow keys I needed to add the event with document.onkeydown so that runs. addEventListener(‘keypress’ adds it directly to the object. Let me know of issues or things to make it better

4 Likes

@Marc_Simon Let me know how you go

1 Like

@Liam_Sawrey Great Job. It works fine. Thank you so much for your support :smile:

1 Like