How to call functions on the server from dynamic component?

Forum to discuss the new web client version of Servoy.

How to call functions on the server from dynamic component?

Postby pauwel.demeyer » Thu Mar 17, 2016 10:10 am

We'd like to create dynamic NGClient components, like e.g. a list of buttons/links/...
This could be very simply done by defining a model containing an array of the definitions for the buttons ({label: "..", callBackFunctionID: "..." })
As the number of buttons is not known from the start, we cannot define handlers for each of them in the .spec file.

How should we define the model in the .spec file? typed as a function (but this returns an encoded string in the client)? or as string (which means you cannot select it at design time)?
How should we call this function in the Component so that it gets executed on the server (as it is a server function in a form/scope)?
pauwel.demeyer
 
Posts: 4
Joined: Wed Jan 27, 2016 10:21 am

Re: How to call functions on the server from dynamic compone

Postby Andrei Costescu » Thu Mar 17, 2016 10:36 am

So you have a web-component that will create more buttons/labels inside it depending on the model.
The first thing that comes to mind is define one handler for the component and call that with an argument. For example you have one onAction handler set on the webcomponent (for all buttons), but it sends an index, or an id of the button (that id could be taken from the model definition).
Andrei Costescu
Servoy
Andrei Costescu
 
Posts: 1018
Joined: Tue Jun 26, 2007 3:14 pm

Re: How to call functions on the server from dynamic compone

Postby paronne » Thu Mar 17, 2016 10:50 am

Hi,

if you want to have a list of buttons/links, why don't you use a valuelist to populate the list instead, a single handler function and pass the clicked button as argument of the callBackFunctionID Handler ?

Just for your information, it is possible to execute a server side script from the client as you are asking.
You can use a type defintion in the spec file as:

Code: Select all
"model" : {
   "list" : {"type" : "mylistitem[]", "droppable" : true}
},
"types": {
  "type" : "mylistitem" {
           "label": "string",
           "onClick" : "function"
      }
}


Using droppable:true, you can actually drag&drop mylistitems in the form designer (as if they are tab in a tabless panel)

To execute the server side function from client you need to include the $window object in the link/controller function and you can execute the server side function like this:
Code: Select all
var i = index of the clicked item.
var args = []
args.push(your param)
...
$window.executeInlineScript($scope.model.list[i].onClick.formname, $scope.model.list[i].onClick.script, args);
paronne
 
Posts: 203
Joined: Fri Nov 02, 2012 3:21 pm

Re: How to call functions on the server from dynamic compone

Postby geert.haegens » Fri Apr 08, 2016 9:00 am

hi,
when executing your suggestion, I am getting an error on the server (servoy 8.0.2) :

Cannot execute inline script

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:913)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at com.servoy.j2db.util.SecuritySupport.decrypt(SecuritySupport.java:140)
at com.servoy.j2db.server.ngclient.NGFormServiceHandler.executeMethod(NGFormServiceHandler.java:127)
at org.sablo.websocket.WebsocketEndpoint$3.run(WebsocketEndpoint.java:278)
at org.sablo.eventthread.Event$1.run(Event.java:100)
at org.sablo.websocket.CurrentWindow.runForWindow(CurrentWindow.java:77)
at org.sablo.eventthread.Event.execute(Event.java:90)
at org.sablo.eventthread.EventDispatcher.dispatch(EventDispatcher.java:125)
at org.sablo.eventthread.EventDispatcher.run(EventDispatcher.java:89)
at com.servoy.j2db.server.ngclient.eventthread.NGEventDispatcher.run(NGEventDispatcher.java:55)
at java.lang.Thread.run(Unknown Source)
geert.haegens
 
Posts: 3
Joined: Fri Apr 08, 2016 8:56 am

Re: How to call functions on the server from dynamic compone

Postby geert.haegens » Mon Apr 11, 2016 11:23 am

hi paronne,

thx for your suggestion. it is exactly what i'm looking for !
however, when i debug, the "$scope.model.list[i].onClick" object does not contain a property "formname", only the prop "script".

in my test, i have used $window.executeInlineScript("myFormName", $scope.model.list[i].onClick.script, []); instead.
could this be the reason why i'm getting the error message on the server side as previously posted ?
any suggestions how to fix this ?
geert.haegens
 
Posts: 3
Joined: Fri Apr 08, 2016 8:56 am

Re: How to call functions on the server from dynamic compone

Postby paronne » Mon Apr 11, 2016 11:49 am

