Menú contextual de ox_lib: registerContext, inputDialog y alertDialog
Construye menús en FiveM con ox_lib: lib.registerContext y lib.showContext con submenús e iconos, además lib.inputDialog y lib.alertDialog, y soluciona que 'lib' sea nil.
Llamas a lib.registerContext y la consola dice:
attempt to index a nil value (global 'lib')O el código del menú se ejecuta y nada se abre. Este artículo cubre las herramientas de menú de ox_lib: el menú contextual, el diálogo de entrada y el diálogo de alerta, con la línea de manifest que hace que lib exista.
Carga ox_lib en tu manifest
lib es un global que ox_lib añade a tu recurso a través de su archivo init. Sin él, cada llamada a lib. falla con el error anterior. En fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
shared_script '@ox_lib/init.lua'
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }Luego inicia ox_lib antes que tu script en server.cfg:
ensure ox_lib
ensure my_scriptSi el archivo no se puede encontrar en absoluto, véase @ox_lib/init.lua not found.
Un menú contextual
Un menú contextual es una lista de opciones en las que se puede hacer clic. Lo registras una vez bajo una id, luego lo muestras cuando lo necesitas. Ambas llamadas están en el lado del cliente:
lib.registerContext({
id = 'my_script_main',
title = 'Garage',
options = {
{
title = 'Take out a vehicle',
description = 'Choose from your parked vehicles',
icon = 'car',
onSelect = function()
print('take out')
end,
},
{
title = 'Store vehicle',
description = 'Park the vehicle you are in',
icon = 'warehouse',
onSelect = function()
print('store')
end,
},
{
title = 'Impound',
description = 'Not available',
icon = 'lock',
disabled = true,
},
},
})
lib.showContext('my_script_main')Las opciones que usarás más:
| Campo | Qué hace |
|---|---|
title |
El texto principal de la opción. |
description |
Una segunda línea de texto bajo el título. |
icon |
Un nombre de icono Font Awesome, como car. También puedes pasar una clase completa como fa-solid fa-car. |
onSelect |
Función que se ejecuta cuando se hace clic en la opción. |
menu |
La id de otro contexto para abrir (un submenú). |
arrow |
Muestra una flecha a la derecha, una pista de que abre algo. |
disabled |
Desactiva la opción para que no se pueda hacer clic. |
Otros campos existen, como event, serverEvent, args, metadata y progress. Verifica la documentación de ox_lib para la versión que ejecutas.
Submenús
Para abrir un submenú, da a la opción menu con la id del siguiente contexto. Da al segundo contexto un menu que apunte de nuevo al primero, y obtiene un botón de atrás:
lib.registerContext({
id = 'my_script_main',
title = 'Garage',
options = {
{
title = 'My vehicles',
icon = 'car',
arrow = true,
menu = 'my_script_vehicles',
},
},
})
lib.registerContext({
id = 'my_script_vehicles',
title = 'My vehicles',
menu = 'my_script_main',
options = {
{
title = 'Sultan',
description = 'Plate ABC 123',
onSelect = function()
print('selected Sultan')
end,
},
},
})
lib.showContext('my_script_main')Consejo: la tabla de opciones se construye cuando registras el menú. Para una lista que cambia, como los vehículos de un jugador, construye la tabla y llama a
lib.registerContextde nuevo justo antes delib.showContext. Registrar la misma id de nuevo reemplaza el menú antiguo.
lib.hideContext() cierra el menú desde el código.
Solicita entrada con inputDialog
lib.inputDialog abre un formulario y espera hasta que el jugador confirme o cancele. Devuelve una tabla con los valores en orden de fila, o nil si el jugador canceló:
local input = lib.inputDialog('New shop', {
{ type = 'input', label = 'Shop name', required = true },
{ type = 'number', label = 'Price', default = 100, min = 0 },
{ type = 'checkbox', label = 'Open to everyone' },
})
if not input then return end
local name, price, open = input[1], input[2], input[3]
print(name, price, open)Otros tipos de fila incluyen select, slider y textarea. Un select toma una lista de opciones:
local input = lib.inputDialog('Pick a colour', {
{
type = 'select',
label = 'Colour',
options = {
{ value = 'red', label = 'Red' },
{ value = 'blue', label = 'Blue' },
},
},
})
if input then print(input[1]) endPorque la llamada espera, ejecútala en un hilo o en un controlador que se permite esperar, como una función onSelect. Nunca valides solo en el cliente. Cuando el valor va al servidor, veríficalo también allí.
Confirma con alertDialog
lib.alertDialog es una ventana sí/no. Devuelve 'confirm' o 'cancel':
local alert = lib.alertDialog({
header = 'Delete the shop?',
content = 'This cannot be undone.',
centered = true,
cancel = true,
})
if alert == 'confirm' then
print('deleting')
endSin cancel = true hay solo un botón de OK.
Úsalo desde un objetivo o un comando
Un menú generalmente se abre por algo más. Con ox_target, llama a lib.showContext en onSelect (véase ox_target: how to add targets). Con un comando, llámalo en el controlador:
RegisterCommand('garage', function()
lib.showContext('my_script_main')
end, false)Registra los contextos primero, en la parte superior del archivo del cliente o cuando el script se inicia, así que la id existe cuando se ejecuta el comando.
Lista de verificación
| Síntoma | Solución |
|---|---|
attempt to index a nil value (global 'lib') |
Añade shared_script '@ox_lib/init.lua' e inicia ox_lib primero |
lib.showContext no abre nada |
Registra la id con lib.registerContext antes de mostrarla |
| El submenú no tiene botón de atrás | Establece menu en el submenú a la id padre |
| El menú muestra datos obsoletos | Registralo de nuevo con las nuevas opciones antes de lib.showContext |
inputDialog devuelve nil |
El jugador canceló: verifica nil |
| El ícono no aparece | Usa un nombre Font Awesome válido, o una clase completa como fa-solid fa-car |
Respuestas rápidas
¿Por qué lib es nil en mi script?
Tu manifest no carga el archivo init de ox_lib. Añade shared_script '@ox_lib/init.lua' y asegúrate de que ox_lib se inicia antes que tu recurso.
¿Cómo hago un submenú?
Registra un segundo contexto con su propia id, luego da la opción en el primer menú menu = 'second_id'. Establece menu = 'first_id' en el segundo para que obtenga un botón de atrás.
¿Cómo leo lo que escribió el jugador?
lib.inputDialog devuelve una tabla con un valor por fila, en orden, o nil si el jugador canceló. Siempre verifica nil.
Scripts que evitan este problema
Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →
Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →
Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →