MrPoulpi Labs
ox_target

Available scripts

FR
Documentation centre

Categories, submenus and checkboxes

Create categories and nested submenus, use separators, remembered checkboxes, emote shortcuts and the generated weather menu.

Goal: organise the menu in categories and add stateful options. File to edit: config_interactions.lua.

Categories and submenus

A category is a type = 'category' option that opens a submenu named by opens. Attached options declare that name in menu:

{ name = 'police', label = 'Police', icon = 'fa-solid fa-shield', type = 'category', opens = 'police_menu', jobs = { 'police' } },
{ name = 'cuff', menu = 'police_menu', label = 'Cuff', icon = 'fa-solid fa-handcuffs', type = 'client_event', event = 'my_pd:cuff' },
{ name = 'escort', menu = 'police_menu', label = 'Escort', icon = 'fa-solid fa-person-walking', type = 'client_event', event = 'my_pd:escort' },

my_pd:cuff and my_pd:escort are example names.

Expected result: the main menu shows “Police” with an arrow; a click opens a second panel on the right containing “Cuff” and “Escort”. The main menu stays visible and clickable.

Observed rules:

  • Without opens, a category opens the menu named after its own name.
  • Options without menu are top level. An option whose menu matches no category is never shown.
  • A submenu can contain categories: the second panel is then replaced by the next submenu. There is no back button: click the top-level category again, or use opens = 'home' to go back to the root.
  • Submenu names are shared by every option shown on the target. Keep them unique per list to avoid mixing.
  • Avoid cycles (A opens B which opens A): the configurator blocks them.

Separators

separatorAfter = true adds a line after the option. The line only appears when the option itself is shown.

Checkboxes

{
    name = 'hud_compact', label = 'Compact HUD', icon = 'fa-solid fa-toggle-on', type = 'checkbox', default = false,
    onToggle = function(state)
        TriggerEvent('my_hud:compact', state)
    end,
    onInit = function(state)
        TriggerEvent('my_hud:compact', state)
    end
},
  • default: initial state (false when absent).
  • persist: true by default. The state is remembered client side (KVP ox_target:cb:<name>) and restored at next start. persist = false always starts from default.
  • onToggle(state): called on every click, with the new state.
  • onInit(state): called once at start with the restored state. The engine reads this field even though it is not listed in the config_interactions.lua header.
  • The name is the memory key: changing it resets players’ state.

The anti_punch built-in is a checkbox of this kind: its default comes from Config.AntiPunch.defaultEnabled, and a default field on the entry overrides it.

Emote shortcuts

The shipped template groups emotes in categories:

{ name = 'self_emotes', label = 'Emotes', icon = 'fa-solid fa-face-smile', description = 'Emote shortcuts', type = 'category', opens = 'self_emotes', separatorAfter = true },
{ name = 'emote_wave', menu = 'self_emotes', label = 'Wave', icon = 'fa-solid fa-hand', type = 'emote', emote = 'wave' },

For players, use type = 'shared_emote' in Config.PlayerInteractions: with the provided presets, the Config.Commands.sharedEmote command (nearby <emote>) is executed. The name must exist in your emote script.

The weather menu

The entry { name = 'weather_menu', menu = 'self_admin', builtin = 'weather_menu' } generates a whole tree from Config.Weather:

weather_menu (category → ox_weather)
├─ weather_menu_types     → one item per Weather.types
├─ weather_menu_time      → one item per Weather.times, Freeze ON, Freeze OFF
├─ weather_menu_zones     → one item per Weather.zones (if useZones)
├─ weather_menu_blackout  → Blackout ON, OFF, Toggle
├─ weather_menu_tools     → Random weather, server time, blackout state, zone info (if useZones)
└─ weather_menu_local     → local rain and freeze (if localTools)
  • The prefix of generated names is the entry’s name; opens changes the root submenu name (ox_weather by default).
  • The entry’s label, icon, description and separatorAfter replace those of Weather.labels.root.
  • Every generated option requires the weather permission and only shows when the weather integration is available client side.
  • Avoid naming your own options weather_menu_… in the same list: names would overlap.

Common mistakes

  • Empty category: the arrow shows but the panel is empty. Check the spelling of menu.
  • Checkbox without onToggle or onInit: the state changes visually but nothing uses it.
  • Renaming a checkbox: players lose their remembered state.

Search

Type a term: setting, export, error…