celestifyx / form
Form library
1.0.0
2025-08-27 19:50 UTC
Requires
- php: ^8.3
This package is not auto-updated.
Last update: 2025-08-28 15:14:27 UTC
README
A powerful, flexible PHP form library for PocketMine-MP servers with strict typing and modern PHP 8.3+ features.
Installation
composer require celestifyx/form
Quick Start
use pocketmine\player\Player;
use nerve\form\FormBuilder;
use nerve\form\forms\ModalForm;
use nerve\form\forms\MenuForm;
use nerve\form\forms\CustomForm;
use nerve\form\elements\Button;
use nerve\form\elements\Input;
use nerve\form\elements\Toggle;
use nerve\form\enums\ImageType;
use nerve\form\response\CustomFormResponse;
// Simple confirmation
$form = FormBuilder::confirm("Delete Item", "Are you sure?", function (Player $player): void {
$player->sendMessage("Item deleted!");
});
// Menu with buttons
$form = FormBuilder::menu("Main Menu", "Choose an option:")
->append("Settings", "Help", "Exit")
->onSubmit(function (Player $player, Button $button): void {
$player->sendMessage("Selected: " . $button->getText());
});
$player->sendForm($form);
Form Types
Modal Form
Binary choice forms (Yes/No, OK/Cancel).
$form = FormBuilder::modal(
"Confirmation",
"Do you want to proceed?",
function (Player $player, bool $response): void {
match ($response) {
true => $player->sendMessage("Confirmed!"),
false => $player->sendMessage("Cancelled!")
};
},
"Yes",
"No"
);
// Or use shorthand for confirmations
$form = FormBuilder::confirm("Delete", "Are you sure?", function (Player $player): void {
// Handle confirmation
});
Menu Form
List of buttons for navigation.
$form = FormBuilder::menu("Game Menu", "Select an option:")
->append(
FormBuilder::button("Play", FormBuilder::image("textures/ui/play.png", ImageType::PATH)),
FormBuilder::button("Settings"),
"Exit" // String buttons are auto-converted
)
->onSubmit(function (Player $player, Button $button): void {
match ($button->getText()) {
"Play" => $this->startGame($player),
"Settings" => $this->openSettings($player),
"Exit" => $player->quit()
};
});
Custom Form
Complex forms with multiple input elements.
$form = FormBuilder::custom("Player Settings", [
FormBuilder::label("Personal Information"),
FormBuilder::input("Username", "Enter username", $player->getName()),
FormBuilder::dropdown("Rank", ["Member", "VIP", "Admin"], 0),
FormBuilder::toggle("Receive notifications", true),
FormBuilder::slider("Volume", 0, 100, 1, 50),
FormBuilder::stepSlider("Difficulty", ["Easy", "Normal", "Hard"], 1)
], function (Player $player, CustomFormResponse $response): void {
$username = $response->getInput()->getValue();
$rank = $response->getDropdown()->getSelectedOption();
$notifications = $response->getToggle()->getValue();
$volume = $response->getSlider()->getValue();
$difficulty = $response->getStepSlider()->getSelectedOption();
// Process form data
});
Server Settings Form
Special form type with icon support.
$form = FormBuilder::serverSettings(
"Server Configuration",
[
FormBuilder::input("Server Name", "Enter name", "My Server"),
FormBuilder::toggle("PvP Enabled", false)
],
FormBuilder::image("textures/ui/server_icon.png", ImageType::PATH),
function (Player $player, CustomFormResponse $response): void {
// Handle server settings
}
);
Direct Form Creation (Without FormBuilder)
You can create forms directly without using FormBuilder:
use nerve\form\forms\{ModalForm, MenuForm, CustomForm};
use nerve\form\elements\{Button, Input, Toggle};
use pocketmine\player\Player;
use nerve\form\response\CustomFormResponse;
// Direct modal form creation
$modal = new ModalForm(
"Confirmation",
"Are you sure?",
function (Player $player, bool $response): void {
match ($response) {
true => $player->sendMessage("Yes!"),
false => $player->sendMessage("No!")
};
}
);
// Direct menu form creation
$menu = new MenuForm(
"Main Menu",
"Choose option:",
[
new Button("Play"),
new Button("Exit")
],
function (Player $player, Button $button): void {
$player->sendMessage("Selected: " . $button->getText());
}
);
// Direct custom form creation
$custom = new CustomForm(
"Settings",
[
new Input("Name", "Enter name"),
new Toggle("Notifications", true)
],
function (Player $player, CustomFormResponse $response): void {
$name = $response->getInput()->getValue();
$notify = $response->getToggle()->getValue();
}
);
Elements
Input
Text input field.
FormBuilder::input("Name", "Enter your name", "Default value")
Label
Display-only text.
FormBuilder::label("Section Header")
Toggle
Boolean switch.
FormBuilder::toggle("Enable feature", true) // default: true
Slider
Numeric range selector.
FormBuilder::slider("Volume", 0, 100, 5, 50) // min, max, step, default
Dropdown
Single selection from list.
FormBuilder::dropdown("Choose option", ["Option 1", "Option 2"], 0) // default index: 0
Step Slider
Discrete value selector.
FormBuilder::stepSlider("Difficulty", ["Easy", "Normal", "Hard"], 1)
Button
Menu form button with optional image.
FormBuilder::button("Click me", FormBuilder::image("icon.png"))
Image
Icon for buttons or server settings.
FormBuilder::image("https://example.com/icon.png") // URL (default)
FormBuilder::image("textures/ui/icon.png", ImageType::PATH) // Resource pack path
Advanced Usage
Form Chaining
$mainMenu = FormBuilder::menu("Main Menu", "Choose:")
->append("Settings", "About")
->onSubmit(function (Player $player, Button $button): void {
match ($button->getText()) {
"Settings" => $this->openSettings($player),
"About" => $this->showAbout($player)
};
});
private function openSettings(Player $player): void {
FormBuilder::custom("Settings", [
FormBuilder::toggle("Sound", true),
FormBuilder::slider("FOV", 30, 120, 1, 90)
], function (Player $player, CustomFormResponse $response): void {
// Save settings and return to main menu
$this->saveSettings($player, $response);
$this->openMainMenu($player);
})->sendTo($player);
}
Response Handling
$form = FormBuilder::custom("Registration", [
FormBuilder::input("Email", "user@example.com"),
FormBuilder::input("Password", "Password", ""),
FormBuilder::dropdown("Country", ["USA", "UK", "Canada"]),
FormBuilder::toggle("Subscribe to newsletter")
], function (Player $player, CustomFormResponse $response): void {
// Get values in order
$email = $response->getInput()->getValue();
$password = $response->getInput()->getValue();
$country = $response->getDropdown()->getSelectedOption();
$subscribe = $response->getToggle()->getValue();
// Or get all values as array
$values = $response->getValues(); // ["email", "password", "USA", true]
// Validate and process
match (filter_var($email, FILTER_VALIDATE_EMAIL)) {
false => $player->sendMessage("Invalid email!"),
default => $this->registerUser($player, $email, $password, $country, $subscribe)
};
});
Close Handling
$form = FormBuilder::menu("Important Choice", "This is important!")
->append("Accept", "Decline")
->onSubmit(function (Player $player, Button $button): void {
// Handle selection
})
->onClose(function (Player $player): void {
$player->sendMessage("You must make a choice!");
// Reopen form or take action
});
Dynamic Forms
class ShopForm {
function create(Player $player, string $category): MenuForm {
$items = $this->getItemsByCategory($category)
$buttons = array_map(fn ($item) =>
FormBuilder::button($item->getName(), $item->getIcon()),
$items
);
return FormBuilder::menu("Shop - " . $category, "Select item:")
->append(...$buttons)
->onSubmit(function (Player $player, Button $button) use ($items): void {
$selectedItem = $items[$button->getValue()];
$this->purchaseItem($player, $selectedItem);
});
}
}
Error Handling
use InvalidArgumentException;
use pocketmine\form\FormValidationException;
try {
$form = FormBuilder::custom("Test", [
FormBuilder::slider("Invalid", 100, 0) // min > max
], function (Player $player, CustomFormResponse $response): void {});
} catch (InvalidArgumentException $e) {
$player->sendMessage("Form error: " . $e->getMessage());
}
The library automatically validates form responses and throws FormValidationException
for invalid data.
Features
- Strict Typing: Full type safety with PHP 8.3+ features
- Modern PHP: Uses match expressions, constructor promotion, readonly properties
- Flexible API: Use FormBuilder or create forms directly
- Method Chaining: Fluent interface for clean code
- Automatic Validation: Built-in response validation
- Error Handling: Comprehensive exception handling
- Clean Code: No if/else chains, uses modern PHP patterns