Adv. javascript support -- function keyword

Discuss all feature requests you have for a new Servoy versions here. Make sure to be clear about what you want, provide an example and indicate how important the feature is for you

Adv. javascript support -- function keyword

Postby agiletortoise » Wed Aug 22, 2007 6:34 pm

I'd like to be able to take advantage of some of the more advanced features of Javascript in Servoy. I don't know if this is planned for 4.0, but it would be very powerful if we could extend objects with Prototypes -- or at least declare and assign functions in our code.

For example, I have several generic bit of functionality I want to extend certain forms with -- such as remembering last size/position for dialog forms. If I could extend the form onLoad, I could write a global method like:

Code: Select all
var frm = argument[0];
frm.get_last_size = function{ return [frm.size_w,frm.size_h]; };
frm.get_last_position = function{ return [frm.position_x,frm.position_y]; };


Right now, the Servoy method editor blocks the use of the "function" keyword (even in a literal string!).

It would open up a lot of options to overcome this limitation. Thanks,

greg.
Greg Pierce
Agile Tortoise
SAN Developer
http://www.agiletortoise.com
User avatar
agiletortoise
 
Posts: 278
Joined: Wed Oct 12, 2005 3:26 pm
Location: Texas, USA

Postby sbutler » Wed Aug 22, 2007 10:02 pm

You can use this..

Code: Select all
var simpleScript = new Script('application.output("Do something");');
// and then later to execute the script
simpleScript();
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 759
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Postby agiletortoise » Thu Aug 23, 2007 12:43 am

That doesn't really help much, because the best I can tell, I can't return a value from, or pass arguments to, that Script object.

If I put a "return" in the Script object string, I get an "invalid return" exception.

g.
Greg Pierce
Agile Tortoise
SAN Developer
http://www.agiletortoise.com
User avatar
agiletortoise
 
Posts: 278
Joined: Wed Oct 12, 2005 3:26 pm
Location: Texas, USA

Postby sbutler » Thu Aug 23, 2007 1:57 am

You can't directly pass in parameters, or return, but you can use globals, like..

Code: Select all
var simpleScript = new Script('globals.myGlobal = [frm.position_x,frm.position_y]');
// and then later to execute the script
simpleScript();
//then reference globals.myGlobal to get the return value.
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 759
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: Adv. javascript support -- function keyword

Postby troy » Mon Oct 22, 2007 6:26 pm

agiletortoise wrote:Right now, the Servoy method editor blocks the use of the "function" keyword (even in a literal string!).

True. However, the method editor does not block the use of the "Function" keyword. So....define your function using the new Function constructor. A decent definition of how it is used may be found here, about half-way down the page.

So, following is a simple add function example.
Code: Select all
//adding
var add=new Function('a','b','return a+b')
application.output(add(8,3)) //returns 11

How about we create a function that is used in the definition of another function?
Code: Select all
//any arithmetic operation
var compute=new Function('myOperator','return new Function("a", "b", "return a" + myOperator + "b")')

var multiply=compute('*')
var divide=compute('/')
var subtract=compute('-')

application.output(multiply(8,3)) //returns 24
application.output(divide(8,4)) //returns 2
application.output(subtract(8,3)) //returns 5

And now, what I read as your original need, prototyping. We'll extend Array's default functionality by writing a numeric sort funtion.
Code: Select all
//prototyping any (established) object
Array.prototype.sortNum = new Function('return this.sort(new Function ("a","b","return a-b"))')

var tmp = [5,9,12,18,56,1,10,42,30,7,97,53,33,35,27]

tmp = tmp.sort()   // returns alphabetical sort: 1,10,12,18,27,30,33,35,42,5,53,56,7,9,97
tmp = tmp.sortNum() // returns numerical sort: 1,5,7,9,10,12,18,27,30,33,35,42,53,56,97

A few considerations:
1. Since the actual body of the function is essentially a string (contained within quotes), if your body includes quotes, you need to be creative in stringing together your code in such a way that there is only one type of quote used in each substring, with the other type surrounding it. For example,
Code: Select all
var copyStyles = function(destDoc, sourceDoc)
{
   var links = sourceDoc.getElementsByTagName('link');

   for(var i = 0; i < links.length; i++)
      if(links[i].rel.toLowerCase() == 'stylesheet')
         destDoc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
}
turns into
Code: Select all
var copyStyles = new Function('destDoc', 'sourceDoc',
                           "var links = sourceDoc.getElementsByTagName('link');" +
                           "for(var i = 0; i < links.length; i++)" +
                              "if(links[i].rel.toLowerCase() == 'stylesheet')" +
                                 "destDoc.write(" +
                                    "'<link type=" +
                                    '"text/css" rel="stylesheet" href="' +
                                    "' + links[i].href + '" +
                                    '">' +
                                    "</link>');"
                           )
2. Functions defined using the constructor are generally compiled when invoked, which may lead to slower than optimal performance. Although I'm not sure how Rhino handles this.
3. Servoy clearly went out of their way to disable our abilitiy to use functions. Not that that is necessarily reason enough not to use them, it is just a 'warning'.
4. When prototyping, your additions to established objects are similar to globals in that they are persistent until you enter layout mode, quit servoy, etc.
Troy Elliott, Data Mosaic

