esx_context
esx_context reference for ESX Legacy. Open mouse-driven context menus and small forms with ESX.OpenContext, element fields, exports, keybind and pitfalls.
esx_context is the mouse-driven context menu of ESX Legacy. Use it for short
action lists (an interaction menu, a boss menu) and small forms with text,
number or radio inputs. You open it from client code with ESX.OpenContext,
which is a wrapper around the esx_context exports.
Overview
| Resource | esx_context |
| Side | Client only |
| Dependencies | es_extended |
| UI | Plain HTML page (index.html), Font Awesome icons |
| Version | 1.16.x (ships with ESX Legacy 1.16.4) |
The menu is a single panel. Only one context menu can be open at a time; opening a new one replaces the current one.
Configuration
config.lua contains a single global:
| Key | Default | Description |
|---|---|---|
PREVIEW_KEYBIND | "LMENU" (left Alt) | Default key for the previewContext key mapping, which gives mouse focus to a menu opened in preview mode. Set it to nil to skip registering the command and key mapping. |
Players can rebind the key under Settings > Key Bindings > FiveM ("Preview Active Context").
Debug commands (see Commands) are only registered when
Config.EnableDebug in es_extended is true.
Functions
All functions are client side and available on the ESX object once you load
@es_extended/imports.lua or call exports['es_extended']:getSharedObject().
Every wrapper returns false when esx_context is not running.
ESX.OpenContext
Opens a context menu and gives it mouse and keyboard focus.
ESX.OpenContext(position, elements, onSelect, onClose, canClose)| Name | Type | Description |
|---|---|---|
position | string | "left", "center" or "right" (default "right"). |
elements | table | Array of elements. |
onSelect | function(menu, element)? | Runs when the player clicks a selectable element. |
onClose | function(menu)? | Runs after the menu closes, by key or by ESX.CloseContext. |
canClose | boolean? | false blocks closing with Escape/Backspace. Defaults to true. |
The menu argument is the internal menu table: menu.eles holds the current
elements (including updated inputValues), menu.position the position.
Before the elements reach the UI, ESX.OpenContext strips HTML tags from
title, description, label and inputPlaceholder. Use plain text.
local function openGarageMenu()
local elements = {
{ unselectable = true, icon = 'fas fa-warehouse', title = 'Garage' },
{ icon = 'fas fa-car', title = 'Take out vehicle', name = 'take_out' },
{ icon = 'fas fa-square-parking', title = 'Park vehicle', name = 'park' },
{ disabled = true, icon = 'fas fa-wrench', title = 'Repair', description = 'Mechanics only' },
}
ESX.OpenContext('right', elements, function(menu, element)
if element.name == 'take_out' then
TriggerServerEvent('my_garage:takeOut')
elseif element.name == 'park' then
TriggerServerEvent('my_garage:park')
end
ESX.CloseContext()
end)
end
RegisterCommand('garage', openGarageMenu, false)ESX.PreviewContext
Shows the menu without taking mouse focus. The player keeps control of the character and can press the preview key (left Alt by default) to focus the menu and click it.
ESX.PreviewContext(position, elements, onSelect, onClose, canClose)The parameters are the same as ESX.OpenContext. The preview key only works
when an onSelect function was passed.
ESX.PreviewContext passes elements to the UI without the HTML stripping that
ESX.OpenContext and ESX.RefreshContext apply.
ESX.CloseContext
Closes the open menu, releases focus and calls the onClose callback. Does
nothing if no menu is open.
ESX.CloseContext()ESX.RefreshContext
Replaces the elements and/or the position of the open menu without closing it.
Callbacks and canClose stay the same.
ESX.RefreshContext(elements, position)| Name | Type | Description |
|---|---|---|
elements | table? | New element list. nil keeps the current elements. |
position | string? | New position. nil keeps the current position. |
-- Update a live counter in the open menu
local elements = {
{ unselectable = true, icon = 'fas fa-users', title = 'Players online' },
{ icon = 'fas fa-hashtag', title = tostring(#GetActivePlayers()) },
}
ESX.RefreshContext(elements)Element fields
| Field | Type | Description |
|---|---|---|
title | string | Main text of the row. |
description | string? | Smaller text below the title. |
icon | string? | Font Awesome 6 free class, e.g. "fas fa-check". Use "" for no icon. |
name | string? | Your identifier. Use it in onSelect and to read input values. |
unselectable | boolean? | Rendered as a header row, not clickable. |
disabled | boolean? | Rendered grayed out, not clickable. |
input | boolean? | Turns the row into an input field. Input rows never trigger onSelect. |
inputType | "text" | "number" | "radio" | Type of input. |
inputPlaceholder | string? | Placeholder text. For radio inputs it also acts as the preselected value when inputValue is not set. |
inputValue | string | number | Initial value. Updated with what the player enters. |
inputMin | number? | Lower bound for number inputs (clamped in the UI and in Lua). |
inputMax | number? | Upper bound for number inputs. |
inputValues | table? | Required for radio: array of { text = 'Label', value = 'key' } options. |
Any other field you add (for example value or job) is kept on the element
and passed back to onSelect.
Form example
Input values are written back to menu.eles when the field changes (on blur or
Enter for text, on change for number and radio). Read them when the player
clicks a submit row:
local function openNameForm()
local elements = {
{ unselectable = true, icon = 'fas fa-id-card', title = 'Register vehicle' },
{ icon = '', title = 'Plate text', input = true, inputType = 'text', inputPlaceholder = 'ABC 123', name = 'plate' },
{ icon = '', title = 'Seats', input = true, inputType = 'number', inputValue = 2, inputMin = 1, inputMax = 8, name = 'seats' },
{
icon = '', title = 'Engine', input = true, inputType = 'radio', name = 'engine', inputValue = 'petrol',
inputValues = {
{ text = 'Petrol', value = 'petrol' },
{ text = 'Electric', value = 'electric' },
},
},
{ icon = 'fas fa-check', title = 'Submit', name = 'submit' },
}
ESX.OpenContext('center', elements, function(menu, element)
if element.name ~= 'submit' then return end
local values = {}
for _, ele in ipairs(menu.eles) do
if ele.input then
values[ele.name] = ele.inputValue
end
end
if not values.plate or values.plate == '' then
ESX.ShowNotification('Enter a plate first', 'error')
return
end
TriggerServerEvent('my_registry:register', values)
ESX.CloseContext()
end)
endValidate on the server
Everything in values comes from the client. Check lengths, ranges and
permissions again in your server event.
Exports
The ESX.* wrappers call these exports. You can use them directly from any
client script.
| Export | Signature | Notes |
|---|---|---|
Open | exports.esx_context:Open(position, elements, onSelect, onClose, canClose) | Opens with focus. No HTML stripping when called directly. |
Preview | exports.esx_context:Preview(position, elements, onSelect, onClose, canClose) | Opens without focus. |
Close | exports.esx_context:Close() | Closes and calls onClose. |
Refresh | exports.esx_context:Refresh(elements, position) | Updates the open menu. |
focusPreview | exports.esx_context:focusPreview() | Gives focus to a previewed menu (same as the preview key). |
State bag
While a menu is open, LocalPlayer.state['context:active'] is true. Other
resources can check it to avoid opening UI on top of the menu:
if LocalPlayer.state['context:active'] then
return
endControls
| Key | Action |
|---|---|
| Mouse click | Select an element |
| Escape / Backspace | Close the menu (ignored while typing in an input, and when canClose is false) |
Left Alt (previewContext) | Focus a menu opened with ESX.PreviewContext |
Commands
| Command | Description |
|---|---|
previewContext | Bound to PREVIEW_KEYBIND; focuses a previewed menu. |
ctx:preview, ctx:open, ctx:close, ctx:form | Debug commands that open sample menus. Only registered when Config.EnableDebug = true in es_extended. |
Common issues
ESX.OpenContextreturnsfalseand nothing shows:esx_contextis not started, or it starts after the resource calling it. Ensure it inserver.cfgafteres_extended.- Argument order:
onSelectandonClosecome beforecanClose, andRefreshContexttakeselementsfirst. Older snippets get both wrong. - Clicking an input row does nothing: by design. Add a separate submit row.
- HTML in titles disappears:
ESX.OpenContextstrips tags on purpose. - Menu stays open after selecting: selecting does not close the menu. Call
ESX.CloseContext()inonSelectwhen you are done. - Mouse cursor stuck after a script error: if your
onSelecterrors before closing, focus stays on the UI. Press Escape, or wrap risky code and always callESX.CloseContext().
Related
- Client UI functions
- esx_menu_default for keyboard-driven list menus
- esx_menu_dialog for single text input
- Core resources overview
Frequently asked questions
Independent documentation
Last updated on
esx_lib
esx_lib reference for ESX Legacy. Load xLib, use callbacks, cache, points, NUI, rate limiting, tokens, pub/sub and every module with signatures.
esx_identity
esx_identity lets ESX Legacy players register first name, last name, date of birth, sex and height. Config, events, commands and validation rules.