reBB Documentation

Working with Javascript

A friendly note about JavaScript in reBB: JavaScript can make your forms much more powerful and user-friendly! While we've built reBB to be safe and secure, JavaScript is inherently powerful—that's what makes it so useful. We encourage you to experiment and create amazing forms, but please use these capabilities responsibly. Avoid collecting sensitive information without consent, and remember that all code runs in the user's browser. While we have implemented some security measures for javascript, we can't cover every possible exploit. Keep in mind that abuse will result in you being banned/blocked from using reBB. Think of it as being a good neighbor in our form-building community. If you have questions or need guidance, don't hesitate to reach out! You can read more regarding security here.

Working with JavaScript in reBB Forms

JavaScript adds powerful dynamic capabilities to your forms in the Standard Editor. This guide will help you harness these capabilities to create intelligent, responsive forms.

Note: JavaScript features are only available in the Standard Editor, not in the Basic Editor.

Where to Use JavaScript in Forms

The Standard Editor provides several specific places to add JavaScript code:

1. Custom Default Value

  • Location: In component settings under the "Data" tab
  • Purpose: Set dynamic initial values for components
  • Available variables:
    • component - The current component configuration
    • moment - The moment.js library for date/time operations
    • window - The browser window object

2. Custom Validation

  • Location: In component settings under the "Validation" tab
  • Purpose: Create custom rules to validate user input
  • Available variables:
    • input - The current value of the component
    • component - The current component configuration
    • valid - Boolean value to set (true if valid, false if invalid)
    • data - All current form data

3. Calculated Value

  • Location: In component settings under the "Data" tab
  • Purpose: Derive a component's value from other form fields
  • Available variables:
    • component - The current component configuration
    • data - All current form data
    • row - The current row data (if in a datagrid)
    • rowIndex - The current row index (if in a datagrid)
    • value - The value to set for this component

4. Custom Conditional

  • Location: In component settings under the "Conditional" tab
  • Purpose: Control when a component is displayed
  • Available variables:
    • component - The current component configuration
    • data - All current form data
    • show - Boolean value to set (true to show, false to hide)

JavaScript Examples by Use Case

Setting Dynamic Default Values

// Set today's date as default value
value = new Date().toISOString().split('T')[0];

// Generate a random ID
value = "ID-" + Math.floor(Math.random() * 100000);

// Set default based on time of day
var hour = new Date().getHours();
if (hour < 12) {
    value = "Good morning!";
} else if (hour < 18) {
    value = "Good afternoon!";
} else {
    value = "Good evening!";
}

Creating Custom Validation Rules

// Ensure password meets complexity requirements
var hasUpperCase = /[A-Z]/.test(input);
var hasLowerCase = /[a-z]/.test(input);
var hasNumbers = /\d/.test(input);
var hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(input);
valid = input.length >= 8 && hasUpperCase && hasLowerCase && hasNumbers && hasSpecial;

// Validate against a list of allowed values
valid = ['apple', 'orange', 'banana', 'grape'].includes(input.toLowerCase());

// Ensure end date is after start date
valid = new Date(input) > new Date(data.startDate);

Calculating Values from Other Fields

// Calculate total price from quantity and unit price
value = data.quantity * data.unitPrice;

// Calculate BMI from height and weight
// Height in cm, weight in kg
value = (data.weight / ((data.height / 100) * (data.height / 100))).toFixed(1);

// Concatenate first and last name
value = data.firstName + ' ' + data.lastName;

// Format phone number
if (data.phoneNumber) {
    value = data.phoneNumber.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

Showing/Hiding Components Conditionally

// Show shipping address only when "Same as billing" is unchecked
show = !data.sameAsBilling;

// Show certain fields based on selection
show = data.paymentMethod === 'creditCard';

// Show based on multiple conditions
show = data.age >= 18 && data.country === 'US';

Working with Cookies

reBB provides built-in cookie functions to save and restore user input across sessions:

Saving Values to Cookies

Use this in the Custom Conditional area to save values when they change:

// Save the current field value for 30 days
setCookie(component.key, value, 30);

// Save with a custom name
setCookie('userPreference', value, 60);

Getting Values from Cookies

Use this in the Custom Default Value area to load saved values:

// Get value from a cookie with the same name as the component key
value = getCookie(component.key);

// Provide a default if cookie doesn't exist
value = getCookie(component.key) || 'Default value';

Practical Example: Remembering User Information

To create a form that remembers user information:

  1. For each field you want to remember (like name, email, etc.):

    A. Set the Custom Default Value:

    value = getCookie(component.key) || '';

    B. Add a Custom Conditional:

    // Save whenever the value changes
    setCookie(component.key, value, 30);
    show = true; // Always show this field
  2. Now when users return to your form, their previous inputs will automatically appear.

Advanced JavaScript with Datagrids

Datagrids require special handling in JavaScript functions:

Accessing the Current Row in a Datagrid

Within a component inside a datagrid:

// In a Calculated Value
// Access data from the same row
value = row.quantity * row.price;

// Get the current row's index (position)
value = "Item " + (rowIndex + 1);

Calculations Across All Rows

For a component outside a datagrid that needs to process all rows:

// Calculate sum across all rows of a datagrid
var total = 0;
if (data.orderItems && Array.isArray(data.orderItems)) {
    // Loop through all rows (skip index 0 in reBB datagrids)
    for (var i = 1; i < data.orderItems.length; i++) {
        total += Number(data.orderItems[i].price || 0);
    }
}
value = total;

Creating Inter-dependent Fields

You can create fields that react to changes in other fields:

Example: Dynamic Options Based on Selection

  1. Create a select component for "Category" with options like "Fruit", "Vegetable", "Meat"
  2. Create another select component for "Item"
  3. In the "Item" component, use Custom Data Source with JS:
// In Advanced tab > Custom Data Source (JS)
values = [];

if (data.category === 'Fruit') {
    values = [
        {label: 'Apple', value: 'apple'},
        {label: 'Banana', value: 'banana'},
        {label: 'Orange', value: 'orange'}
    ];
} else if (data.category === 'Vegetable') {
    values = [
        {label: 'Carrot', value: 'carrot'},
        {label: 'Broccoli', value: 'broccoli'},
        {label: 'Spinach', value: 'spinach'}
    ];
} else if (data.category === 'Meat') {
    values = [
        {label: 'Beef', value: 'beef'},
        {label: 'Chicken', value: 'chicken'},
        {label: 'Pork', value: 'pork'}
    ];
}

// Always return values variable
return values;

Security Considerations

When using JavaScript in your forms:

  1. Be aware that all JavaScript runs in the user's browser
  2. Avoid handling truly sensitive information (use proper backend systems instead)
  3. Don't use JavaScript to bypass security measures
  4. Remember that users will see security warnings for forms with potentially risky JavaScript

By following these guidelines, you can create dynamic, intelligent forms that provide excellent user experiences while maintaining security and performance.