TwinaForms Help
Using Custom JavaScript in TwinaForms.
Custom JavaScript lets you add browser-side automation to a published TwinaForms form. Use it for advanced field syncing, light custom behavior, and interaction patterns that go beyond the standard builder settings.
Where to add it
In TwinaForms Designer:
- Open the form.
- Open Form Settings.
- Open Advanced.
- Click Edit Custom JavaScript.
- Paste your code and save.
- Republish the form.
Basic pattern
Most scripts use the same simple structure:
(function (TwinaForms) {
function syncSomething() {
const source = TwinaForms.getValue("text5") || "";
TwinaForms.setValue("text6", source);
}
TwinaForms.on("change", function () {
syncSomething();
});
syncSomething();
})(TwinaForms);
That gives you two important behaviors:
- the script reacts when the user changes a field
- the form also starts in the correct state on first load
Writing several functions
A form can have as many Custom JavaScript functions as you need. Two patterns work well — pick whichever fits the code you are writing.
Pattern A — one IIFE, multiple helpers
Use this when your functions share helpers or need to run together on the same event.
(function (TwinaForms) {
function updatePhoneCode() { /* ... */ }
function updateFullName() { /* ... */ }
function updateSfDatetime() { /* ... */ }
function syncAll() {
updatePhoneCode();
updateFullName();
updateSfDatetime();
}
TwinaForms.on("change", syncAll);
syncAll(); // initial state
})(TwinaForms);
Pattern B — separate IIFEs per concern
Use this when the concerns are unrelated. Each block is self-contained, so you can copy, paste, or remove one without breaking the others.
// Block 1: phone code sync
(function (TwinaForms) {
function updatePhoneCode() { /* ... */ }
TwinaForms.on("change", updatePhoneCode);
updatePhoneCode();
})(TwinaForms);
// Block 2: GMT-to-SF datetime
(function (TwinaForms) {
function updateSfDatetime() { /* ... */ }
TwinaForms.on("change", updateSfDatetime);
updateSfDatetime();
})(TwinaForms);
Examples
These examples use internal field IDs like text5, text6, and checkbox11. Use the actual field IDs from your form.
Build full name from two fields
Assume text1 is first name, text2 is last name, and text3 is full name.
(function (TwinaForms) {
function updateFullName() {
const first = (TwinaForms.getValue("text1") || "").trim();
const last = (TwinaForms.getValue("text2") || "").trim();
const fullName = [first, last].filter(Boolean).join(" ");
TwinaForms.setValue("text3", fullName);
}
TwinaForms.on("change", function () {
updateFullName();
});
updateFullName();
})(TwinaForms);
Set a greeting based on country
Assume text5 is country and text7 is greeting.
(function (TwinaForms) {
function updateGreeting() {
const country = TwinaForms.getValue("text5") || "";
if (country === "Israel") {
TwinaForms.setValue("text7", "Shalom");
return;
}
if (country === "Spain") {
TwinaForms.setValue("text7", "Hola");
return;
}
TwinaForms.setValue("text7", "Hello");
}
TwinaForms.on("change", function () {
updateGreeting();
});
updateGreeting();
})(TwinaForms);
Country to phone country code
Assume text5 is the country field and text6 is the phone code field.
(function (TwinaForms) {
const phoneCodes = {
"Israel": "+972",
"United States": "+1",
"Canada": "+1",
"United Kingdom": "+44",
"Germany": "+49",
"France": "+33",
"Spain": "+34",
"Italy": "+39"
};
function updatePhoneCode() {
const country = TwinaForms.getValue("text5") || "";
TwinaForms.setValue("text6", phoneCodes[country] || "");
}
TwinaForms.on("change", function () {
updatePhoneCode();
});
updatePhoneCode();
})(TwinaForms);
Show a section only when a checkbox is checked
Assume checkbox11 controls a section whose element id is sectionPromo.
(function (TwinaForms) {
function syncSection() {
const checked = TwinaForms.getValue("checkbox11") === true;
if (checked) {
TwinaForms.showElement("sectionPromo");
} else {
TwinaForms.hideElement("sectionPromo");
}
}
TwinaForms.on("change", function () {
syncSection();
});
syncSection();
})(TwinaForms);
GMT with Salesforce — write an SF Datetime value
Detects the submitter's current timezone (including Daylight Saving automatically), combines it with a Date field and a Time field, and writes an ISO 8601 string like 2026-04-23T14:30:00+03:00 into a hidden Text field. Map that hidden field to a Salesforce Datetime column on the Submit action. SF stores it in UTC and renders in each user's locale.
Assume date1 is the date the user picks, time1 is a TwinaForms Time field (HH:mm), and text5 is the hidden Text field submitted to SF.
(function (TwinaForms) {
function pad(n) {
return String(n || 0).padStart(2, "0");
}
function offsetPart() {
var minutes = -new Date().getTimezoneOffset();
var sign = minutes >= 0 ? "+" : "-";
var m = Math.abs(minutes);
return sign + pad(Math.floor(m / 60)) + ":" + pad(m % 60);
}
function datePart() {
var val = TwinaForms.getValue("date1");
if (val) return String(val);
var d = new Date();
return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
}
function timePart() {
var val = TwinaForms.getValue("time1");
if (val) {
var p = String(val).split(":");
return pad(p[0]) + ":" + pad(p[1]) + ":" + pad(p[2]);
}
var d = new Date();
return pad(d.getHours()) + ":" + pad(d.getMinutes()) + ":" + pad(d.getSeconds());
}
function updateSfDatetime() {
var iso = datePart() + "T" + timePart() + offsetPart();
TwinaForms.setValue("text5", iso);
}
TwinaForms.on("input", updateSfDatetime);
TwinaForms.on("change", updateSfDatetime);
updateSfDatetime();
})(TwinaForms);
Notes:
- Half-hour timezones (India +05:30, Iran +03:30, Newfoundland -03:30) render correctly.
- Privacy-hardened browsers (Tor, Firefox with privacy.resistFingerprinting) always report UTC. The script still produces valid ISO; it just records +00:00 for those users.
- The Time field returns HH:mm. The script adds seconds as :00 when needed.
- If the Time field is empty, the script uses the current browser time on page load or field change.
- To store midnight instead of the current time when the Time field is empty, replace the last three lines of timePart() with return "00:00:00";.
Good practices
- Keep scripts short and focused.
- Prefer TwinaForms.getValue() and TwinaForms.setValue() over direct DOM selectors.
- Republish after saving new code.
- Test with realistic form values.
Avoid
- very large scripts
- code that depends heavily on the page HTML structure
- untrusted copied code