Input Dialog

The Input dialog system provides modal input forms for collecting user data with validation, formatting, and customization options. Perfect for gathering text input, numbers, and other user data.

Dark Input Dialog

Input Dialogs

Modal input dialogs for collecting user data with validation and customization options. Perfect for gathering text input, numbers, and other user data with comprehensive validation support.

Features

  • Multiple Input Types: Text, number, password, email, and more

  • Validation Support: Built-in and custom validation rules

  • Theme Integration: Adapts to dark/light themes automatically

  • Modal Design: Focused input experience with backdrop

  • Keyboard Navigation: Full keyboard support with Enter/Escape handling

  • NUI Focus Management: Automatic cursor and keyboard focus handling

  • Server-Side Support: Can be triggered from server-side with callbacks

B2Lib.UI.input

Display an input dialog to collect user data.

-- Client-side
B2Lib.UI.input(options, callback)

-- Server-side
B2Lib.UI.input(playerId, options, callback)

playerId: number (server-side only) Player server ID to show the input dialog to.

options: table (object)

  • title?: string Dialog title (default: 'Input Required').

  • subtitle?: string Dialog subtitle (default: empty string).

  • placeholder?: string Input placeholder text (default: 'Enter value...').

  • defaultValue?: string Pre-filled input value (default: empty string).

  • type?: string Input type - 'text', 'number', 'password' (default: 'text').

  • required?: boolean Whether input is required (default: true).

  • maxLength?: number Maximum character limit (default: 255).

  • minLength?: number Minimum character requirement (default: 0).

  • validation?: function Custom validation function.

  • confirmText?: string Confirm button text (default: 'Confirm').

  • cancelText?: string Cancel button text (default: 'Cancel').

  • allowCancel?: boolean Whether cancel is allowed (default: true).

  • position?: string Dialog position (default: from config).

  • showBackground?: boolean Show background overlay (default: from config).

  • id?: string Custom input dialog ID (default: auto-generated).

callback: function|nil (optional) Callback function to handle the input result.

Returns: number|boolean - Input dialog ID on success, false on failure

Example:

-- Client-side usage
B2Lib.UI.input({
    title = 'Enter Your Name',
    placeholder = 'Your name...',
    maxLength = 50
}, function(result)
    if result and result.value then
        print('User entered:', result.value)
    else
        print('Input was cancelled')
    end
end)

-- Server-side usage (sends to specific player)
B2Lib.UI.input(playerId, {
    title = 'Server Input Request',
    placeholder = 'Enter your response...',
    maxLength = 100
}, function(result)
    if result and result.value then
        print('Player ' .. playerId .. ' entered:', result.value)
        B2Lib.UI.notify(playerId, {
            message = 'Input received: ' .. result.value,
            type = 'success'
        })
    end
end)

B2Lib.UI.hideInput

Hide the currently active input dialog.

B2Lib.UI.hideInput()

Returns: boolean - Success status

Example:

-- Hide input dialog
local success = B2Lib.UI.hideInput()

Input Types

Text Input

Standard text input for general text data.

B2Lib.UI.input({
    title = 'Player Name',
    type = 'text',
    placeholder = 'Enter your character name',
    maxLength = 30,
    required = true
})

Number Input

Numeric input with automatic validation.

B2Lib.UI.input({
    title = 'Set Price',
    type = 'number',
    placeholder = 'Enter price',
    defaultValue = '0',
    maxLength = 8
})

Password Input

Masked input for sensitive data.

B2Lib.UI.input({
    title = 'Security Code',
    type = 'password',
    placeholder = 'Enter 4-digit code',
    maxLength = 4,
    minLength = 4
})

Validation

Input dialogs support custom validation functions:

Custom Validation

-- Phone number validation
B2Lib.UI.input({
    title = 'Phone Number',
    placeholder = '(555) 123-4567',
    validation = function(value)
        -- Check for phone number pattern
        return value:match("^%(%d%d%d%) %d%d%d%-%d%d%d%d$") ~= nil
    end
})

-- Username validation
B2Lib.UI.input({
    title = 'Username',
    placeholder = 'Enter username',
    validation = function(value)
        -- Alphanumeric only, 3-16 characters
        return value:match("^[%w_]+$") and #value >= 3 and #value <= 16
    end
})

