Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

You have a form with three controls and you have assigned them Names N1, N2 and T respectively. When the user enters a value in either N1 or N2 you want to set the value of T to the sum of N1 and N2. The rule would be written as

Code Block
languagejavascript
themeConfluence
languagejavascript
T.value = N1.value + N2.value;

...

Code Block
if (form.load) {
  var an = _data.getParameter ("flow.activity.name");
  if (an === 'Manager' || an === 'VP'){
    ManagerApproval.visible = true;
  } else {
    ManagerApproval.visible = false;
  }
}

...

The 1st rule "Load Products" populates both the visible and hidden dropdowns with options from a database.

Code Block
/*member descriptionproductCode, productIdproductName, resultSet */
var x;
  
if (form.load) {
  eval('x=' + http.get('httphttps://localhost:8082app.frevvo.com/database/BIRT/productsallProducts'));   
  
    var opts1 = [];
     var opts2 = [];
  
    for (var i=0; i < x.resultSet.length; i++) {
         if (x.resultSet[i]) {
             opts1[i] = x.resultSet[i].descriptionproductName;
             opts2[i] = x.resultSet[i].productIdproductCode;
        }
    }
  
   Products.options = opts1;
  PID.options = opts2;
  Products.value = opts1[0]; // default to 1st product option
  PID.value = opts2[0];

}

Finding a Selected Options Index

The 2nd rule Select Product ID keeps the hidden PID dropdown syncronized synchronized with the visible Products dropdown.

Code Block
}
if (Products.value.length > 0)

{
     var i;
     for (var x in Products.options) {
        if ((Products.value + '=' + Products.value) === Products.options[x]){
             i = Products.options.indexOf(Products.options[x]);
        }
    }
 
  PID.value = PID.options[i] + ''.split('=')[0];

}

In v4 rules using hidden dropdowns to keep descriptive option labels visible to the user while keeping cryptic database values hidden are often no longer necessary. Dropdown options have values distinct from the human visible option labels. The above can now be achieved with a single simpler rule:

...

You can style this form so the comment input controls align with the checkbox options. See details and download a working sample form here

Code Block
var heartProblem = false;
var foodAllergy = false;
var rashes = false;
var jointInjury = false;
var asthma = false;
var moodiness = false;

for (var i = 0; i < MedicalIssues.value.length; i++)
{
  if (MedicalIssues[i].value === 'heart_problem') {
    heartProblem = true;
  } else if (MedicalIssues[i].value === 'food_allergy') {
    foodAllergy = true;
  } else if (MedicalIssues[i].value === 'rashes') {
    rashes = true;
  } else if (MedicalIssues[i].value === 'joint_injury') {
    jointInjury = true;
  } else if (MedicalIssues[i].value === 'asthma') {
    asthma = true;
  } else if (MedicalIssues[i].value === 'moodiness') {
    moodiness = true;
  }
}

if (heartProblem === true) {
  heartProblemDetails.visible = true;
  heartProblemDetails.required = true;
} else {
  heartProblemDetails.visible = false;
  heartProblemDetails.required = false;
  //heartProblemDetails.value = null;
}

if (foodAllergy === true) {
  foodAllergyDetails.visible = true;
  foodAllergyDetails.required = true;
} else {
  foodAllergyDetails.visible = false;
  foodAllergyDetails.required = false;
  //foodAllergyDetails.value = null;
}

if (rashes === true) {
  rashesDetails.visible = true;
  rashesDetails.required = true;
} else {
  rashesDetails.visible = false;
  rashesDetails.required = false;
  //rashesDetails.value = null;
}

if (jointInjury === true) {
  jointInjuryDetails.visible = true;
  jointInjuryDetails.required = true;
} else {
  jointInjuryDetails.visible = false;
  jointInjuryDetails.required = false;
  //jointInjuryDetails.value = null;
}

if (asthma === true) {
  asthmaDetails.visible = true;
  asthmaDetails.required = true;
} else {
  asthmaDetails.visible = false;
  asthmaDetails.required = false;
  //asthmaDetails.value = null;
}

if (moodiness === true) {
  moodinessDetails.visible = true;
  moodinessDetails.required = true;
} else {
  moodinessDetails.visible = false;
  moodinessDetails.required = false;
  //moodinessDetails.value = null;
}

