Skip to content
This page View Markdown Open in ChatGPT Open in Claude

Dropdown Form Control

UI Maker is deprecated

UI Maker is kept for the projects which use it and will be removed in API Maker v4. New admin screens are better built with any frontend framework on top of the generated APIs.

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',
}