OOUI/Widgets/Selects and Options

Any widget that provides mutually exclusive options should be built using a SelectWidget that contains instances of OptionWidget (e.g., a ButtonSelectWidget that contains ButtonOptionWidgets, a RadioSelectWidget that contains RadioOptionWidgets, or a MenuSelectWidget that contains MenuOptionWidgets).

OptionWidgets are special elements that can be selected and (optionally, though almost always) configured with data, which can be a string, object, or number. The data is often unique for each option, but it does not have to be. A widget used to select a city by ZIP code, for example, might have labeled options with the different numerical codes, but the same data value (e.g., ‘San Francisco’) for all codes that belong to that city.

Note that if an OptionWidget is added to a SelectWidget that already contains an option with the same reference, the existing option will be removed, and the new option will be added to the end of the option array.

SelectWidgets emit several types of events that have subtle but important differences:

  • highlight indicates which item may be selected when a user presses enter or clicks. When a user mouses over an item, it is highlighted.
  • press is a state that occurs when a user mouses down on an item, but has not yet let go of the mouse. The item may appear selected, but it will not be selected until the user releases the mouse. press can be used to give feedback to a user between mousedown and mouseup.
  • choose is something that happens only when the user makes a selection. Choose is never modified programmatically. If a user chooses an item, it becomes selected. You might wish to use this event if you wish to close a menu when a user chooses an item.
  • select changes which item is currently selected. A select can be made programmatically or by a user (i.e., the user chooses an item and the item is then selected).

SelectWidgets have a number of useful methods for finding items as well as getting and changing their state. In general, all modifications to the highlight or selection should be handled by the SelectWidget rather than by its individual options (e.g., use the SelectWidget’s highlightItem() method to set a highlighted option, not the option-level method).

For a full list of supported methods and configuration options, please see the code-level documentation.

Button selects and options

edit

The following example demonstrates how to create and configure a ButtonSelectWidget that contains three options. Note that the ButtonOptionWidgets are created, but are not appended to the DOM. Instead, they are added to the buttonSelect using the ButtonSelectWidget’s items configuration option.

 

// Example: Creating a ButtonSelectWidget that contains ButtonOptionWidgets
// Note that when rendered, ButtonOptionWidgets might look like ButtonWidgets, 
// but the two are different.
// Although optional, data is almost always specified (e.g., 1, 2, and 
// 3 in this example).
var option1 = new OO.ui.ButtonOptionWidget( {
		data: 1,
		label: 'Option 1', 
		title: 'Button option 1' 
	} ),
	option2 = new OO.ui.ButtonOptionWidget( {
		data: 2,
		label: 'Option 2', 
		title: 'Button option 2' 
	} ),
	option3 = new OO.ui.ButtonOptionWidget( { 
		data: 3,
		label: 'Option 3',
		title: 'Button option 3'
	} ),

// Create a new ButtonSelectWidget and add the button options to it
// via the ButtonSelectWidget's 'items' config option.
	buttonSelect = new OO.ui.ButtonSelectWidget( { 
		items: [ option1, option2, option3 ] 
	} );

// Append the ButtonSelectWidget to the DOM. 
$( document.body ).append( buttonSelect.$element );

For a full list of supported methods and configuration options, please see the code-level documentation.

Radio selects and options

edit

The following example illustrates a RadioSelectWidget that contains two radio options. Note that the first option has been selected using the RadioSelectWidget’s selectItem() method.

 

 
// Example: Creating a RadioSelectWidget with RadioOptions.
// Create options to populate the RadioSelectWidget.
var option1 = new OO.ui.RadioOptionWidget( {
		data: 'a',
		label: 'Selected radio option'
	} ),
	option2 = new OO.ui.RadioOptionWidget( {
		data: 'b',
		label: 'Unselected radio option'
	} ),
 
// Create a new RadioSelectWidget and add the radio options to it 
// via the 'items' config option.
	radioSelect = new OO.ui.RadioSelectWidget( { 
		items: [ option1, option2 ] 
	} );
 
// Select 'option1' using the RadioSelectWidget's selectItem() method.
radioSelect.selectItem( option1 );
 
// Append the widget to the DOM. 
$( document.body ).append( radioSelect.$element );

For a full list of supported methods and configuration options, please see the code-level documentation.

edit

The OOUI library contains two types of ready-to-use widgets that contain menus: DropdownWidgets and ComboBoxWidgets. Note that MenuSelectWidgets themselves are not designed to be instantiated directly, rather subclassed and customized to be opened, closed, and displayed as needed.

