Forsta API Method Examples

Forsta HX Platform - API Scripting Guide

Forsta API Method Examples

Using Forsta-Specific Methods

These examples use Forsta HX native methods like .domainValues(), .item(), .toBoolean(), and .set()

Example 1: Sum Multiple Checkbox Values

// Calculate total from selected checkboxes with numeric values
var totalSpend = 0; // Initialize total to zero

// Get array of all possible option codes for this checkbox question
var codes = f('BQ4c').domainValues();

// Loop through each option code
for (var i = 0; i < codes.length; i++) {
    // Check if this specific option is selected (returns true/false)
    if (f('BQ4c').item(codes[i]).toBoolean()) {
        // If selected, get its numeric value and add to running total
        totalSpend = totalSpend + f('BQ4c').item(codes[i]).toNumber();
    }
}

// Set the calculated total to the TotalSpend question
f('TotalSpend').set(totalSpend);
console.log('Total: ' + totalSpend); // Log for debugging

Example 2: Count Selected Items

// Count how many checkboxes are selected
var selectedCount = 0;
var codes = f('AQ1').domainValues();

codes.forEach(function(code) {
    if (f('AQ1').item(code).toBoolean()) {
        selectedCount++;
    }
});

f('SelectedCount').set(selectedCount);

Example 3: Check for Specific Combinations

// Check if user selected both option "1" AND option "3"
var hasOption1 = f('BQ2').item('1').toBoolean();
var hasOption3 = f('BQ2').item('3').toBoolean();

if (hasOption1 && hasOption3) {
    f('BQ2a').show(); // Show follow-up
} else {
    f('BQ2a').hide();
}

Example 4: Calculate Average from Grid

// Calculate average rating from selected scale items
var codes = f('CQ1').domainValues(); // Get all option codes
var sum = 0; // Initialize sum
var count = 0; // Initialize counter

// Loop through each option
for (var i = 0; i < codes.length; i++) {
    // Check if this option is selected
    if (f('CQ1').item(codes[i]).toBoolean()) {
        // Add the numeric value to sum
        sum += f('CQ1').item(codes[i]).toNumber();
        count++; // Increment count of selected items
    }
}

// Calculate average (prevent division by zero)
// Ternary operator: condition ? valueIfTrue : valueIfFalse
// .toFixed(2) rounds to 2 decimal places
var average = count > 0 ? (sum / count).toFixed(2) : 0;

// Set the calculated average
f('AverageRating').set(average);

Example 5: Validate Minimum/Maximum Selections

// Ensure user selects between 2-5 options
function validateSelectionRange() {
    var codes = f('DQ1').domainValues();
    var selectedCount = 0;
    
    codes.forEach(function(code) {
        if (f('DQ1').item(code).toBoolean()) {
            selectedCount++;
        }
    });
    
    if (selectedCount < 2) {
        alert('Please select at least 2 options');
        return false;
    }
    
    if (selectedCount > 5) {
        alert('Please select no more than 5 options');
        return false;
    }
    
    return true;
}

Example 6: Get Selected Values as Array

// Build array of selected numeric values
function getSelectedValues(qid) {
    var codes = f(qid).domainValues();
    var values = [];
    
    codes.forEach(function(code) {
        if (f(qid).item(code).toBoolean()) {
            values.push(f(qid).item(code).toNumber());
        }
    });
    
    return values;
}

// Usage
var selected = getSelectedValues('EQ1');
console.log('Selected values:', selected); // [10, 25, 50]
var total = selected.reduce(function(sum, val) {
    return sum + val;
}, 0);

Example 7: Set Multiple Values

// Pre-populate questions with calculated values
var income = 50000;
var taxRate = 0.25;
var afterTax = income * (1 - taxRate);

f('Income').set(income);
f('TaxRate').set(taxRate * 100); // Show as percentage
f('AfterTax').set(afterTax);

Example 8: Compare Two Questions

// Check if same items selected in two different questions
function compareSelections(q1, q2) {
    var codes = f(q1).domainValues();
    var matches = 0;
    
    codes.forEach(function(code) {
        var q1Selected = f(q1).item(code).toBoolean();
        var q2Selected = f(q2).item(code).toBoolean();
        
        if (q1Selected && q2Selected) {
            matches++;
        }
    });
    
    return matches;
}

