PHPackages                             j1b1x/forms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. j1b1x/forms

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

j1b1x/forms
===========

v1.1.0(1y ago)185715PHPCI passing

Since Aug 29Pushed 1y ago1 watchersCompare

[ Source](https://github.com/J1b1x/Forms)[ Packagist](https://packagist.org/packages/j1b1x/forms)[ RSS](/packages/j1b1x-forms/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (3)Used By (0)

Forms
=====

[](#forms)

[![php](https://camo.githubusercontent.com/74f7f565e570e394cb9358c41b8d3f1728a9d41a0e7dc10627bbcb45819fd38a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e302d696e666f726d6174696f6e616c)](https://camo.githubusercontent.com/74f7f565e570e394cb9358c41b8d3f1728a9d41a0e7dc10627bbcb45819fd38a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e302d696e666f726d6174696f6e616c)[![api](https://camo.githubusercontent.com/09f5789e63311cafb26c8af7e2f3f9f5fd29d49b678e18edad26402ee7abb73c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706f636b65746d696e652d352e302d696e666f726d6174696f6e616c)](https://camo.githubusercontent.com/09f5789e63311cafb26c8af7e2f3f9f5fd29d49b678e18edad26402ee7abb73c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706f636b65746d696e652d352e302d696e666f726d6174696f6e616c)

#### [![GitHub all releases](https://camo.githubusercontent.com/0eb4dba6a88f9e2b1fc997bb264bb483fe9c5903f2c1bb6e3a973eef689570e8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f4a316231782f466f726d732f746f74616c3f636f6c6f723d76696f6c6574266c6162656c3d446f776e6c6f616473267374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/0eb4dba6a88f9e2b1fc997bb264bb483fe9c5903f2c1bb6e3a973eef689570e8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f4a316231782f466f726d732f746f74616c3f636f6c6f723d76696f6c6574266c6162656c3d446f776e6c6f616473267374796c653d666c61742d737175617265)

[](#)

This is a PocketMine-MP 5.0 form library with PHP 8.0 support and high quality code

Credits
-------

[](#credits)

This API is a spoon of [Frago's](https://github.com/Frago9876543210) [forms library](https://github.com/Frago9876543210/forms) and also includes a ServerSettingsForm which is inspired of [skymin's](https://github.com/sky-min) [ServerSettingsForm](https://github.com/sky-min/ServerSettingForm) virion and a [Image loading fix](#image-fix) which is inspired by [Muqsit's](https://github.com/Muqsit) [FormImagesFix](https://github.com/Muqsit/FormImagesFix) plugin.

Code samples
------------

[](#code-samples)

- [Registration](#registration)
- [Auto-back](#auto-back)
    - [What is "auto-back"?](#auto-back-is-a-feature-that-sends-the-previous-opened-form-to-the-player-once-they-close-a-form-or-click-on-a-back-button-it-also-overwrites-back-buttons-in-a-menuformmenuform-with-close-buttons-if-theres-no-form-to-go-back-to)
    - [Toggling it](#if-you-want-to-use-the-auto-back-feature-you-just-need-to-do)
- [Image Fix](#image-fix)
- [ServerSettingsForm](#serversettingsform)
- [ModalForm](#modalform)
    - [Using ModalForm to represent "yes" / "no" button clicks as `bool` in closure](#using-modalform-to-represent-yes--no-button-clicks-as-bool-in-closure)
    - [Short version of ModalForm to confirm any action](#short-version-of-modalform-to-confirm-any-action)
- [MenuForm](#menuform)
    - [Using MenuForm to display buttons with icons from URL and path](#using-menuform-to-display-buttons-with-icons-from-url-and-path)
    - [Creating MenuForm from array of strings (i.e. from `string[]`) with modern syntax of matching button clicks](#creating-menuform-from-array-of-strings-ie-from-string-with-modern-syntax-of-matching-button-clicks)
    - [Appending MenuForm with new options to handle different permissions](#appending-menuform-with-new-options-to-handle-different-permissions)
- [CustomForm](#customform)
    - [Using CustomForm with strict-typed API](#using-customform-with-strict-typed-api)
    - [Using CustomForm with less strict-typed API](#using-customform-with-less-strict-typed-api)
    - [From/to Data CustomForm](#fromto-data-customform-this-can-be-useful-if-you-want-to-send-the-same-ui-again-but-with-some-changes-such-as-an-error-message-label)
- [Uncloseable Form](#uncloseable-form)
    - [Sending an uncloseable form](#an-uncloseable-form-can-be-useful-if-you-permanently-want-to-display-something-to-the-player)

### Registration

[](#registration)

In order to use the [ServerSettingsForms](#serversettingsform), [ImageFix](#image-fix) and the [auto-back](#autoback) feature you first need to **register** the packet handler by doing

```
protected function onEnable(): void{
    \Jibix\Forms\Forms::register($this);
}
```

Note: You only need to do this if you use this plugin as a virion, otherwise it's handled by the [Main class](https://github.com/J1b1x/Forms/blob/master/src/Jibix/Forms/Main.php)

### Auto-back

[](#auto-back)

Auto-back is a feature that sends the previous opened form to the player once they close a form or click on a back button. It also overwrites back buttons in a [MenuForm](#menuform) with close buttons if there's no form to go back to If you want to use the auto-back feature, you just need to do

```
\Jibix\Forms\Forms::setAutoBack(true);
```

Image fix
---------

[](#image-fix)

Image fix is a workaround for a MCPE MenuForm bug, where url button images take ages to load To make this work you only need to do the [registration](#registration)

### ServerSettingsForm

[](#serversettingsform)

The ServerSettingsForm is similar to a [CustomForm](#customform) and has the same elements, but will be displayed in the player's game-settings ui Once you have registered the packet handler, you can just use the ServerSettingsFormEvent

```
public function onServerSettingsForm(ServerSettingsFormEvent $event): void{
    $player = $event->getPlayer();
    if (!$player->hasPermission(DefaultPermissions::ROOT_OPERATOR)) return; //Not an operator
    (new ServerSettingsForm(
        "§bServer settings",
        [
            new Label("Want to adjust some server settings? Just do it!"),
            new Input("Motd", "§cBest Server!", Server::getInstance()->getNetwork()->getName(), function (Player $player, Input $input): void{
                Server::getInstance()->getNetwork()->setName($input->getName());
            }),
        ],
        function (Player $player, CustomFormResponse $response): void{
           $player->sendMessage("Done! You successfully adjusted the server settings.");
        },
        Image::path("textures/items/diamond") //Set the icon of the form
    ))->send($player);
}
```

### ModalForm

[](#modalform)

Using ModalForm to represent "yes" / "no" button clicks as `bool` in closure

```
$player->sendForm(new ModalForm("A small question", "Is our server cool?",
	//result of pressing the "yes" / "no" button is written to a variable $choice
	function (Player $player, bool $choice): void{
		$player->sendMessage($choice ? "Thank you" : "We will try to become better");
	}
));
```

Short version of ModalForm to confirm any action

```
$player->sendForm(ModalForm::confirm("Teleport request", "Do you want to accept it?",
	//called only when the player selects the "yes" button
	function (Player $player): void{
		$player->sendMessage("*teleporting*");
	}
));
```

### MenuForm

[](#menuform)

Using MenuForm to display buttons with icons from URL and path

```
$player->sendForm(new MenuForm("Select server", "Choose server", [
	//buttons without icon
	new Button("SkyWars #1"),
	//URL and path are supported for image
	new Button("SkyWars #2", null, Image::url("https://static.wikia.nocookie.net/minecraft_gamepedia/images/f/f0/Melon_JE2_BE2.png")),
	new Button("SkyWars #3", null, Image::path("textures/items/apple.png")),
	//If you have some dynamic images you can use Image::detect
	new Button("SkyWars #4", null, Image::detect($image)),
	new BackButton(), //Dynamic back button
], function (Player $player, Button $selected): void{
	$player->sendMessage("You selected: " . $selected->getText());
	$player->sendMessage("Index of button: " . $selected->getValue());
}, function (Player $player): void{
    $player->sendMessage("You closed the server selector!");
}));
```

Shorther/simpler MenuForm, you can directly set the button's onSubmit callback, which can be useful if you have object foreaches

```
foreach ($objectArray as $key => $object) {
    $buttons[] = new Button("Key #$key", function (Player $player, Button $selected) use ($key, $object): void{
        $player->sendMessage("You have selected the key #$key");
        //Do something with $object
    })
}
$buttons[] = new BackButton(); //Dynamic back button
$player->sendForm(new MenuForm("Select key", "Choose key", $buttons));
```

### CustomForm

[](#customform)

Using CustomForm with strict-typed API

```
$player->sendForm(new CustomForm("Enter data", [
	new Dropdown("Select product", ["beer", "cheese", "cola"]),
	new Input("Enter your name", "Bob"),
	new Label("I am label!"), //Note: get() does not work with label
	new Slider("Select count", 0.0, 100.0, 1.0, 50.0),
	new StepSlider("Select product", ["beer", "cheese", "cola"]),
	new Toggle("Creative", $player->isCreative()),
], function (Player $player, CustomFormResponse $response): void{
	$dropdown = $response->getDropdown();
	$player->sendMessage("You selected: " . $dropdown->getSelectedOption());

	$input = $response->getInput();
	$player->sendMessage("Your name is " . $input->getValue());

	$slider = $response->getSlider();
	$player->sendMessage("Count: " . $slider->getValue());

	$stepSlider = $response->getStepSlider();
	$player->sendMessage("You selected: " . $stepSlider->getSelectedOption());

	$toggle = $response->getToggle();
	$player->setGamemode($toggle->getValue() ? GameMode::CREATIVE() : GameMode::SURVIVAL());
}));
```

Using CustomForm with less strict-typed API

```
$player->sendForm(new CustomForm("Enter data", [
	new Dropdown("Select product", ["beer", "cheese", "cola"]),
	new Input("Enter your name", "Bob"),
	new Label("I am label!"), //Note: get() does not work with label
	new Slider("Select count", 0.0, 100.0, 1.0, 50.0),
	new StepSlider("Select product", ["beer", "cheese", "cola"]),
	new Toggle("Creative", $player->isCreative()),
], function (Player $player, CustomFormResponse $response): void{
	[$product1, $username, $count, $product2, $enableCreative] = $response->getValues();

	$player->sendMessage("You selected: $product1");
	$player->sendMessage("Your name is $username");
	$player->sendMessage("Count: $count");
	$player->sendMessage("You selected: $product2");
	$player->setGamemode($enableCreative ? GameMode::CREATIVE() : GameMode::SURVIVAL());
}));
```

Using CustomForms elements with directly setting their onSubmit callback

```
$player->sendForm(new CustomForm("Enter data", [
	new Dropdown("Select product #1", ["beer", "cheese", "cola"], "", function (Player $player, Dropdown $dropdown): void{
	    $player->sendMessage("Your first product is {$dropdown->getSelectedOption()}");
	}),
	new Input("Enter your name", "Bob", "", function (Player $player, Input $input): void{
	    $player->sendMessage("You entered the name: {$input->getValue()}!");
	}),
	new Label("I am label!"),
	new Slider("Select count", 0.0, 100.0, 1.0, 50.0, function (Player $player, Slider $slider): void{
	    $player->sendMessgae("You selected a count of {$slider->getValue()}");
	}),
	new StepSlider("Select product #2", ["beef", "fanta", "chips"], "", function (Player $player, StepSlider $slider): void{
	    $player->sendMessage("Your second product is {$slider->getSelectedOption()}");
	}),
	new Toggle("Creative", $player->isCreative(), function (Player $player, Toggle $toggle): void{
	    $player->setGamemode($toggle->getValue() ? GameMode::CREATIVE() : GameMode::SURVIVAL());
	}),
]));
```

From/to Data CustomForm. This can be useful if you want to send the same ui again, but with some changes, such as an error message label

```
public function sendCustomForm(Player $player, array $data = [], ?string $message = null){
    $player->sendForm(new CustomForm(
        "Enter rank data",
        CustomForm::fromData([
            new Label($message ?? "Enter the ranks data!")
	        new Input("Name", "Owner"),
	        new Slider("Price", 0, 100, 1)
        ], $data),
        function (Player $player, CustomFormResponse $response): void{
            $data = $response->__toData();
            [$name, $price] = $response->getElements();
            $error = match (true) {
                strlen($name) < 4 => "§cThe name must be at least 4 chars!",
                strlen($name) > 20 => "§cThe name must be shorter than 20 chars!",
                //other checks
                default => null
            };
            if ($error !== null) {
                $this->sendCustomForm($player, $data, $error);
                return;
            }
            //Do something with the rank data
        }
    ));
}
```

### Uncloseable form

[](#uncloseable-form)

An uncloseable form can be useful if you permanently want to display something to the player

```
$player->sendForm(new MenuForm(
    "§cMaintenance",
    "Hello {$player->getName()}! Unfortunately we are currently in maintenance to update some server features!\nPlease come back once we announce that we're done with the update.",
    [],
    null,
    Form::uncloseable()
));
```

###  Health Score

35

—

LowBetter than 79% of packages

Maintenance48

Moderate activity, may be stable

Popularity23

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 73.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~606 days

Total

2

Last Release

383d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/17a7e8099b8d2fdc6597c376d6367f3fa04b1e64f9ae07cc408cc3386d71537c?d=identicon)[J1b1x](/maintainers/J1b1x)

![](https://www.gravatar.com/avatar/c1073badf7242d47c040f90cdd3577a6ae9ddb657ebb5675571793ef5df998ff?d=identicon)[xxAROX](/maintainers/xxAROX)

---

Top Contributors

[![J1b1x](https://avatars.githubusercontent.com/u/64813399?v=4)](https://github.com/J1b1x "J1b1x (70 commits)")[![xxAROX](https://avatars.githubusercontent.com/u/57589973?v=4)](https://github.com/xxAROX "xxAROX (14 commits)")[![NeturCrafter](https://avatars.githubusercontent.com/u/96377600?v=4)](https://github.com/NeturCrafter "NeturCrafter (5 commits)")[![poggit-bot](https://avatars.githubusercontent.com/u/22427965?v=4)](https://github.com/poggit-bot "poggit-bot (3 commits)")[![Endermanbugzjfc](https://avatars.githubusercontent.com/u/53002741?v=4)](https://github.com/Endermanbugzjfc "Endermanbugzjfc (2 commits)")[![DerCooleVonDem](https://avatars.githubusercontent.com/u/75242580?v=4)](https://github.com/DerCooleVonDem "DerCooleVonDem (1 commits)")

### Embed Badge

![Health badge](/badges/j1b1x-forms/health.svg)

```
[![Health](https://phpackages.com/badges/j1b1x-forms/health.svg)](https://phpackages.com/packages/j1b1x-forms)
```

###  Alternatives

[webmozart/assert

Assertions to validate method input/output with nice error messages.

7.6k894.0M1.2k](/packages/webmozart-assert)[bensampo/laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.

2.0k15.9M104](/packages/bensampo-laravel-enum)[nette/forms

📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server &amp; client side validation and mature design.

54013.2M450](/packages/nette-forms)[swaggest/json-schema

High definition PHP structures with JSON-schema based validation

48612.5M73](/packages/swaggest-json-schema)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[ashallendesign/laravel-config-validator

A package for validating your Laravel app's config.

217905.3k5](/packages/ashallendesign-laravel-config-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
