Sending data to a WebSDK control from client Javascript

I was familiar with the Web 1.00 SDK, but I am stuck with the 2.00 one.

I have read the documentation, but I am sorry to say I could not find any way to send data to a non visual control to trigger ExecuteEvent or HandleRequest from a JavaScript on the client.

I went through the examples but found nothing that shows how to send data back to the server side from the client.

Perhaps I have a brain freeze, but I will definitely appreciate a short example of JavaScript code showing how it is done.

TIA

Are you working in JavaScript or in TypeScript?

Either way you can use TriggerServerEvent the same way you can on a visual control.

Javascript.

I am sorry, but I don’t understand how to address a particular SDK control. In Web 1.00, I used the controlID, but I don’t see it in the SDK documentation:

triggerServerEvent(eventName: string, parameters: JSONItem | null = null, forced: boolean = false)

Sends an event to the server for processing. eventName should match the Xojo event name. parameters are of type JSONItem. The forced parameter should be used sparingly, it is meant for sending events that otherwise send important information to your control even if the event hasn’t been explicitly implemented. For example, changes to the text in a textfield are always sent because the user has a reasonable expectation that the Value property of the field will be up to date, regardless of whether he or she implemented the ValueChanged event.

TriggerServerEvent exists on the base class so you can call it as

var js = new XojoWeb.JSONItem
js.set("var1", "value1")
this.TriggerServerEvent("click", js)
1 Like

To get the instance and send data in JS, I do it like this, passing JSON as params:

var controlObject = XojoWeb.getNamedControl(controlID);
if (typeof controlObject != 'undefined' && controlObject != null) {
  controlObject.triggerServerEvent(eventName, params, true);
}
1 Like

unfortunately it looks like we neglected to document the JSONItem class…

Class

XojoWeb.JSONItem

Methods

get(key as String) As any
Returns the value specified by the key, if it exists. Value Types will be in a valid JSON type (number, string, boolean, null, JSONItem or an array of one of these types). Returns Null if the key was not found.

set(key as String, value as any
Sets the specified value to the specified key. Value must be a valid JSON type.

lookup(key as string) as any
Same as get.

length() as number
Returns the number of items in the current JSONItem.

serialize() as any
Converts the JSONItem to a javascript object.

3 Likes

In any case the callback example in the SKD folder can give some hint. (removing the bug)

Thank you Anthony.

This should be in the SDK documentation. A simple, short example, easy to insert in a project.

I shall experiment with that later today or tomorrow.

With some luck, it will help me complete RubberviewsWE 2.00.

:slight_smile:

Anthony, I am trying to use this in the SDK Examples project, and am getting nowhere. I placed that code in a constant, and this in a button:

self.ExecuteJavaScript(js.Replaceall("ControlID", VisualControl1.ControlID))

Nothing happens. It seems the JS does not even see the control.

I used the Chrome developer tools to see if the control is in the DOM, but it does not even seem to be there.

don’t you need single quotes ?

self.ExecuteJavaScript(js.Replaceall("ControlID", "'"+VisualControl1.ControlID+"'"))

or did you put the single quotes in the constant ?

The single quotes are in the constant.

What are your params? If you’re just executing that code, it’ll fail because params doesn’t exist in scope. Doing some testing in that example project, even when everything is seemingly done right, it still fails because VisualControl1 doesn’t appear to be available in XojoWeb.controls, which I assume is because there’s no JavaScript class loaded for the object and no actual nodes created.

At any rate, the Gravatar example is better for this. I added the following constant to WebPage1:

Private Const js as String = window.mBujardet = {};
window.mBujardet.sendXojoEvent = function (controlID, eventName, params) {
  var controlObject = XojoWeb.getNamedControl(controlID);
  if (typeof controlObject != 'undefined' && controlObject != null) {
    controlObject.triggerServerEvent(eventName, params, true);
  }
}

Then, in WebPage1.Opening:

ExecuteJavaScript( js )

Next, in a button:

ExecuteJavaScript( "mBujardet.sendXojoEvent('" + Gravatar1.ControlID + "', 'test', ['data1', 1, true]);" )

And finally a breakpoint in the Gravatar class’s ExecuteEvent event I simply added break. When run, and you click the button, the project will break and you’ll be able to inspect the data sent back.

This isn’t really the right way to do it, but it’ll work. You should be creating a proper JavaScript/TypeScript class and encapsulating everything properly according to the docs and limiting communication. Two-way communication is slow and you should probably be using client-side events for triggering your data submission back to the app for RubberViews.

Note that the params parameter of sendXojoEvent accepts a JavaScript object, which is returned to Xojo as a JSONItem. In this example, I’m returning three supported types, a string, a number, and a boolean.

when I have this kind of error (no control in the browser debugger)
it was mainly that you need to send any string to the browser as UTF8 encoding
I mean you must encode the string in the serialize event
the JSON you send to the control has bad characters in it
or also you send forbidden JSON characters to the control.

if the json is correct, and all is utf8 you should get an error in the browser debugger.

Thank you Anthony. I will work on that tomorrow morning (10:20 PM here).

Hi Anthony,

I am sorry to be so thick, but after trying to apply what you posted, I still get nowhere.

Can I please ask you to share the modified Gravatar project you did ? That would help me better understand.

Thank you in advance.

Unfortunately I’m on mobile for most of the day today, so I won’t be able to do that, but following the steps I provided it should just work.

That’s the problem: I cannot get that to work.

It is not an absolute emergency, though. If you can share your test project at a later date when you are back in front of your computer, I will gratefully appreciate it :slight_smile:

Don’t the example SDK controls help with this?

They certainly should. Everything I’ve built was done from the docs and examples.