...

T/F controls are simplified checkbox controls with only a single visible option. This rule makes the control named "s" visible if the T/F control named "agree" is checked and invisible if the T/F control named "agree" is checked/ unchecked.

Code Block
if (agree[0].value === 'true') {
  s.visible = true;
} else {
  s.visible = false;
}

...

Then write a rule that first sets up a javascript JSON syntax array with the contact information for each person. The rules then uses the dropdown value to index into the contantInfo contactInfo array to set the details for the selected person into four other form controls.

...

This form contains two rules. One is adding values entered into a column of assets and a column of liabilities and calculatng calculating netWorth. The 2nd rule is checking the value of netWorth and displaying an error message and marking netWorth invalid if liabilities exceed assets since the form designer does not want the form to be submitted in that state.

...

When a rule sets <control>.invalid the control background turns red and the submit button greys grays out just as if the user had entered an invalid value into a phone control. 

Frevvoproduct
treats it exactly the same way. This is a good way to dynamically control your form's valid state.

...

Today's Date and Time

Use

Frevvoproduct
' s built-in date and time methods to set your date, time, and date/time controls to the current date and time in the user's local timezone.

...

This rule makes the date control invalid if the date entered isn't before today's date.

Code Block
var// todayfrevvo =currentDate new Date(); 
var bd = method gets today in users timezone
var today = frevvo.currentDate().split('-');
var today_date = new Date(today[0], today[1]-1, today[2]); 
var bd = DOB.value.split('-'); 
var bd_date = new Date(bd[0],bd[1]-1,bd[2]);

if (bd_date.getTime() > today.getTime(_date)) { 
    MyMsg.value = 'Birth Date must be earlier than today!!!!';   
    DOB.valid = false; 
} else { 
    MyMsg.value = 'This is a good Birth Date: ' + DOB.value; 
    DOB.valid = true; 
}
Note

Use frevvo.currentDate() rather than the javascript new Date() since the latter gets today's date in the Live Forms server's timezone while the frevvo currentDate() correctly gets today's date in the user's timezone.

Date no more then 14 days from Today

...

Code Block
if (EventStartDate.value !== "") { 
    var date1 = DateUtil.today(); 
    var date2 = EventStartDate.value; 
    date1 = date1.split("-"); 
    date2 = date2.split("-"); 
    var sDate = new Date(date1[0]+"/"+date1[1]+"/"+date1[2]); 
    var eDate = new Date(date2[0]+"/"+date2[1]+"/"+date2[2]); 
    var days = Math.round((eDate-sDate)/86400000);
 
if (!eval(parseInt(days,10) > parseInt(-30,10))) { 
    EventStartDate.valid = false; 
    EventStartDate.status = "The date entered can only go back a maximum of 30 days from the current date. Please try again.";
 
} else { 
    EventStartDate.valid = true; 
}
}

 Add # of Years, Months or Days to a Date

Here is a rule that will add 3 years to a given date.  For example, to calculate the expiration date of a three year contract by adding three years to the starting date, your form could have two date controls, one used to enter the starting date and the other to show the contract expiration date. This rule will take the date from the StartingDate field, add 3 years to it and populate the result in a field named ExpirationDate.

...

Code Block
Traveler1.visible = false;
Traveler2.visible = false;
Traveler3.visible = false;
Traveler1.required = false;
Traveler2.required = false;
Traveler3.required = false;

for (var i=0; i < NumTickets.value; i++) {
 if (i >= 0) {
  Traveler1.visible = true;
  Traveler1.required = true;
 }
 if (i >= 1) {
  Traveler2.visible = true;
  Traveler2.required = true;
 }
 if (i >= 2) {
  Traveler3.visible = true;
  Traveler3.required = true;
 }
}

 

Tables

Tables are identical to repeat controls when referenced in business rules. Tables are a grid layout of repeating items. All the rule examples in this chapter that discuss repeats apply also to tables. The one important note is that you cannot explicitly name the repeat control inside your table. The repeat control inside a table is automatically named as <TableName>Repeat. For example a table named Expense automatically has a repeat named ExpenseRepeat. The rule ExpenseRepeat.itemAdded and ExpenseRepeat.itemIndex references an item added to your table and that item's index respectively.