// Usage
var matchCount = compareSelections('AQ1', 'BQ1');
f('MatchCount').set(matchCount);

Example 9: Generate Unique Patient ID (Production Only)

/**
 * threeDigitString - Pads a number to 3 digits with leading zeros
 * @param {number} iNum - The number to pad (e.g., 1, 12, 123)
 * @returns {string} - Zero-padded string (e.g., "001", "012", "123")
 * @description Converts a number to a string and prepends zeros
 *              until the string is exactly 3 characters long.
 *              Useful for generating sequential IDs like "P001", "P002".
 */
function threeDigitString(iNum) {
    var sNum = String(iNum); // Convert number to string
    // Keep adding leading zeros until we have 3 digits
    while (sNum.length < 3) {
        sNum = "0" + sNum; // Prepend a zero
    }
    return sNum; // Returns "001", "002", etc.
}

// Only run this in production environment
if (IsInProductionMode()) {
    // Check if userid field has a value
    if (f('userid').toBoolean()) {
        var patNum = 1; // Start with patient number 1
        var patNumString = threeDigitString(patNum); // Convert to "001"
        
        // Create unique ID: userid + patient number (e.g., "john001")
        var uidPatString = f('userid').toString().toLowerCase() + patNumString;
        
        // Keep incrementing until we find a unique ID not in database
        while (isFieldValueTaken('uidPatnum', uidPatString)) {
            patNum++; // Try next number
            patNumString = threeDigitString(patNum); // Format it
            // Rebuild the unique string
            uidPatString = f('userid').toString().toLowerCase() + patNumString;
        }
        
        // Only set PatientNumber if it doesn't already have a value
        if (!f('PatientNumber').toBoolean()) {
            f('PatientNumber').set(patNum); // Save the patient number
        }
    }
}

Key methods: .toBoolean() checks if field exists, .toString() converts to string, IsInProductionMode() ensures production environment, isFieldValueTaken() validates uniqueness on server.

Example 10: Check Field Exists Before Setting

// Only set value if field doesn't already have one
if (!f('UniqueID').toBoolean()) {
    var newID = generateUniqueID();
    f('UniqueID').set(newID);
}

// Check if field has value
if (f('userid').toBoolean()) {
    console.log('User ID exists: ' + f('userid').toString());
} else {
    console.log('No user ID found');
}

Example 11: Loop Through Grid and Set Patient IDs

// Generate patient IDs for each row in a loop/grid question
// Get array of all row codes (e.g., ["1", "2", "3"])
var arrRows = f('ePatId').domainValues();

// Loop through each row in the grid
for (var i = 0; i < arrRows.length; i++) {
    var iRow = parseInt(arrRows[i]); // Convert row code to integer
    var patSuffix; // Variable to store the suffix we'll generate
    
    // Check if this is a test ID
    if (isTestID()) {
        // TEST MODE: Use simple numeric suffix like "P001", "P002"
        var sRow = String(iRow); // Convert row number to string
        
        // Pad with leading zeros to make 3 digits
        while (sRow.length < 3) {
            sRow = "0" + sRow; // "1" → "001"
        }
        patSuffix = "P" + sRow; // Result: "P001", "P002", etc.
    }
    else if (f('userid').toBoolean()) {
        // PRODUCTION MODE: Generate unique suffix based on user
        var uid = f('userid').get(); // Get the user ID
        patSuffix = generatePatSuffix(uid, iRow); // Custom function
    }
    
    // If we successfully generated a suffix
    if (patSuffix) {
        // Combine user ID with suffix (e.g., "john" + "P001" = "johnP001")
        var patId = f('userid').get() + patSuffix;
        
        // Set this value for the specific row in the grid
        // .item(arrRows[i]) targets the specific row
        // .set(patId) sets the value for that row
        f('ePatId').item(arrRows[i]).set(patId);
    }
}

Key pattern: Use f('Qid').item(code).set(value) to set values for specific rows in loop/grid questions.