Hi Geert, formname would be empty if your function is not a scope function. Which version of Servoy are you using ? if your test method $window.executeInlineScript("myFormName", $scope.model.list[i].onClick.script, []); is working it may be a bug of that Servoy version.
I don't know which is your use case, but having a single handler function instead of many functions linked to object is the preferred solution. There are normally few use cases where $window.executeInlineScript() should be used
paronne
 
Posts: 203
Joined: Fri Nov 02, 2012 3:21 pm

Re: How to call functions on the server from dynamic compone

Postby geert.haegens » Mon Apr 11, 2016 2:17 pm

hi paronne,

i just tested a form-method as well as a scope-method, same result : only getting onClick.script, no onClick.formname.
i am using servoy Version: 8.0.2 - build 3024.

in regards to "single handler function instead of many functions linked to object is the preferred solution" : my object is a ngClientComponent navigation bar, that has an array of buttons. in part, the buttons vary depending on the program where the navigation bar is used. some of the buttons are generated dynamically by altering the array of buttons.

do you think i've encountered a bug ?
geert.haegens
 
Posts: 3
Joined: Fri Apr 08, 2016 8:56 am

Re: How to call functions on the server from dynamic compone

Postby paronne » Mon Apr 11, 2016 3:00 pm

Hi Geert, yes it may be a bug. Still you can make use of a single handler to which you provide the button the user has clicked on. Is then responsability of the handler method to switch to the proper action depending on the button properties.
I have actually implemented a similar use case for multi-level navbar menu component with such structure. See menu and menuItem below. I use the property methodArguments to provide extra params to the menu/menuItem. For instance i can include the form to show and the record to select for a specific menuItem

Code: Select all
        "model":
         {
      "menubarSource"               : {"type" :"menu[]", "default" : [], "pushToServer": "deep", "droppable" : true}
                 ......
   },
   
   "handlers":
   {
           "onMenuItemSelected"       : {
                                      "parameters" : [
                                          { "name" : "event", "type" : "JSEvent" },
                                          { "name" : "menuItem", "type" : "menuItem" }
                                      ]
                                }
   },

   "types": {
      "menu": {
            "id"               : "string",
            "text"               : "tagstring",
            "icon"               : "media",
            "enabled"            : {"type" : "boolean", "default" : true},
            "methodArguments"      : "object",
            "tooltip"            : "tagstring",
            "menuItems"            : "menuItem[]"
       },
       "menuItem": {
            "id"               : "string",
            "text"               : "tagstring",
            "icon"               : "media",
            "enabled"            : {"type" : "boolean", "default" : true},
            "methodArguments"      : "object",
            "menuItems"            : "menuItem[]"
       }
}
paronne
 
Posts: 203
Joined: Fri Nov 02, 2012 3:21 pm

Re: How to call functions on the server from dynamic compone

Postby pauwel.demeyer » Tue Apr 12, 2016 5:08 pm

Hey Paolo,

I understand that in case of e.g. a menuitem, you can do this with a single handler function, and passing some argument in this method to identify the exact button that is clicked.
We although are creating a generic list of buttons, where we would like to pass in the model containing the icon or button label, and a function that will be executed when this button is clicked. As the behavior is completely different for each of them, we would like to pass in different methods when designing the form containing this NG component. As the number of buttons is dynamic (hence the name of the thread), we cannot define a set of handlers beforehand.
For us, it seems to be the finest achitectural solution to pass these functions in the model (as is done in many contemporary architectures by adding lambda functions to a model), which will then be called by the controller of the component. That way, our handler method does not have to know what is put in the model as items. (passing in a parameter mentioning the 'type' of button requires us having a switch/case in the handler, thereby splitting out the definition of our buttons and the handling of them in 2 different places)
The solution you mentioned (calling executeInlineScript()) seems to be the one we need, but as Geerts mentions, this does not work as described, and it makes me think that it is a bug.
If it's a bug (like we filed one today), why is it then already in a resolved state? (without further comments on it)
pauwel.demeyer
 
Posts: 4
Joined: Wed Jan 27, 2016 10:21 am

Re: How to call functions on the server from dynamic compone

Postby paronne » Tue Apr 12, 2016 6:00 pm

Hi,

as told to Geert this is a bug for the version of Servoy 8.0.2. In the latest builds of Servoy is alredy solved.
8.0.3 has been released just today viewtopic.php?f=16&t=21270 it should work there.

Paolo
paronne
 
Posts: 203
Joined: Fri Nov 02, 2012 3:21 pm


Return to Servoy NGClient

Who is online

Users browsing this forum: No registered users and 22 guests