Image
Everything you need to build great apps with Servoy
U.S. demo server
Blog: Coding Nomad
User avatar
troy
 
Posts: 27
Joined: Fri Oct 24, 2003 8:49 pm
Location: Washington, DC

Postby IT2Be » Mon Oct 22, 2007 6:52 pm

No help now, I know.
But we have been told that Servoy 4.0 will be your friend :)
Marcel J.G. Trapman (IT2BE)
SAN partner - Freelance Java and Servoy
Servoy Components - IT2BE Plug-ins and Beans for Servoy
ServoyForge - Open Source Components for Servoy
User avatar
IT2Be
Servoy Expert
 
Posts: 4766
Joined: Tue Oct 14, 2003 7:09 pm
Location: Germany

More Advanced Javascript capabilities planned?

Postby Thomas Parry » Wed Jan 30, 2008 4:43 am

Since the original post I wonder what there will be in 4.x for the use of the Rhino prototype.

For that matter does anyone know the actual Rhino javascript version in use by Servoy? I think I remember seeing someplace someone suggesting that the javascript is a little ancient and could use a later version.

I am of course hoping that objects and similar could be created so that as developers we are able to better manage our code. For example if we could crate a base class and then some specialized classes without having to repeat methods all over the place like now then I think we can improve our efficiency.
Thomas Parry
 
Posts: 498
Joined: Thu Jan 10, 2008 8:48 pm
Location: Ottawa, Canada

Postby Thomas Parry » Fri Feb 01, 2008 6:54 pm

I have been playing with Troy's code and want to make it clear that the sample prototype only works as he says in the parentheses "established object". To clarify, this means use an established Servoy object. It does not work for your own.

For example the following code snippet shows that any "established object" can exploit the prototype:

Code: Select all
Array.prototype.add = new Function('a','b','return a+b');
var tmp = [];//any instance of an array will do - we will make it empty
var result = tmp.add(2,7);
application.output('result=' + result);

String.prototype.mult = new Function('x', 'y', 'return x * y');
var temp = '';//any old string will do, but make it empty to conserve resources

var z = temp.mult(5, 9);
application.output('z=' + z);


I reused his example of the Array then used String to show you that it can be applied to other established objects. Also note that the
Code: Select all
var temp = '';
merely instantiates a new object of that type so that we can then use the new function created.

However if one tries this:

Code: Select all
var MyObject = new Object();
MyObject.prototype.add = new Function('a','b','return a+b');


then you will find that at execution that the "prototype" is not defined.

However if we then do this:
Code: Select all
var MyObject = new Object();
MyObject.add = new Function('a','b','return a+b');
application.output(MyObject.add(8,3)) //returns 11


Then the code executes ok. However we have not created a prototype! Only a new function in the Object called MyObject.
This is still useful but not as useful as in creating real prototypes. (If you leave off the var in front of the MyObject declaration then it should be a global).

SO if Servoy could come up with an "empty" established Object, rather than mess around with other objects such as the Array and String that I used here, that has prototype already then we as users could extend it???

Perhaps the adoption of the latest Rhino in release 4.x will allow some other freedoms?
Thomas Parry
 
Posts: 498
Joined: Thu Jan 10, 2008 8:48 pm
Location: Ottawa, Canada

Re: Adv. javascript support -- function keyword

Postby mxvanzant » Tue Sep 09, 2008 7:27 pm

This worked for me - note the use of the eval() function as well as splitting "function" into "...f" + "unction...":

Code: Select all
jsLib = new Object();
jsLib.exceptionCodes = new Object();
jsLib.exceptionCodes.missingData = "missingData";

var vcode = "jsLib.exception = f" + "unction (code, text) { \
  if(text.length > 5 && text.substring(0,5) == 'i18n:') \
    text = i18n.getI18NMessage(text); \
  this.code = code; \
  this.text = text; \
} \
";
eval(vcode);


Code: Select all
//can now be used like this:
var vex = new jsLib.exception(jsLib.exceptionCodes.missingData, "i18n:lbl.my_message_here");
throw vex;
...
Mike VanZant
mxvanzant@yahoo.com
vanzant@orangeloft.com
Orange Loft LLC
mxvanzant
 
Posts: 17
Joined: Fri Aug 24, 2007 5:33 pm
Location: Wheeling, IL (Chicago burb)

Re: Adv. javascript support -- function keyword

Postby BulldogBen » Wed Jul 07, 2010 11:44 am

Is prototyping supported in Servoy 5?

Relating to this post of mine: http://www.servoy.com/forum/viewtopic.php?f=3&t=14433...

I am interested in writing a parent method (called Journal), then specialising it for various uses such as Journal.Transfer or Jourlal.VATReturn, etc.

Before I go to the trouble of learning JavaScript prototyping, inheritance, etc I'd like to know the current limitations of Servoy 5.1

With thanks

Ben
27" iMac, MacOS 10.6.4
Servoy 5.2 / SQL Anywhere 11
Java 1.6.0_20
User avatar
BulldogBen
 
Posts: 58
Joined: Sun Jun 20, 2010 1:02 pm


Return to Discuss Feature Requests

Who is online

Users browsing this forum: No registered users and 14 guests