Friday, August 26, 2011

Servoy TIP: Calculating Age

Calculating the age of something (or someone) is a task that I come across a lot. Here's a simple function that will help get you the basics:

function getAge(myDate){
  // myDate= new Date("7/12/1968")
  var now = new Date();
  var yr = now.getFullYear() - myDate.getFullYear();
  var mo = now.getMonth() - myDate.getMonth();
  if(mo < 0) {
  mo = myDate.getMonth() - now.getMonth();
  }
  var days = now.getDate() - myDate.getDate();
  if(days < 0) {
  days = myDate.getDate - now.getDate();
  }
  var agestr = yr + " years, " + mo + " months, " + days + " days";
  plugins.dialogs.showInfoDialog("Date DIff", agestr,"OK");

}
You can (should) enhance the function by checking the years, months and days for plurality and modifying the strings accordingly:

function getAge(myDate){
  // myDate= new Date("7/12/1968")
  var now = new Date();
  var yrTxt = "year";
  var moTxt = "month";
  var dayTxt = "day";

  var yr = now.getFullYear() - myDate.getFullYear();
  if(yr != 1) {
  yrTxt += "s";
  }
  var mo = now.getMonth() - myDate.getMonth();
  if(mo < 0) {
  mo = myDate.getMonth() - now.getMonth();
  }
  if(mo != 1) {
  moTxt += "s"
  }
  var days = now.getDate() - myDate.getDate();
  if(days < 0) {
  days = myDate.getDate - now.getDate();
  }
  if(days != 1) {
  dayTxt += "s";
  }
  var agestr = yr + " " + yrTxt + ", " + mo + " " + moTxt + ", " + days + " " + dayTxt;
  plugins.dialogs.showInfoDialog("Date DIFF", agestr,"OK");

}

Happy age calculating...

Friday, August 19, 2011

Servoy TIP: How To Trap For Modifier Keys

When you're developing your solution - there are times where you want to know if the user had any modifier keys pressed when they performed the action (drag and drop, right click, shift key down, etc.). Servoy returns a number for each key that is held down and, if you add up the numbers, you can tell which keys are down.

Luckily, there's a really straightforward to accomplish this - and it's all held in the event that triggered your method.
if ((event.getModifiers() & JSEvent.MODIFIER_SHIFT) != 0) {
   application.output("shift")
} else if ((event.getModifiers() & JSEvent.MODIFIER_ALT & JSEvent.MODIFIER_CTRL) != 0 ) {
   appliction.output ("alt and ctrl");
}
The operator is a bit operator - that's why you have to use this type of syntax - but since there are event constants (under Application -> JSEvent in the Solution Explorer) - it's easy to check for whatever key combination you want!

You can also tell what type of action the user was doing (as well as any key combinations) - by using the event.getType() function. Here's an example:
if (event.getType() == JSEvent.ACTION) {
   application.output("user clicked");
} else if (event.getType() == JSEvent.RIGHTCLICK) {
   application.output("user right clicked");
} else if (event.getType() == JSEvent.DOUBLECLICK) {
   application.output("user double clicked");
}
There are other even type constants you can take advantage of including: action, datachanged, focuslost, focusgained, none (for unknown types), ondrag, ondragover, ondrop and rightclick.

Thursday, August 11, 2011

Servoy TIP: Leap Year Function

There may be times in your solution when you need to see if a certain year is a leap year. Here's the basic rules to determine if a date is a leap year or not:

A year will be a leap year if it is divisible by 4 but not by 100. If a year is divisible by 4 and by 100, it is not a leap year unless it is also divisible by 400.

So, as always is the case when you use JavaScript - there are many different ways to get this done. I've seen some very long functions that use  the "brute force" method to parse the date and check the year. Here's one example (modified for copy/paste use in Servoy 4+):
function isleap(yr)
{
 if ((parseInt(yr)%4) == 0)
 {
  if (parseInt(yr)%100 == 0)
  {
    if (parseInt(yr)%400 != 0)
    {
    application.output("Not Leap");
    return "false";
    }
    if (parseInt(yr)%400 == 0)
    {
    application.output("Leap");
    return "true";
    }
  }
  if (parseInt(yr)%100 != 0)
  {
    application.output("Leap");
    return "true";
  }
 }
 if ((parseInt(yr)%4) != 0)
 {
    application.output("Not Leap");
    return "false";
 }
}
However, there's a MUCH easier way to do the same thing:
function isLeap(yr) {
 return new Date(yr,1,29).getDate() == 29;
}
This function simply creates a new date with the year you pass in and February as the month (JavaScript months start at 0=January... yeah, I know - I HATE that as well!) and 29th as the day. JavaScript will auto-convert this to either Feb 29, yr - OR March 1, yr. So if the day that gets returned is the 29th - it's a leap year, if not, then it's not a leap year.

You can also test if your calculation is working - by looking at this list of all leap years 1800-2400.

Friday, August 5, 2011

Servoy TIP: Setting or Passing Multiple Variables At Once

Servoy methods are JavaScript (or Java) functions - and in today's tip I'm going to show you how to initialize multiple variables at once and how to use an array to send multiple values as parameters to a different method.

Let's start with the easy one first - initializing multiple variables to a single value. Now, keep in mind - there is no "right way" to do this - it's a matter of your personal preference and it also depends on how readable you want your code to be.

A best practice, and a good habit to get into, is to declare all the variables you're going to use in your method at the top of your method. This way, they're all in one place, and it's easy to assign default values. To demonstrate, here's some code:
var formName = null;
var showPreview = null;
var hasRecords = null;
var whatReport = "Customers";
var useDefaults = 1;
In JavaScript - rather than having each command on its own line, you can combine commands (that end with a semi-colon) into a single line. So we could reduce 5 lines to 1 - but it's much less readable:
var formName = null; var showPreview = null; var hasRecords = null; var whatReport = "Customers"; var useDefaults = 1;
So rather than putting all in a single line - you can reduce the top code to 3 lines - by defining all the variables with a single value into a single line:
var formName, showPreview, hasRecords = null;
var whatReport = "Customers";
var useDefaults = 1;
Now that we've set our variables - let's say we want to call another method and pass all the variables to that method. We could do it a couple of different ways - depending on how we define the incoming parameter list on our function.

For example - we have two methods - one called setVariables() and one called doAction(). The setVariables() function will just set the variables like we did above and then it will call to doAction() method:
function setVariables()  var formName, showPreview, hasRecords = null;  var whatReport = "Customers";  var useDefaults = 1;  doAction (formName, showPreview, hasRecords, whatReport, useDefaults);end function
Then when we define the doAction method - we define it like this:
function doAction( formName, showPreview, hasRecords, whatReport, useDefaults)
  //my actions here
end function
This is the best, and most readable way to accomplish passing the parameters. This will allow you to use all the variables in the doAction method just as they're specified and passed.

However, there may be times when you need to package more information into a single variable. Each variable you pass to a function does not have to be a single value - they can be any object that Servoy supports! That means you can pass arrays, record objects - even entire foundsets between methods! Here's an example:
function setVariables()
  var formName, showPreview = null;
  var hasRecords = forms.customers.foundset;
  var whatReport = "Customers";
  var useDefaults = new Array[1,'blue','green'];
  doAction (formName, showPreview, hasRecords, whatReport, useDefaults);
end function
I hope this will help you with your Servoy development efforts! What other tricks to you guys use when passing/setting parameters?