doo.model
The doo.model
object gives you access to the current record in Scripting within Tabidoo. Whether you're using scripts in form’s lifecycle (on model load, on model change, before model save), or in Workflow Automation, this object is the core way to read and modify field values.
What Is doo.model
?
doo.model
is a JavaScript object representing the data model of the current record. Each property corresponds to a field in your table.
General Properties and Methods
doo.model
contains all of the table fields and some other predefined properties:
doo.model.id
Returns internal record identifier (e.g. "865f8bac-ed8a-4979-972f-3f1706fb1bb1")
Example
const recordId = doo.model.id;
Here’s what doo.model.id
is useful for:
Example: Accessing the current record in another context
const record = await doo.table.getRecord('Orders', doo.model.id);
Example: Creating relationships between records
const record = await doo.table.createRecord('Order Row', { orderId: doo.model.id });
Example: Generating links (e.g., in emails or buttons)
const urlLink = `https://app.tabidoo.cloud/app/myApp/schema/orders?recordId=${doo.model.id}`
doo.model.ver
Holds the internal version number of the record. It’s incremented automatically every time the record is updated.
Version Values and Their Meaning
-1
— The record does not exist yet. You are in the form before the record is created (e.g., during the On Model Load of a new record).0
— The record has just been created (No updates yet).1+
— The record has been updated at least once.
You can use doo.model.ver
to apply different logic for new vs. existing records (e.g. Enable/Disable Field on form).
Example
if (doo.model.ver === -1) {
console.log('Record not created yet.');
} else {
console.log('Existing record with version:', doo.model.ver);
}
doo.model.isReadOnly
doo.model.isReadOnly
is a special property that, when set to true
, makes the entire form non-editable. It’s typically used to enforce business rules — for example, preventing edits to records with certain statuses or by unauthorized users.
Example
doo.model.isReadOnly = true; // Locks the entire form
Example: Make the form read-only for archived records
if (doo.model.status.value === 'Archived') {
doo.model.isReadOnly = true;
}
Example: Allow only admins to edit
if (!doo.currentUser.roles.includes('Admin')) {
doo.model.isReadOnly = true;
}
doo.model.isValid
doo.model.isValid
controls whether the form can be saved. By default, it is true
. If your script sets it to false
, Tabidoo will block form submission and notify the user with an error message.
This is useful for applying custom validations that go beyond field-level rules.
Example
doo.model.isValid = false; // Prevents the form from being saved
You typically use this in combination with some logic in the Before Model Save event.
Example: Custom validation across multiple fields
// Start date must be before end date.
if (doo.model.startDate.value > doo.model.endDate.value) {
doo.model.isValid = false;
}
doo.model.infoText
Assign a message to this property in case you want to show something in the form header.
Example
doo.model.infoText = 'Please double-check all fields before saving.';
doo.model.hideCategory()
Allows you to dynamically hide a specific tab (category) within a form. It is useful when you want to simplify the user interface or restrict access to sections of the form based on certain conditions.
- The argument is the label (header) of the tab as defined in the form.
- The category becomes hidden immediately when the script runs.
Example
doo.model.hideCategory('Advanced Settings');
Example: Hide a tab for new records
if(doo.model.ver === -1) {
doo.model.hideCategory('Internal Notes');
}
doo.model.showCategory()
doo.model.showCategory()
is used to reveal a tab (category) within a form that was previously hidden using doo.model.hideCategory()
. This method is useful when you want to show specific parts of the form only under certain conditions.
Example
doo.model.showCategory('Advanced Settings');
Example: Show category after field selection
if (doo.model.type.value === 'Custom') {
doo.model.showCategory('Customization Options');
}
doo.model.selectCategory()
Allows you to programmatically focus a specific tab (category) in a form. This is useful for improving user experience — guiding them to relevant parts of the form based on their input or actions.
- Switches the active tab in the form to the specified category.
- Has no effect if the category does not exist or is hidden.
Example
doo.model.selectCategory('Details');
Example: Focus on the first required tab
if (!doo.model.customer.value) {
doo.model.selectCategory('Customer Info');
}
Field-Level Properties and Methods
doo.model
is a JavaScript object that represents the data model of the current record. Each property corresponds to a field in your table. Each field (e.g., doo.model.status
) includes the following properties and methods:
doo.model.<field>.value
Allows you to get or set the current value of a specific field in the form/record. It’s the most commonly used property when working with data in scripts.
Example
const status = doo.model.status.value; // Reading a value
doo.model.priority.value = 'High'; // Setting a new value
You access fields using their internal name, not the visible label. For example, if your field label is Order Status and its internal name is status
, you use doo.model.status.value
.
value
reflects what's currently in the form — including unsaved changes.- Use
.setValue(...)
if you want more control or when working with linked fields.
Behavior by Data Type
Text / Long Text / Markdown
doo.model.firstname.value = 'John'; // Text field
doo.model.description.value = '<p>Hello!</p><p><br></p><p>How are you?</p>'; // Long text field
doo.model.pageContent.value = '# Headline\nText\n'; // Markdown field
Number / Decimal / Percentage / Money
doo.model.age.value = 10; // Number field
doo.model.length.value = 65.2543; // Decimal field
doo.model.vat.value = 0.1 // Percentage field
doo.model.cost.value = 999.99; // Money field
Money With Currency
doo.model.price.value = { amount: 10, currency: "USD", date: "2025-07-16T00:00:00" }; // Money with currency field
Checkbox (Yes/No)
doo.model.isPublic.value = true; // Checkbox field
Date / Datetime
doo.model.validFrom.value = new Date(); // Date field
Dropdown / Radio
doo.model.state.value = 'Done'; // Dropdown field
doo.model.choice.value = 'Single'; // Radio field
Multi choice / Tags
doo.model.colors.value = ['Red', 'Blue']; // Multi choice field
doo.model.tags.value = ['Garden', 'Outdoor']; // Tags field
URL/Mailto link
doo.model.email.value = { href: doo.currentUser.login, isMailto: true }; // Mailto link
doo.model.urlLink.value = { href: 'https://tabidoo.cloud', description: 'Link to Tabidoo' }; // URL link
List of checkboxes (Checklist)
const subtasks = doo.model.subtasks.value; // READ-ONLY
Chat
const chat = doo.model.chat.value; // READ-ONLY
Link to Table
doo.model.customer.value = { id: 'c56a4180-65aa-42ec-a945-5fd21dec0538' }; // Link to table (Lookup) field
Example: Setting a field based on a condition
if (doo.model.total.value > 1000) {
doo.model.discount.value = '10%';
}
doo.model.<field>.setValue(value)
The .setValue()
method is a convenient and reliable way to assign a value to a specific field in your form. It's especially useful for date fields and linked records, where direct assignment to .value
might not work as expected.
Example: Set a lookup field by full-text search
doo.model.customer.setValue('John Smith');
Example: Set a Links to many records field using a filter
doo.model.members.setValue({ filter: "surname(in)(Black)" });
Example: Set a Links to many records field in case we know the exact value of id
doo.model.members.setValue(['865f8bac-ed8a-4979-972f-3f1706fb1bb1']);
doo.model.<field>.originalValue
originalValue
gives you access to the initial value of a field before the user made any changes. It’s useful when you need to compare the current value (.value
) with what was originally loaded into the form.
Example
const original = doo.model.status.originalValue;
const current = doo.model.status.value;
if (original !== current) {
console.log('Status has been changed by the user.');
}
Example: Prevent specific field change
if (doo.model.status.originalValue === 'Approved' &&
doo.model.status.value !== 'Approved') {
doo.model.isValid = false;
doo.toast.warning('Approved status cannot be changed.');
}
Use Cases
- Detecting whether a user has updated a field.
- Logging or auditing changes before saving.
- Validating transitions (e.g., allowed status changes).
Notes
originalValue
is available as soon as the form loads.- It does not reflect unsaved intermediate changes — it’s always the last saved value.
- Best used in Before Save scripts or On Change when validating edits.
doo.model.<field>.currentlyChanged
currentlyChanged
is a boolean property available only in On Model Change scripts. It tells you whether the specific field that triggered the script was actually modified — avoiding unnecessary execution when the change event is triggered by other updates in the form.
Example
if (doo.model.status.currentlyChanged) {
console.log('The status field was changed by the user.');
}
This ensures that your logic runs only when the value truly changes — not when other fields update or the form is re-evaluated.
Example: Trigger logic only when a field changes
if (doo.model.discount.currentlyChanged) {
doo.model.total.value = recalculateTotal();
}
Notes
- Only available in
On Model Change
event scripts. - Helps reduce redundant logic executions.
- Prevents side effects from re-triggering scripts unnecessarily.
doo.model.<field>.isVisible
isVisible
is a boolean property that allows you to control the visibility of a field in the form. It’s commonly used to simplify the interface or show fields conditionally based on user input, roles, or record status.
Example
doo.model.comments.isVisible = false; // Hide the field
doo.model.notes.isVisible = true; // Show the field
Use this in On Model Load
or On Model Change
scripts to dynamically manage what users see.
Example: Show/Hide a field based on status
doo.model.resolution.isVisible = doo.model.status.value === 'Closed';
Example: Show field for admins only
if (doo.currentUser.roles.includes('Admin')) {
doo.model.internalNote.isVisible = true;
} else {
doo.model.internalNote.isVisible = false;
}
Notes
- Hidden fields are still part of the record — their values are retained unless you clear them manually.
- Use with caution when hiding required fields; validation may still fail unless you also adjust
isRequired
.
doo.model.<field>.isRequired
isRequired
is a boolean property that allows you to dynamically set whether a field must be filled before saving the form. It’s useful when required fields depend on other field values, user roles, or the current record state.
Example
doo.model.deadline.isRequired = true; // Make the field required
doo.model.notes.isRequired = false; // Make the field optional
This setting overrides the default configuration in the table definition for the current form session.
Example: Make a field required only for new records
if (doo.model.ver === -1) {
doo.model.responsible.isRequired = true;
}
Example: Conditionally require a field
if (doo.model.status.value === 'Closed') {
doo.model.resolution.isRequired = true;
}
Notes
- The user must fill in all required fields before saving; otherwise, the form is blocked.
- Combine with
isVisible
to ensure required fields aren’t hidden unintentionally. - Applies only during the current editing session — the original table setup remains unchanged.
doo.model.<field>.isEnabled
isEnabled
is a boolean property that allows you to enable or disable a field in the form. When disabled, the field becomes read-only and cannot be modified by the user, although its value can still be changed programmatically.
Example
doo.model.discount.isEnabled = false; // Disable input
doo.model.comment.isEnabled = true; // Enable input
This affects only the form UI — the field remains visible but grayed out when disabled.
Example: Lock a field based on record status
if (doo.model.status.value === 'Approved') {
doo.model.total.isEnabled = false;
}
Example: Disable field after first save
if (doo.model.ver >= 0) {
doo.model.orderNumber.isEnabled = false;
}
Notes
- Disabling a field does not clear its value or prevent the form from being saved.
- Use
doo.model.isReadOnly
to disable the entire form. isEnabled
is ideal for partial control — e.g. lock specific inputs while leaving others editable.
doo.model.<field>.filterForDropdown
filterForDropdown
allows you to filter available options in a Dropdown or Lookup field based on a condition. This is helpful when the list of choices should change depending on user input, roles, or record context.
Example
doo.model.status.filterForDropdown = ['New', 'Approved'];
For linked fields (Lookups), you can use filter expressions in a string format:
doo.model.customer.filterForDropdown = "region === 'North'";
Example: Filter dropdown by user role
if (doo.currentUser.roles.includes('Admin')) {
doo.model.state.filterForDropdown = ['Active', 'Closed'];
} else {
doo.model.state.filterForDropdown = ['New'];
}
Example: Filter Lookup based on another field
const branch = doo.model.branch.value;
doo.model.employees.filterForDropdown = `Branch === '${branch}'`;
Example: Filter for multiple conditions
doo.model.members.filterForDropdown = "Branch === 'A01' or Branch === 'B01'";
doo.model.cities.filterForDropdown = "city contains Pra";
doo.model.tasks.filterForDropdown = "state in [New, Canceled]"; // for arrays - e.g. multichoice
Notes
- Filtering is text-based and limited to simple expressions (e.g.,
===
,contains
,in
). - Applied only during the form session — doesn't affect the data in the table.
doo.model.<field>.label
The label
property allows you to dynamically change the visible label (header) of a field in the form. This is useful for context-sensitive forms where field meaning or language may vary based on user role, status, or input.
Example
doo.model.priority.label = 'Urgency Level';
This updates the label shown above the input field, without affecting the internal name or data.
Example: Change label based on status
if (doo.model.status.value === 'Escalated') {
doo.model.comment.label = 'Manager Comment';
} else {
doo.model.comment.label = 'User Comment';
}
Notes
- The change is visual only — it does not affect the field’s internal name or data structure.
- Can be used together with
isVisible
,isEnabled
, andisRequired
for full dynamic UI control.