Fields
Select Field

Select

This field selects an option from a list of options.

Display type

  • select

Field properties

NameDescription
displayTypeThe displayType for this field (select)
displayNameThe display name used for this field
optionsThe list of available options for the field
valueThe value used by this field
placeholderThe hint value used for this field
isDisabledMarks the field as disabled
isReadonlyMarks the field as readonly

Config

The configuration defines how to load dropdown options for the select field. Use this to load options from remote api and configure its behaviour.

NameDescription
urlThe api endpoint to load dropdown options
urlTypeUse urlType="remote" for calling third party api
pathParamsThe path parameters of the url. Use this for dynamic path parameters
queryParamsList of query parameters. Use this for dynamic query parameters
requestTypeRepresents HTTP method used for url. Options are get, post, put, delete.
If none is specified and url key is present, then default value is get
requestHeadersA mapping of header key and value pairs. Use this for authentication, content type, caching policies, custom headers etc.
requestBodyA JSON payload. Parameters are representes as $0, $1 and so forth.
Parameters are 0 indexed.
requestBodyParamsList of parameter values of request body. Each index value in the requestBodyParams represents the same index parameter form requestParams
valueKeyThe key from the response for value of the field
labelKeyThe key from the response for display name of the field
responseKeyThe key from response which contains the results
lazyLoad options lazily. For example: load the options on opening dropdown

Common Properties

Click here to go to common properties

Basic example

Schema

{
fields
:
[
0
:
{
name
:
"name"
meta
:
{
displayName
:
"Fruits"
displayType
:
"select"
options
:
[
0
:
{
}
1
:
{
}
2
:
{
}
]
}
}
]
}

Query params

Query params can be used to pass additional data as part of the api url. This data can either be hardcoded or configured to pass data dynamically from other fields.

Format of query params: It accepts an array/list of query params.

[<QUERY_PARAM1>, <QUERY_PARAM2>,...]

Format of query param: It accepts name and value in list like format.

[<NAME_OF_QUERY_PARAM>, <VALUE_OF_QUERY_PARAM>]
  • NAME_OF_QUERY_PARAM is just a string
  • VALUE_OF_QUERY_PARAM can be a hardcoded value or can reference value from another field like this:
    • type: 'fieldValue' indicates the value has to be taken from another field
    • ref: name of the reference field from where value can be copied

Schema example with query params

{
fields
:
[
0
:
{
name
:
"countries"
meta
:
{
displayName
:
"Select Country"
displayType
:
"select"
value
:
"IN"
options
:
[
0
:
{
}
1
:
{
}
]
events
:
{
change
:
{
}
}
}
}
1
:
{
name
:
"states"
meta
:
{
config
:
{
lazy
:
"true"
url
:
"/api/states"
queryParams
:
[
]
responseKey
:
"data"
labelKey
:
"label"
valueKey
:
"value"
}
displayName
:
"Select State"
displayType
:
"select"
options
:
[
]
}
}
]
}

Request Body

A sample request body payload for HTTP method 'post' with request body parameters and url.

Demo

Schema example

{
fields
:
[
0
:
{
name
:
"product1"
meta
:
{
displayName
:
"Product 1"
displayType
:
"select"
options
:
[
0
:
{
}
1
:
{
}
2
:
{
}
]
}
}
1
:
{
name
:
"product2"
meta
:
{
displayName
:
"Product 2"
displayType
:
"select"
options
:
[
0
:
{
}
1
:
{
}
2
:
{
}
]
}
}
2
:
{
name
:
"product_details"
meta
:
{
config
:
{
url
:
"https://dummyjson.com/carts/add"
urlType
:
"remote"
requestType
:
"post"
requestBody
:
{
}
requestBodyParams
:
[
]
responseKey
:
"products"
labelKey
:
"title"
valueKey
:
"total"
lazy
:
true
}
displayName
:
"Product Details"
displayType
:
"select"
options
:
[
]
}
}
]
}

How to load options from remote api

Schema

{
fields
:
[
0
:
{
name
:
"countries"
meta
:
{
config
:
{
url
:
"/api/countries"
valueKey
:
"code"
labelKey
:
"name"
}
displayName
:
"Select Country"
displayType
:
"select"
options
:
[
]
}
}
]
}

How to load options from remote api that require auth

Approach 1: using request headers configured for specific field

Schema

{
fields
:
[
0
:
{
name
:
"countries"
meta
:
{
config
:
{
lazy
:
true
url
:
"/api/countriesWithAuth"
valueKey
:
"code"
labelKey
:
"name"
requestHeaders
:
{
}
}
displayName
:
"Select Country"
displayType
:
"select"
options
:
[
]
}
}
]
}

Approach 2: using global config headers

Schema

{
fields
:
[
0
:
{
name
:
"countries"
meta
:
{
config
:
{
lazy
:
true
url
:
"/api/countriesWithAuth"
valueKey
:
"code"
labelKey
:
"name"
}
displayName
:
"Select Country"
displayType
:
"select"
options
:
[
]
}
}
]
}

Usage

import React from "react";
import MuiForms from "mui-forms";
import schema from "./schema.json";
 
function RatingForm() {
    return (
        <MuiForms
            config={{
                headers: {
                    "authorization": "Basic dGVzdHVzZXI6dGVzdHBhc3N3b3Jk"
                }
            }}
            schema={schema}
            onSubmit={() => {
                // do nothing
            }}
        />
    );
}