By default, menus are clipped to the visible viewport and the toggle value is set to false (i.e., the menu is not visible) when a user presses the mouse outside the menu.

Menus also have support for keyboard interaction:

  • Enter/Return key: choose and select a menu option
  • Up-arrow key: highlight the previous menu option
  • Down-arrow key: highlight the next menu option
  • Esc key: hide the menu

Note that there is also an OOUI MenuLayout, which is a two-panel layout that does not by default contain a MenuSelectWidget (but it can be used with one).

edit

DropdownWidgets are not menus themselves, rather they contain a menu, which can be accessed with the getMenu() method. The DropdownWidget takes care of opening and displaying the menu so that users can interact with it. If you would like to use a dropdown in an HTML form, use DropdownInputWidget instead.

The menu can be placed inside an overlay to avoid being clipped by outer elements. See OOUI/Concepts#Overlays for details.

To create a dropdown menu, use a DropdownWidget that contains a menu of options:

 

// Example: A DropdownWidget that contains a menu of options. 
// Note that the DropdownWidget is not a menu itself, but a container for a menu. 
var dropDown = new OO.ui.DropdownWidget( {
		label: 'Dropdown menu: Select one option',
		// The menu is composed within the DropdownWidget
		menu: {
			items: [
				new OO.ui.MenuOptionWidget( {
					data: 'a',
					label: 'First'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'b',
					label: 'Second (disabled option)',
					disabled: true
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'c',
					label: 'Third'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'd',
					label: 'The fourth option has a long label'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'e',
					label: 'Fifth'
				} )
			]
		}
	} ),

// Trigger an event when an item in the menu is selected.
	itemSelected = function(){
		console.log( 'item selected' );
	};

// Append the menu to the DOM. 
$( document.body ).append( dropDown.$element );

dropDown.getMenu().on('select', itemSelected);

DropdownWidgets can be configured with icons, indicators, labels, and titles. By default, the widget will use a ‘down’ indicator. The class defines one public method, getMenu():

 

// Example: Create a DropdownWidget and use the getMenu() method to get the 
// contained menu and modify it.
var dropDown = new OO.ui.DropdownWidget( {
		label: 'Dropdown menu: Select one option',
		menu: {
			items: [
				new OO.ui.MenuOptionWidget( {
					data: 'a',
					label: 'First'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'b',
					label: 'Second'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'c',
					label: 'Third'
				} )
			]
		}
	} );
 
$( document.body ).append( dropDown.$element );
 
// Get the menu from the dropdown using the getMenu() method. 
// In this example, the getItemFromData() method returns a reference to the option  
// that contains the specified data (i.e., 'a', which is the first menu option). 
// This option is then disabled with the setDisabled() method. 
dropDown.getMenu().getItemFromData( 'a' ).setDisabled( true );

For a complete list of supported configuration options and methods, please see the code-level documentation for DropdownWidget.

ComboBox menus

edit

ComboBoxInputWidgets combine a text input field (where a value can be entered manually) and a menu of options (from which a value can be chosen instead). Users can choose options from the combobox in one of two ways:

  1. By typing a value in the text input field. If the value exactly matches the value of a menu option, that option will appear to be selected.
  2. By choosing a value from the menu. The value of the chosen option will then appear in the text input field.

To create a combobox with options populated by the server, which might be useful if you’d like to narrow down a long static list of options based on the characters the user types, use the LookupElement mixin. Please see OOjs/Inheritance#Mixins for more information.

To create a combobox widget use a ComboBoxInputWidget with a menu of options:

 

// Example: Creating a ComboBoxInputWidget. Users can type 'Option Four' in the text 
// field  to make that option appear selected, or choose 'Option Four' from the 
// menu, in which case, the Option Four data will appear in the text field.
var comboBox = new OO.ui.ComboBoxInputWidget( {
		label: 'ComboBoxInputWidget',
		menu: {
			items: [
				new OO.ui.MenuOptionWidget( {
					data: 'Option 1',
					label: 'Option One'
				} ),
				new OO.ui.MenuOptionWidget( { 
					data: 'Option 2',
					label: 'Option Two'
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'Option 3',
					label: 'Option Three'
				} ),
				new OO.ui.MenuOptionWidget( { 
					data: 'Option 4',
					label: 'Option Four' 
				} ),
				new OO.ui.MenuOptionWidget( {
					data: 'Option 5', 
					label: 'Option Five'
				} )
			]
		}
	} );
$( document.body ).append( comboBox.$element );

ComboBoxInputWidgets can be disabled or configured with CSS and initial values for the text input and menu options. For a complete list of supported configuration options and methods, please see the code-level documentation.