...

Let's take a look at a simple example. Users are instructed to enter a capital Y in a table if they are planning on calling a customer. The user enters the "Y" then tabs to the company name column. The minus icon for that row will disappear.  

In this example, the name of the table control is CustomerTable and column 0 in the table is named ContactCustomer.

Here is the rule:

Code Block
for (var i=0; i<ContactCustomer.value.length; i++) {
    if (ContactCustomer[i].value === "Y") {
        CustomerTableItem[i].deletable = false;
    } else {
        CustomerTableItem[i].deletable = true;
    }
}

Notice the TableItem deletable property is set to false when a capital Y is entered in the first column. This will remove the minus icon for that row of the table. The for loop cycles through the table rows until the Max# property is reached. 

form.load

Clearing Values in a Table

This rule clears the values from all rows in a table. Notice the For loop that iterates over all the rows. Inside the loop a null value is assigned to all the columns in the table row.

Code Block
languagejs
 for (var i = 0; i < Col0.value.length; i++) { 
    Col0[i].value = null;
    Col1[i].value = null;
    Col2[i].value = null;
  } 

You cannot clear an entire table from a rule.

form.load

Rules can be used to initialize field values. This is a very useful feature and is often used to dynamically populate dropdown options from a database. Rules using form.load are triggered when a form first loads and when a workflow is loaded from a task list.

...

Code Block
/*member nextid results */
var x;
 
if (form.load) { 
    var readmethod = 
'http://www.frevvo.com/google/spreadsheets/query/u/<google username>/p/<google password>/s/SequentialNumberGenerator/w/Sheet1?media=json&query=formname="Checkbook"';
 
    var updatemethod = 
'http://www.frevvo.com/google/spreadsheets/update/u/<google username>/p/<google password>/s/SequentialNumberGenerator/w/Sheet1?media=json&query=formname="Checkbook"';
 
 
    eval('x=' + http.get(readmethod)); 
 
    var id = 'unknown'; 
 
    if (x.results === null) 
        { CheckNum.value = 'error'; 
    } else if (x.results.length === 0) { 
        CheckNum.value = 'No Match'; 
    } else { 
    id = x.results[0].nextid; 
    CheckNum.value = id; 
    id = id*1 + 1; 
    } 
 
    if (id !== 'unknown') { 
    eval('x=' + http.getput(updatemethod + '&updates=nextid=' + id + '&_method=put')); 
    } 
}

Unique ID

Forms such as invoices, bills of lading, etc often need to be stamped with a unique ID. The Sequential Number example is one approach, however it has some limitations. One is that you must guarantee that only one person at a time is filling out your form. This is because there is no mutex around the read and update of the Google spreadsheet cell.

...

A rule can dynamically display an image uploaded to your form via the upload control. In this example the upload control is named 'u'. The form also must contain a message control as a place holder for displaying the uploaded image. The rule dynamically creates a URL to the uploaded image in the

Frevvoproduct
temporary attachment repository. The upload control's value 'u.value' is a GUID that uniquely identifies the attachment. The uploaded image will be included in the submissions pdf.

Code Block
languagejavascript
if (u.value.length > 0) {
  var baseUrl = _data.getParameter('_frevvo_base_url') + 
      ""/frevvo/web/tn/" +
      _data.getParameter('tn.id') +
      "/user/"+_data.getParameter('user.id') +
      "/app/"+_data.getParameter('app.id') +
      "/form/"+_data.getParameter('form.id');
 
  im.value = "'<img src="'" +
         baseUrl + "'/attachment/"' + u.value+"'/does_not_matter'"/>"';
} 

Here is the example form before and after the user has upload the orangegrovefrevvo.logo,orange.png image:

Section
Column

Column

...

The section control contains controls that are the search critiera criteria for finding a RACF ID based on other pieces of information you may know about an employee such as name, type, email address. The values entered into the search criteria can be partial values. For instance entering a name "Smith" will find all employees whose name contains the letters "Smith". If you also select email, it will find all employees whose name contains "Smith" and have an email address containing the string "frevvo".

...