-- Age validation
B2Lib.UI.input({
    title = 'Age',
    type = 'number',
    validation = function(value)
        local num = tonumber(value)
        return num and num >= 18 and num <= 100
    end
})

Events

The Input system triggers events for handling user input:

b2lib:input-submitted

Triggered when user submits input (client-side only).

AddEventHandler('b2lib:input-submitted', function(data)
    if data.value and data.value ~= '' then
        print('User entered:', data.value)
        -- Process the input
        processUserInput(data.value)
    else
        print('Input was cancelled or empty')
    end
end)

Note: When using callbacks with B2Lib.UI.input(), the callback function is preferred over event handlers as it provides better context and error handling.

Server-Side Usage

Input with Callback

-- Request input from specific player
B2Lib.UI.input(source, {
    title = 'Transfer Amount',
    placeholder = 'Enter amount to transfer',
    type = 'number',
    maxLength = 10,
    validation = function(value)
        local num = tonumber(value)
        return num and num > 0 and num <= 10000
    end
}, function(result)
    if result and result.value then
        local amount = tonumber(result.value)
        -- Process the transfer
        processTransfer(source, amount)
        
        B2Lib.UI.notify(source, {
            message = string.format('Transfer of $%d completed', amount),
            type = 'success'
        })
    else
        B2Lib.UI.notify(source, {
            message = 'Transfer cancelled',
            type = 'info'
        })
    end
end)

Multi-Step Input Process

-- Step 1: Get player name
B2Lib.UI.input(source, {
    title = 'Character Creation',
    subtitle = 'Step 1 of 3',
    placeholder = 'Enter character name',
    maxLength = 30
}, function(nameResult)
    if not nameResult or not nameResult.value then return end
    
    local characterName = nameResult.value
    
    -- Step 2: Get character age
    B2Lib.UI.input(source, {
        title = 'Character Creation',
        subtitle = 'Step 2 of 3',
        placeholder = 'Enter character age',
        type = 'number',
        maxLength = 3
    }, function(ageResult)
        if not ageResult or not ageResult.value then return end
        
        local characterAge = tonumber(ageResult.value)
        
        -- Step 3: Confirm details
        B2Lib.UI.alert(source, {
            title = 'Confirm Character',
            message = string.format('Name: %s\nAge: %d\n\nCreate this character?', characterName, characterAge),
            type = 'confirm'
        }, function(confirmed)
            if confirmed then
                createCharacter(source, characterName, characterAge)
            end
        end)
    end)
end)

Configuration

Configure Input dialog defaults in Config.lua:

-- Input dialog configuration
Config.Input = {
    position = 'center',         -- Default position
    showBackground = true,       -- Show background by default
    enableValidation = true      -- Enable input validation
}

-- Input dialog styling configuration
Config.ComponentStyles.inputDialog = {
    width = '400px',             -- Dialog width
    padding = '24px',            -- Internal padding
    borderRadius = 'xl',         -- Border radius
    shadow = 'xl',               -- Shadow style
    borderWidth = '1px',         -- Border width
    
    -- Title styling
    title = {
        fontSize = 'lg',         -- Title font size
        fontWeight = 'semibold', -- Title font weight
        marginBottom = '16px'    -- Title bottom margin
    },
    
    -- Description styling
    description = {
        fontSize = 'sm',         -- Description font size
        fontWeight = 'normal',   -- Description font weight
        lineHeight = 'relaxed',  -- Description line height
        marginBottom = '20px'    -- Description bottom margin
    },
    
    -- Input field styling
    input = {
        padding = '12px 16px',   -- Input padding
        borderRadius = 'lg',     -- Input border radius
        fontSize = 'sm',         -- Input font size
        borderWidth = '1px',     -- Input border width
        focusRingWidth = '2px',  -- Focus ring width
        marginBottom = '20px'    -- Input bottom margin
    },
    
    -- Button styling
    button = {
        padding = '10px 20px',   -- Button padding
        borderRadius = 'lg',     -- Button border radius
        fontSize = 'sm',         -- Button font size
        fontWeight = 'medium',   -- Button font weight
        spacing = '12px',        -- Button spacing
        hoverTransition = 'fast' -- Button hover transition
    }
}

Advanced Examples

