Dropdown Form Control
Show dropdown with database data
let dbMasterConfig: T.IDBMasterConfig = {
form: {
fields: [
[{
label: 'Person',
control: T.EDBMasterFormControl.dropdown,
path: 'person_id',
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: { // Optional, it can pickup instance,database,collection details from schema.
collection: 'persons',
select: 'person_name, mobile_no, _id'
},
optionLabel: 'person_name', // 👈 It will be displayed in UI, HTML supported
optionValue: '_id', // 👈 It will be saved in database.
filter: true,
filterBy: 'person_name,mobile_no,_id',
// filterBy: 'person_name',
filterMatchMode: 'contains',
// virtualScroll: false,
alwaysGetLatestDataOnFormOpen: true,
},
validations: {
required: true,
}
}]
]
}
};
Show static data
let dbMasterConfig: T.IDBMasterConfig = {
form: {
fields: [
[{
label: 'Gender',
control: T.EDBMasterFormControl.dropdown,
path: 'gender',
dropdownSettings: {
showClear: true,
dataSource: 'static_data',
staticData: [{
label: 'Male', // Shown In UI
value: 'male', // Saved In DB
data: 'some other property data 1',
}, {
label: 'Female',
value: 'female',
data: 'some other property data 1',
}],
optionLabel: 'label', // 👈 It will be displayed in UI, HTML supported
optionValue: 'value', // 👈 It will be saved in database.
filter: true,
filterBy: 'label',
filterMatchMode: 'contains',
},
validations: {
required: true,
}
}]
]
}
};
Show data from custom API
let dbMasterConfig: T.IDBMasterConfig = {
form: {
fields: [
[{
label: 'Cities',
control: T.EDBMasterFormControl.dropdown,
path: 'city_id',
dropdownSettings: {
dataSource: 'api_call',
optionLabel: 'city_name',
optionValue: '_id',
apiCallOverrides: {
// :userPath = it will be replaced with admin user path by master page automatically.
// :beHostPort = it will be replaced with API Maker backend's protocol and host and port automatically. ex : https://example.com
// url: ':beHostPort/api/custom-api/:userPath/list-of-cities', // 👈 Use this to make it dynamic
url: 'http://localhost:38246/api/custom-api/admin/list-of-cities',
},
jsCode: [{
appendTo: T.EDBMasterDropdownAppendTo.modifyDropdownRequest,
code: `
reqBody.state_id = formData.state_id;
console.log(body);
`
}],
},
}]
]
}
};
Add new item support
let dbMasterConfig: T.IDBMasterConfig = {
form: {
fields: [
[{
label: 'Product Categories',
control: T.EDBMasterFormControl.dropdown,
path: 'product_category_id',
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: {
collection: 'product_categories',
select: 'name'
},
optionLabel: 'name',
optionValue: '_id',
addNewFormConfig: { // 👈 Opens add product category & saves & reloads dropdown
screenName: 'Product Category',
form: {
width: '500px',
fields: [
[{ // field
label: 'Name',
control: T.EDBMasterFormControl.input,
path: 'name',
}]
]
}
}
},
validations: {
required: true,
}
}]
]
}
};
Dependent Dropdowns | Auto Completes | Multi Selects
👉 It supports N level of dependent dropdowns with any type of complexity.
let dbMasterConfig: T.IDBMasterConfig = {
form: {
fields: [
[{
path: 'planetId',
control: T.EDBMasterFormControl.dropdown,
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: {
collection: 'ui_maker_planet',
},
optionValue: '_id',
optionLabel: 'name',
reloadDropdownsOfPath: ['continentId'], // 👈 dropdown | auto complete | multi select path
},
}],
[{
path: 'continentId',
control: T.EDBMasterFormControl.dropdown,
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: {
collection: 'ui_maker_continent',
},
optionValue: '_id',
optionLabel: 'name',
isDependentOnPath: ['planetId'],
reloadDropdownsOfPath: ['countryId'], // 👈 dropdown | auto complete | multi select path
jsCode: [{
appendTo: T.EDBMasterDropdownAppendTo.modifyDropdownRequest,
code: `
reqBody.find.planetId = formData.planetId;
`,
}]
}
}],
[{
path: 'countryId',
control: T.EDBMasterFormControl.dropdown,
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: {
collection: 'ui_maker_country',
},
optionValue: '_id',
optionLabel: 'name',
isDependentOnPath: ['continentId'],
reloadDropdownsOfPath: ['stateId'], // 👈 dropdown | auto complete | multi select path
jsCode: [{
appendTo: T.EDBMasterDropdownAppendTo.modifyDropdownRequest,
code: `
reqBody.find.continentId = formData.continentId;
`,
}]
}
}],
[{
path: 'stateId',
control: T.EDBMasterFormControl.dropdown,
dropdownSettings: {
showClear: true,
dataSource: 'db_data',
dbData: {
collection: 'ui_maker_states',
},
optionValue: '_id',
optionLabel: 'name',
isDependentOnPath: ['countryId'],
jsCode: [{
appendTo: T.EDBMasterDropdownAppendTo.modifyDropdownRequest,
code: `
reqBody.find.countryId = formData.countryId;
`,
}]
}
}]
]
}
};
Interface Documentation
/**
* Form field configuration for UI controls.
* Defines the appearance, behavior, and validation of individual form inputs.
*/
export interface IDBMasterConfigFormField {
/**
* Unique identifier for programmatic element access.
* Useful for dynamic field manipulation.
*/
hiddenId?: string;
/** Display label for the form field. */
label?: string;
/**
* Help text displayed below the control.
* Supports HTML formatting for rich content.
*/
helpText?: string;
/**
* Database field path where the control value is stored.
* Supports nested paths using dot notation.
* @example 'name', 'address.city', 'user.contact.email'
*/
path?: string;
/** Type of UI control to render. */
control?: EDBMasterFormControl;
/**
* CSS classes for the parent div wrapping the control.
* @default 'col-lg mt-4 col-md-{calculated based on columns.length}'
*/
cssClassDiv?: string;
/**
* Auto-focus this control when form opens.
* @default false
*/
autofocus?: boolean;
/**
* Disable the control or use expression to conditionally disable.
* When a string is provided, it's evaluated as JavaScript.
* @example true | false | "formData.type === 'readonly'"
*/
disabled?: boolean | string;
/**
* Control visibility or use expression to conditionally show/hide.
* When a string is provided, it's evaluated as JavaScript.
* @default true
* @example true | false | "formData.userRole === 'admin'"
*/
visible?: boolean | string;
/**
* Nested form fields for complex layouts.
* Enables hierarchical form structures within this field.
*/
fields?: IDBMasterConfigFormField[][];
/** Validation rules for this field. */
validations?: Pick<IPropertyValidation, 'required'> & {
/**
* Dynamic required validation function.
* Evaluated when form data changes to determine if field is required.
* Note: When present, this takes precedence over static 'required' property.
* @example "formData.type === 'individual' ? true : false"
*/
requiredFun?: string;
};
/** Custom validation error messages. */
validationErrors?: {
/** Custom error message for required field validation. */
required?: string;
};
/**
* Dropdown (select) control configuration.
* Supports static data, database queries, and custom API calls.
*/
dropdownSettings?: {
/** Inline style object (Angular style binding format). */
style?: any;
/** Space-separated CSS class names. */
cssClass?: string,
/** Placeholder text displayed when no selection is made. */
placeholder?: string;
/**
* Show clear button to reset selection.
* @default false
*/
showClear?: boolean;
/**
* Data source type for dropdown options.
* - `static_data`: Use predefined array of options
* - `db_data`: Query database for options
* - `api_call`: Call custom API endpoint
*/
dataSource: 'static_data' | 'db_data' | 'api_call';
/**
* Static dropdown options.
* Used when dataSource is 'static_data'.
* @example [{ label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 }]
*/
staticData?: any[];
/**
* Database query configuration for dropdown options.
* Can inherit values from schema if field has database relationship defined.
*/
dbData?: Partial<Pick<ICollectionIdentity, 'instance' | 'database' | 'collection' | 'table'>
& Pick<IQueryFormat, 'find' | 'select' | 'limit' | 'deep' | 'sort'>>;
/**
* Property name to display in dropdown.
* @default 'label'
*/
optionLabel?: string;
/**
* Property name to use as option value.
* @default 'value'
*/
optionValue?: string;
/**
* Enable dropdown filtering.
* @default false
*/
filter?: boolean;
/**
* Fields to search when filtering.
* Supports multiple fields (comma-separated, no spaces).
* @example 'name', 'name,email,phone'
*/
filterBy?: string;
/**
* Filter matching strategy.
* @default 'contains'
*/
filterMatchMode?: 'contains' | 'startsWith' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'lt' | 'lte' | 'gt' | 'gte';
/**
* Reload dropdown data when form opens.
* Ensures options are always up-to-date.
* @default false
*/
alwaysGetLatestDataOnFormOpen?: boolean;
/**
* Enable virtual scrolling for large datasets.
* Improves performance when dealing with thousands of options.
* @default false
*/
virtualScroll?: boolean;
/**
* Dependent dropdown cascade.
* When this dropdown value changes, reload these other dropdowns.
* @example ['city', 'area'] - Reload city and area dropdowns
*/
reloadDropdownsOfPath?: string[];
/**
* Required field dependencies.
* Dropdown only loads data when these fields have values.
* @example ['country', 'state'] - Only load if country and state are selected
*/
isDependentOnPath?: string[];
/** Tooltip text displayed on hover. */
tooltip?: string;
/** Tooltip position relative to the element. */
tooltipPosition?: 'left' | 'top' | 'bottom' | 'right';
/** CSS class for tooltip styling. */
tooltipStyleClass?: string;
/** Custom event handlers and data transformation scripts. */
jsCode?: {
/**
* Event type or lifecycle hook:
* - modifyDropdownRequest: Before API call
* - onceDropdownDataLoaded: After data loaded
* - onChange: When selection changes
*
* Available variables:
* - reqBody: Query object for modification
* - formData: Complete form data
* - dropdownData: Loaded options array
* - reloadDropdownsOfPath: Array to trigger dependent reloads
*/
appendTo: EDBMasterDropdownAppendTo,
code: string | (($scope: IDBMasterUIPageUtilsScope) => any),
}[],
/**
* Nested form configuration for adding new options.
* Opens a modal to create new records that can be immediately selected.
*/
addNewFormConfig?: IDBMasterConfig;
/**
* Custom API endpoint configuration.
* Override default query API with custom endpoint and logic.
*/
apiCallOverrides?: IDBMasterAPICallOverrides;
};
}
/**
* Validation rules for schema properties and form fields.
* Define constraints that values must satisfy before being saved.
*/
export interface IPropertyValidation {
/**
* Field is mandatory and must have a non-null, non-empty value.
* Applicable to all data types.
*/
required?: boolean;
/**
* Minimum allowed value.
* Applicable to: number, date
*/
min?: number;
/**
* Maximum allowed value.
* Applicable to: number, date
*/
max?: number;
/**
* Minimum string/array length.
* Applicable to: string, array
*/
minLength?: number;
/**
* Maximum string/array length.
* Applicable to: string, array
*/
maxLength?: number;
/**
* Value must be unique across all records.
* @deprecated API Maker maintains uniqueness internally.
* Avoid using on tables with frequent updates due to performance impact.
*/
unique?: boolean;
/**
* Validate email address format.
* Applicable to: string
*/
email?: boolean;
/**
* Custom validation function.
* Return true if valid, false or error message if invalid.
*/
validatorFun?: Function;
/**
* Enumeration constraint - value must be from this array.
* @example ['active', 'inactive', 'pending']
*/
enum?: any[];
}
export enum EDBMasterDropdownAppendTo {
visible = 'visible',
disabled = 'disabled',
modifyDropdownRequest = 'modifyDropdownRequest',
onceDropdownDataLoaded = 'onceDropdownDataLoaded',
onChange = 'onChange',
}
/**
* Available form control types for UI generation.
* Each control type has specific settings and behavior.
*/
export enum EDBMasterFormControl {
/** Single-line text input. */
input = 'input',
/** Numeric input with spinner buttons and formatting. */
inputNumber = 'inputNumber',
/** Text input with pattern-based masking (phone, SSN, etc.). */
inputMask = 'inputMask',
/** One-time password multi-character input. */
inputOtp = 'inputOtp',
/** Password input with visibility toggle and strength meter. */
password = 'password',
/** Date and/or time picker with calendar popup. */
date_picker = 'date_picker',
/** Multi-line text input. */
textarea = 'textarea',
/** Rich text WYSIWYG editor. */
editor = 'editor',
/** Binary checkbox (true/false). */
checkbox = 'checkbox',
/** Radio button group for single selection. */
radio = 'radio',
/** Color picker with multiple format support. */
color_picker = 'color_picker',
/** Dropdown select with single selection. */
dropdown = 'dropdown',
/** Autocomplete with type-ahead search. */
auto_complete = 'auto_complete',
/** Multi-select dropdown with chip display. */
multi_select = 'multi_select',
/** File upload with validation. */
file_upload = 'file_upload',
/** Nested data grid for one-to-many relationships. */
grid = 'grid',
/** Visual separator line. */
divider = 'divider',
/** Star-based rating input. */
rating = 'rating',
/** Circular dial for numeric input. */
knob = 'knob',
/** Collapsible accordion panels (field container). */
accordion = 'accordion',
/** Tabbed view for organizing fields (field container). */
tab_view = 'tab_view',
/** Clickable button with custom actions. */
button = 'button',
/** Image display with preview. */
image = 'image',
/** Custom HTML content. */
customHTML = 'customHTML',
}
export enum EDBMasterCustomActionButtonAppendTo {
click = 'click',
}