Error Handling

Handling Failed API Calls

When loading options from a remote API, handle failures gracefully:

{
  "fields": [
    {
      "name": "product",
      "meta": {
        "displayName": "Select Product",
        "displayType": "select",
        "placeholder": "Loading products...",
        "config": {
          "url": "https://api.example.com/products",
          "labelKey": "name",
          "valueKey": "id",
          "lazy": true
        },
        "validation": {
          "required": true
        }
      }
    }
  ]
}

How to handle API errors with onError Callback

Use the onError callback to handle API failures globally across the form:

import React from "react";
import MuiForms from "mui-forms";
import schema from "./schema.json";
 
function MyForm() {
  const handleErrorCallback = (error, section, field) => {
    // error is the actual error from server
    // section is the form section where the error occurred
    // field is the source where api failure happened
    
    console.error(`API Error in ${section}.${field}:`, error);
    
    // Handle different error types
    if (error.status === 401) {
      // Handle authentication errors
      console.error("Unauthorized - please login again");
    } else if (error.status === 404) {
      // Handle not found errors
      console.error("Resource not found");
    } else {
      // Handle other errors
      console.error("Failed to load products");
      // showToast({ type: 'error', message: error.message });
    }
  };
 
  return (
    <MuiForms
      onError={handleErrorCallback}
      schema={schema}
      onSubmit={(data) => {
        // handle form submission
      }}
    />
  );
}
 
export default MyForm;

Callback Parameters:

  • error - The error object returned from the API call (includes status, message, etc.)
  • section - The form section where the error occurred
  • field - The specific field name that triggered the API error

Use cases:

  • Log errors to monitoring/analytics services
  • Show user-friendly error messages
  • Retry failed API calls
  • Update form state based on error type

Best Practices

When loading options from a remote API, handle failures gracefully:

Best Practices:

  • Use the lazy property to load options only when the dropdown opens
  • Provide a meaningful placeholder that indicates loading state
  • Set default options as fallback while data loads
  • Validate required fields to ensure selection is made

Response Data Transformation

Use responseKey to extract data from nested API responses:

{
  "config": {
    "url": "https://api.example.com/data",
    "responseKey": "results",
    "labelKey": "displayName",
    "valueKey": "id"
  }
}

If your API returns:

{
  "results": [
    { "id": 1, "displayName": "Option 1" },
    { "id": 2, "displayName": "Option 2" }
  ]
}

Common Patterns

Pattern 1: Static Options (Hardcoded)

Use this for small, fixed option lists:

{
  "meta": {
    "displayType": "select",
    "options": [
      { "label": "Draft", "value": "draft" },
      { "label": "Published", "value": "published" },
      { "label": "Archived", "value": "archived" }
    ]
  }
}

When to use: Status fields, predefined categories, priority levels


Pattern 2: Remote API Options

Use this for large, dynamic option lists:

{
  "meta": {
    "displayType": "select",
    "config": {
      "url": "https://api.example.com/options",
      "labelKey": "name",
      "valueKey": "id",
      "lazy": true
    }
  }
}

When to use: User lists, product catalogs, geographic data


Pattern 3: Cascading Selects

Second select depends on first select value:

{
  "fields": [
    {
      "name": "country",
      "meta": {
        "displayName": "Country",
        "displayType": "select",
        "config": {
          "url": "https://api.example.com/countries",
          "labelKey": "name",
          "valueKey": "code"
        }
      }
    },
    {
      "name": "state",
      "meta": {
        "displayName": "State",
        "displayType": "select",
        "config": {
          "url": "https://api.example.com/states",
          "queryParams": [
            ["country", { "type": "fieldValue", "ref": "country" }]
          ],
          "labelKey": "name",
          "valueKey": "code"
        },
        "dependencies": {
          "exists": {
            "field": "country",
            "operator": "$notempty"
          }
        }
      }
    }
  ]
}

Key points:

  • Secondary select should only show when parent has a value
  • Use queryParams to pass parent value to API
  • Use dependencies to hide/show based on parent selection

Pattern 4: Filtered Options with Search

Enable server-side filtering as user types:

{
  "meta": {
    "displayName": "Search User",
    "displayType": "search",
    "placeholder": "Type to search...",
    "config": {
      "url": "https://api.example.com/users/search",
      "queryParams": [
        ["q", { "type": "fieldValue", "ref": "searchQuery" }]
      ],
      "labelKey": "name",
      "valueKey": "id"
    }
  }
}

Performance Considerations

StrategyBenefitWhen to Use
lazy: trueDon't load options until dropdown opensLarge option lists (100+ items)
queryParamsFilter server-sideData that changes based on other fields
responseKeyExtract nested dataComplex API responses
Static optionsInstant loading, no network callsSmall, fixed lists
CachingReduce API callsStable data that loads frequently

Recommended approach:

  • Use static options for UI status, constants
  • Use lazy loading for large remote datasets
  • Use query parameters to filter at the source
  • Implement backend caching for frequently accessed data

Troubleshooting Select Fields

IssueSolution
Options not loadingCheck API URL, verify CORS headers, check network tab
Wrong labels/values shownVerify labelKey and valueKey match response
Cascading not workingEnsure parent field has a value, check queryParams reference
Change event not firingCheck events configuration, verify field name in dependencies
Show/hide not workingVerify dependencies.exists condition matches actual field value

Related Topics

Star us at github

© Copyright 2023 MuiForms