esx_menu_default
esx_menu_default reference for ESX Legacy. Build keyboard list menus with ESX.UI.Menu.Open, sliders, element fields, menu methods, keybinds and fixes.
esx_menu_default is the classic ESX list menu: a vertical list of buttons and
sliders that players navigate with the arrow keys and Enter. It does not take
mouse focus, so the player can keep moving while the menu is open. You open it
with ESX.UI.Menu.Open('default', ...) from a client script.
Overview
| Resource | esx_menu_default |
| Side | Client only |
| Menu type | default |
| Dependencies | es_extended, esx_lib (loaded via @esx_lib/imports.lua) |
| UI | React build in web/build, Font Awesome icons |
The manifest only declares es_extended as a dependency, but the resource loads
@esx_lib/imports.lua. Start esx_lib before esx_menu_default or the
resource fails with xLib errors.
The resource has no config.lua. Menus are stacked: when you open a second menu,
it is shown on top, and closing it brings back the previous one.
ESX.UI.Menu.Open
ESX.UI.Menu.Open(menuType, namespace, name, data, submit, cancel, change, close)| Name | Type | Description |
|---|---|---|
menuType | string | 'default' for this resource. |
namespace | string | Usually GetCurrentResourceName(). Menus in this namespace are closed when the resource stops. |
name | string | Unique menu name inside the namespace. |
data | table | Menu data, see below. |
submit | function(data, menu)? | Enter pressed on a usable element. |
cancel | function(data, menu)? | Backspace pressed. |
change | function(data, menu)? | Highlight moved or a slider value changed. |
close | function()? | Runs after menu.close(). |
Returns the menu object (see Menu object).
Menu data
| Field | Type | Description |
|---|---|---|
title | string | Menu header. HTML is rendered. |
align | string? | top-left, top-right, bottom-left, bottom-right, center, left-center or right-center. Defaults to right-center. |
elements | table | Array of elements. |
Element fields
| Field | Type | Description |
|---|---|---|
label | string | Text of the row. HTML is rendered. |
name | string? | Your identifier, used to branch in callbacks. |
description | string? | Second line below the label. HTML is rendered. |
icon | string | table | Font Awesome icon name, e.g. 'burger' (solid set), or { 'fab', 'discord' } for another set. |
type | 'slider'? | Omit for a button. |
value | number? | Current slider value. For sliders with options it is the zero-based index into options. |
min | number? | Slider minimum (default 0). Ignored when options is set. |
max | number? | Slider maximum (default 0). Ignored when options is set. |
options | string[]? | Text values for a slider. The slider cycles through them. |
unselectable | boolean? | Skipped by arrow navigation, Enter does nothing. Good for headers. |
usable | boolean? | false keeps the row selectable but blocks submit, change and slider steps. |
disableRightArrow | boolean? | Hides the arrow icon on a button. |
Sliders wrap around: pressing Right on the maximum jumps to the minimum and vice
versa. Any extra fields you add (for example price) are passed back to your
callbacks unchanged.
Callback data
submit and change receive:
| Field | Description |
|---|---|
data.current | The highlighted element (a copy with selected = true). |
data.elements | All elements, each with a selected flag. |
data._namespace, data._name | Menu identifiers. |
cancel receives only _namespace and _name in data.
Before change runs, the menu writes each element's value and selected
state back into menu.data.elements, so menu.data always matches what the
player sees.
Example
local function openShopMenu()
local elements = {
{ label = 'Food', unselectable = true, icon = 'utensils' },
{ label = 'Bread', name = 'bread', price = 5, type = 'slider', value = 1, min = 1, max = 20, icon = 'bread-slice' },
{ label = 'Water', name = 'water', price = 3, type = 'slider', value = 1, min = 1, max = 20, icon = 'bottle-water' },
{ label = 'Payment', name = 'payment', type = 'slider', value = 0, options = { 'Cash', 'Bank' }, icon = 'wallet' },
{ label = 'Close', name = 'close', icon = 'xmark', disableRightArrow = true },
}
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'shop', {
title = '24/7 Shop',
align = 'top-left',
elements = elements,
}, function(data, menu)
local item = data.current
if item.name == 'close' then
return menu.close()
end
if item.name == 'payment' then return end
local payment = menu.data.elements[4].value == 0 and 'money' or 'bank'
TriggerServerEvent('my_shop:buy', item.name, item.value, payment)
end, function(data, menu)
menu.close()
end)
end
RegisterCommand('shop', openShopMenu, false)Menu object
ESX.UI.Menu.Open returns a menu object. The same object is passed as menu to
every callback.
| Member | Description |
|---|---|
menu.close() | Closes this menu and runs the close callback. |
menu.refresh() | Re-sends menu.data to the UI. Call it after changing data. |
menu.update(query, newData) | Merges newData into every element matching all query fields. |
menu.setElement(index, key, value) | Sets one field of the element at index. |
menu.setElements(elements) | Replaces the element list. |
menu.setTitle(title) | Changes the title. |
menu.removeElement(query) | Removes elements that match any field in query. |
menu.data | The data table you passed in. |
menu.type, menu.namespace, menu.name | Identifiers. |
menu.update({ name = 'bread' }, { label = 'Bread (sold out)', usable = false })
menu.refresh()The setters only change Lua data. Nothing changes on screen until you call
menu.refresh().
Other menu functions
These are generic ESX.UI.Menu helpers that work for every menu type
(default, dialog, list).
| Function | Description |
|---|---|
ESX.UI.Menu.Close(type, namespace, name, cancel) | Closes a specific menu. With cancel = true the cancel callback runs instead of close. |
ESX.UI.Menu.CloseAll(cancel) | Closes every open menu. |
ESX.UI.Menu.GetOpened(type, namespace, name) | Returns the menu object or nil. |
ESX.UI.Menu.IsOpen(type, namespace, name) | Alias of GetOpened; truthy when open. |
ESX.UI.Menu.GetOpenedMenus() | Returns the internal list of open menus (may contain nil holes). |
ESX.UI.Menu.RegisterType(type, open, close) | Registers a custom menu type. Used by the menu resources themselves. |
Controls
All keys are FiveM key mappings, so players can rebind them under Settings > Key Bindings > FiveM.
| Default key | Key mapping | Action |
|---|---|---|
| Enter | +menu_default_enter | Submit the highlighted element (200 ms debounce) |
| Backspace | +menu_default_backspace | Cancel |
| Arrow Up | +menu_default_top | Move up (skips unselectable rows, wraps) |
| Arrow Down | +menu_default_down | Move down |
| Arrow Left / Right | +menu_default_left / +menu_default_right | Change slider value |
Keys are ignored while the pause menu is open.
Common issues
attempt to index a nil value (global 'xLib'):esx_libis missing or starts after this resource.- Menu does not close:
submitandcancelnever close the menu automatically. Callmenu.close(). - Same menu opens twice:
ESX.UI.Menu.Opendoes not check for duplicates. Guard withif ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'shop') then return endor callESX.UI.Menu.CloseAll()first. - Changes to elements are not visible: call
menu.refresh()aftersetElement,updateorsetTitle. - Untrusted text breaks the menu:
label,descriptionandtitleare rendered as HTML. Escape player names or other user input before you show them.
Related
- Client UI functions
- esx_menu_dialog
- esx_menu_list
- esx_context for mouse-driven menus
- esx_lib
Frequently asked questions
Independent documentation
Last updated on
esx_inventory
esx_inventory is the default ESX Legacy NUI inventory. Learn its config, keybinds, the server storage API exports and how it relates to ox_inventory.
esx_menu_dialog
esx_menu_dialog reference for ESX Legacy. Ask players for a text or number value with ESX.UI.Menu.Open('dialog'), data fields, callbacks and input rules.