Conditional Input Based on User Type

local function conditionalInput(playerId, userType)
    if userType == 'admin' then
        B2Lib.UI.input(playerId, {
            title = 'Admin Access Code',
            type = 'password',
            placeholder = 'Enter admin code',
            maxLength = 8,
            validation = function(value)
                return value == 'admin123' -- Simple example
            end
        }, function(result)
            if result and result.value then
                grantAdminAccess(playerId)
            end
        end)
    elseif userType == 'player' then
        B2Lib.UI.input(playerId, {
            title = 'Player Registration',
            placeholder = 'Enter display name',
            maxLength = 20,
            required = true
        }, function(result)
            if result and result.value then
                registerPlayer(playerId, result.value)
            end
        end)
    end
end

Input with Complex Validation

-- Bank account creation with multiple validation rules
B2Lib.UI.input(source, {
    title = 'Create Bank Account',
    subtitle = 'Enter your desired account PIN',
    placeholder = '4-digit PIN',
    type = 'password',
    maxLength = 4,
    minLength = 4,
    validation = function(value)
        -- Must be exactly 4 digits
        if not value:match("^%d%d%d%d$") then
            return false
        end
        
        -- Cannot be sequential (1234, 4321)
        if value == "1234" or value == "4321" then
            return false
        end
        
        -- Cannot be all same digits (1111, 2222, etc.)
        if value:match("^(%d)%1%1%1$") then
            return false
        end
        
        return true
    end
}, function(result)
    if result and result.value then
        createBankAccount(source, result.value)
        B2Lib.UI.notify(source, {
            message = 'Bank account created successfully!',
            type = 'success'
        })
    end
end)

Dynamic Input Based on Context

-- Vehicle interaction system
local function showVehicleInput(playerId, vehicleId, action)
    if action == 'lock' then
        B2Lib.UI.input(playerId, {
            title = 'Lock Vehicle',
            subtitle = 'Enter security code to lock this vehicle',
            placeholder = 'Security code',
            type = 'password',
            maxLength = 6
        }, function(result)
            if result and result.value then
                lockVehicle(vehicleId, result.value)
            end
        end)
    elseif action == 'rename' then
        B2Lib.UI.input(playerId, {
            title = 'Rename Vehicle',
            subtitle = 'Enter a new name for this vehicle',
            placeholder = 'Vehicle name',
            maxLength = 30,
            defaultValue = getVehicleName(vehicleId)
        }, function(result)
            if result and result.value then
                renameVehicle(vehicleId, result.value)
            end
        end)
    end
end

Best Practices

  1. Use appropriate input types - Match input type to expected data

  2. Provide clear placeholders - Help users understand expected format

  3. Implement validation - Validate input on both client and server

  4. Use callbacks effectively - Prefer callbacks over events for better context

  5. Set reasonable limits - Use appropriate min/max length constraints

  6. Handle cancellation gracefully - Always handle the case where users cancel

  7. Test edge cases - Test with empty input, special characters, etc.

  8. Provide user feedback - Use notifications to confirm actions

  9. Server-side validation - Always validate input on the server side as well

Troubleshooting

Input Dialog Not Showing

  1. Check that B2Lib is properly initialized

  2. Verify no other modal dialogs are active

  3. Check console for error messages from B2Lib.Debug

  4. Ensure NUI focus is available

  5. Verify B2Lib.UI is available (check with print(B2Lib.UI ~= nil))

Validation Not Working

  1. Verify validation function returns boolean

  2. Check for JavaScript errors in console

  3. Test validation function independently

  4. Ensure validation logic is correct

  5. Check that validation function doesn't throw errors

Input Not Submitting

  1. Check that required fields are filled

  2. Verify validation passes

  3. Ensure callback functions are properly defined

  4. Check for conflicting key bindings

  5. Verify server-side callback handling

Server-Side Issues

  1. Ensure player ID is valid when calling from server

  2. Check that callback functions don't reference invalid variables

  3. Verify network events are properly registered

  4. Check server console for callback-related errors

NUI Focus Issues

  1. Verify no other resources are interfering with NUI focus

  2. Check that input dialogs are properly closed before opening new ones

  3. Ensure proper cleanup in callback functions

  4. Test with minimal resource load to isolate conflicts


Last updated