---
title: "Advanced select field capabilities"
date: "2024-06-27T14:46:27+00:00"
summary: "Discover advanced select field capabilities in Site Studio 7.5.0. Learn how to use external data sources and custom functions for dynamic options, enhancing your form-building toolkit with flexible, powerful select fields."
image:
type: "page"
url: "/drupal-starter-kits/add-ons/site-studio/advanced-select-field-capabilities"
id: "3f421d9b-9866-44f0-a0cd-c0185c13f058"
---

Table of contents will be added

Two new options have been added for the Select form field in the form builder in Site Studio 7.5.0.

The previous two options have been renamed as described:

*   Manually set options - _previously "Custom select field"_ 
*   Options from existing select field - _previously "Existing select field"_ 
*   Options from external data source - **_new_** 
*   Options from custom function - **_new_**

Selecting "Options from external data source" will display a new field "External URL". You must enter a url endpoint that returns JSON data in the correct format.

Selecting "Options from custom function" will display a new field "Function name". You must enter the name of a function that is globally available that returns the data in the correct format (or a promise that resolves to the correct data).

An [example module](https://github.com/acquia/cohesion/tree/7.5.x/modules/example_custom_select) (example\_custom\_select) is also included to further outline usage expectations.

Demo
----

Enable this module from `/admin/modules`

### Drupal route

1.  Create a new Component by navigating to: `admin/cohesion/components/components/add`
2.  Add a `Select` field to the Component form builder
3.  Double-click the new Select field and choose `Options from external data source` as the `Type`
4.  Enter `/sitestudio/select-options` to use the Drupal route supplied by this example module
5.  Observe the dynamic values supplied by this endpoint in the `Default value` options.

### Javascript function

1.  Create a new Component by navigating to: `admin/cohesion/components/components/add`
2.  Add a `Select` field to the Component form builder
3.  Double-click the new Select field and choose `Options from custom function` as the `Type`
4.  Enter `exampleGetOptions1` to use the Javascript function supplied by this example module
5.  Observe the dynamic values supplied by this endpoint in the `Default value` options.

Example code
------------

This module provides an example of both the Drupal and Javascript implementations of this feature.

### Drupal route

*   [Drupal route](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/example_custom_select.services.yml) - defines an endpoint for returning JSON.
*   [Controller](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/src/Controller/ExampleCustomSelectController.php) - returns JSON data.

### Javascript function

*   [Javascript library definition](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/example_custom_select.libraries.yml) - defines a custom JS library.
*   [Javascript library](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/js/example_custom_select.js) - return JSON data.
*   [module file](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/example_custom_select.module) - attaches library during entity create/edit.
*   [Service definition](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/example_custom_select.services.yml) - defines the EventSubscriber service.
*   [Event Subscriber](https://github.com/acquia/cohesion/blob/7.5.x/modules/example_custom_select/src/EventSubscriber/ExampleCustomSelectSubscriber.php) - attaches library during Page Builder load.

**Note**: an [Event subscriber](https://www.drupal.org/docs/develop/creating-modules/subscribe-to-and-dispatch-events) must be utilised to ensure a custom Javascript library is attached during Page Builder interaction.

JSON format
-----------

When writing a function to retrieve options for the Select form element, it is crucial to adhere to specific guidelines to ensure consistency and compatibility. This documentation provides a set of rules and examples for creating a valid options retrieval function.

### Rules for a Valid Options Retrieval Function

1.  Return Type:
    
    *   The function must return an array of objects representing options.
    *   Each object in the array should have a label property and a value property.

    // Valid Example
    [
      { label: 'Option 1', value: 'option1' },
      { label: 'Option 2', value: 'option2' },
      // ...
    ]
    

2.  Optional Grouping:
    
    *   Optionally, an object can have a group property to categorize options.

    // Valid Example
    [
      { label: 'Option 1', value: 'option1', group: 'Group A' },
      { label: 'Option 2', value: 'option2', group: 'Group B' },
      // ...
    ]
    

3.  Function Structure:
    
    *   The options retrieval function must be a callable function and the function must be globally available (on the Window object.)

    // Valid Example
    const validOptionsFunction = function () {
      return [
        { label: 'Option 1', value: 'option1' },
        { label: 'Option 2', value: 'option2' },
        // ...
      ];
    };
    window.getOptions = validOptionsFunction;
    

Examples
--------

### Valid Examples

1.  Using a Promise (asynchronous):

    window.exampleGetOptions = async function () {
      return new Promise((resolve) => {
       setTimeout(() => {
         resolve([
           { label: 'Foo', value: 'foo' },
           { label: 'Bar', value: 'bar' },
           { label: 'Wut', value: 'wut', group: 'Other' },
         ]);
        }, 1000); // Simulate a delay of 1 second
      });
    };
    

2.  Using a synchronous function:

    window.exampleGetOptions1 = function () {
      return [
       { label: 'Foo', value: 'foo' },
       { label: 'Bar', value: 'bar' },
       { label: 'Wut', value: 'wut', group: 'Other' },
      ];
    };
    

### Invalid Examples

1.  Not returning an array:

    window.exampleGetOptions2 = function () {
       return 'This is not an array of options.';
    };
    

2.  Not being a callable function:

    window.exampleGetOptions3 = [
      { label: 'this is not a function', value: 'this is not a function' },
    ];
    

3.  Invalid object properties:

    window.exampleGetOptions4 = async function () {
      return [
        { label: 'Foo', value: 'foo' },
        { label: 'Bar', value: 'bar' },
        { label: 'Wut', foo: 'Other' }, // Invalid property 'foo'
      ];
    };
    

Creating a valid custom URL
---------------------------

### Overview

When retrieving options from a URL it is crucial that the data returned from the URL is in the correct format and is returned as JSON data.

1.  Return Type:
    
    *   The URL must return an array of objects representing options.
    *   Each object in the array should have a label property and a value property.

    [
      { "label": "Option 1", "value": "option1" },
      { "label": "Option 2", "value": "option2" }
    ]
    

2.  Optional Grouping:
    
    *   Optionally, an object can have a group property to categorize options.

    [
      { "label": "Option 1", "value": "option1", "group": "Group A" },
      { "label": "Option 2", "value": "option2", "group": "Group B" }
    ]