The SingleSelect question type presents users with a list of options from which they can select one answer.

Basic Usage

const favoriteColorQuestion = new SingleSelect({
    id: 'favorite_color',
    text: 'What is your favorite color?',
    options: ['Red', 'Blue', 'Green', 'Yellow'],
    required: true
});

Parameters

id
string
required

Unique identifier for the question.

text
string
required

The main question text.

subText
string
default: ""

Additional text to provide context or instructions.

options
array
required

An array of strings representing the available options.

required
boolean
default: "true"

Whether the question is required.

randomize
boolean
default: "false"

Whether to randomize the order of options.

allowOther
boolean
default: "false"

Whether to include an “Other” option with a text input.

otherText
string
default: "Other (please specify)"

The label for the “Other” option, if allowed.

customValidation
function

A custom validation function that takes the response as input and returns true if valid, or an error message string if invalid.

styles
object

Custom styles to apply to the question. Available keys are:

  • root
  • innerContainer
  • textContainer
  • text
  • subText
  • optionsContainer
  • option
  • radio
  • label
  • otherInput
  • errorMessage

Data

Response Format

The SingleSelect question type returns a string representing the selected option:

"Blue"

If the “Other” option is selected and filled:

{ selected: "other", otherValue: "Purple" }

Validation

The SingleSelect question validates that:

  1. An option has been selected when required is set to true.
  2. If “Other” is selected, the other input is not empty when required is true.
  3. The selected option is valid (exists in the options array or is “other”).
  4. Any custom validation provided in the customValidation function passes.

If validation fails, it displays an appropriate error message.

Methods

The SingleSelect question type inherits methods from the base Element class and includes some specific methods:

setResponse
function

Set the response for the question.

Parameters:

  • value (string or object): The selected option or other value
singleSelectQuestion.setResponse('Blue');
// or
singleSelectQuestion.setResponse({ selected: 'other', otherValue: 'Purple' });
validate
function

Validate the current response against the question’s rules.

Returns:

  • An object with isValid (boolean) and errorMessage (string) properties.
const { isValid, errorMessage } = singleSelectQuestion.validate();

Example

Here’s an example of how to create a customized single-select question:

const customizedQuestion = new SingleSelect({
    id: 'preferred_contact',
    text: 'How would you prefer to be contacted?',
    subText: 'Choose the method that works best for you',
    options: ['Email', 'Phone', 'Text Message', 'Mail'],
    randomize: true,
    required: true,
    allowOther: true,
    otherText: 'Other method (please specify)',
    customValidation: (response) => {
        if (response === 'Phone' || (response.selected === 'other' && response.otherValue.toLowerCase().includes('phone'))) {
            return 'Phone contact is currently unavailable. Please choose another option.';
        }
        return true;
    },
    styles: {
        root: { 
            backgroundColor: '#f0f8ff',
            padding: '15px',
            borderRadius: '8px',
            boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
        },
        text: { 
            color: '#2c3e50',
            fontSize: '1.2em',
            fontWeight: 'bold'
        },
        subText: {
            fontStyle: 'italic',
            color: '#7f8c8d'
        },
        optionsContainer: {
            marginTop: '10px'
        },
        option: {
            marginBottom: '10px',
            transition: 'background-color 0.3s ease'
        },
        radio: {
            accentColor: '#3498db'
        },
        otherInput: {
            marginTop: '5px',
            width: '100%'
        },
        errorMessage: {
            color: '#e74c3c',
            fontWeight: 'bold',
            marginTop: '5px'
        }
    }
});