PHPackages                             jazzman/form-html-generator - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. jazzman/form-html-generator

ActiveLibrary[HTTP &amp; Networking](/categories/http)

jazzman/form-html-generator
===========================

PHP-HTML form manager

v1.2.2(8y ago)232MITPHPPHP &gt;=5.4.0

Since Sep 17Pushed 8y ago1 watchersCompare

[ Source](https://github.com/Jazz-Man/form-html-generator)[ Packagist](https://packagist.org/packages/jazzman/form-html-generator)[ Docs](https://github.com/Jazz-Man/form-html-generator)[ RSS](/packages/jazzman-form-html-generator/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (6)Dependencies (1)Versions (7)Used By (0)

FormManager
===========

[](#formmanager)

Usage
-----

[](#usage)

### Namespace import

[](#namespace-import)

FormManager is namespaced, but you only need to import a single class into your context:

```
use FormManager\Builder as F;
```

### Create a field

[](#create-a-field)

All HTML5 field types are supported.

```
//Create an input type="text" element
$name = F::text();

//Use the jQuery syntax to set/get/remove attributes:
$name->attr('name', 'username');

$name->attr([
	'maxlength' => 50,
	'required' => true
]);

$maxlength = $name->attr('maxlength');

$name->removeAttr('required');

//Get/set values
$name->val('MyName');

//Get/set css classes
$name->addClass('cool-input');
$name->removeClass('cool-input');

//Get/set/remove data-* attributes
$name->data('id', 23);
$name->data([
	'name' => 'value',
	'foo' => 'bar'
]);
$foo = $name->data('foo');

$name->removeData('id');

$name->removeData(); //Remove all data

//You can chain various methods:
$email = F::email()->addClass('cool-input')->id('my-email')->val('my@email.com');

//And use the __call() magic method to add attributes:
$email->required(); //same than $email->attr('required', true);
$email->required(false); //same than $email->attr('required', false);
```

### Generate the html code

[](#generate-the-html-code)

The html code is created automatically on convert the object into a string:

```
$name = F::text()->class('my-input')->required();

echo $name; //

//print the input with extra attributes
echo $name->addClass('text-input')->placeholder('Your name');
```

### Working with data

[](#working-with-data)

Inputs can validate the data depending of the type and other validation attributes:

```
$url = F::url();

//Set the input as required
$url->required();

//Check if the value is valid
if (!$url->validate()) {
	echo $url->error(); //This value is required
}

//set an invalid url
$url->val('invalid-url');

//check the value and get the error
if (!$url->validate()) {
	echo $url->error(); //This value is not a valid url
}
```

The inputs can handle custom validators:

```
$name = F::text();

function isDave($input)
{
	if ($input->val() !== 'dave') {
		throw new FormManager\InvalidValueException('This value must be "dave"');
	}
}

//Add custom validators
$name->addValidator('isDave');

$name->val('tom');

if (!$name->validate()) {
	echo $name->error(); //This value must be "dave"
}

//Remove the validator
$name->removeValidator('isDave');
```

The `load()` method is like `val()` but it handles the data sent by the client:

```
$name = F::text();

//Add a function to sanitize the data
$name->sanitize(function($value)
{
	return strip_tags($value);
});

//if you use val(), the value remains as is
$name->val('earl');
echo $name->val(); //earl

//if you use load(), the value will be sanitized
$name->load('earl');
echo $name->val(); //earl
```

### Labels

[](#labels)

You can use labels with your inputs, just use the property `->label` and it will be created automatically. It may also generate an extra label with the error message.

```
$name = F::text();

//Define a label
$name->label('User name');

//And modify the label using the same syntax than inputs:
$name->label->class('main-label');

//Print all (label + input)
echo $name;

//Print label and inputs separately
echo $name->label . '' . $name->input;

//Use errorLabel to print a secondary label with the validation error:
echo $name->label . '' . $name->input . $name->errorLabel;
```

### Datalist

[](#datalist)

[Datalist](http://www.w3.org/TR/html5/forms.html#the-datalist-element) are also allowed, just use the `datalist()` method to set/get values:

```
$name = F::search();

//Define the datalist values
$name->datalist([
	'female' => 'Female',
	'male' => 'Male'
]);
```

### Custom renders

[](#custom-renders)

You can configure how each field must be rendered. First, you need to know all properties of each field:

- `$field->input` The input/select/textarea element
- `$field->label` The label element
- `$field->errorLabel` A secondary label with the validation error
- `$field->datalist` An optional datalist instance
- `$field->wrapper` A div element containing all the stuff above

```
$field->render(function ($field) {
	$html = (string) $field->label;
	$html .= ''.$field->input.$field->errorLabel.'';
	$html .= $field->datalist;

	return $html;
});
```

Special fields
--------------

[](#special-fields)

In addition with regular fields (the html5 equivalents: text, textarea, select, datetime, etc...) there are some special fields useful to create more complicate data schemes:

### Group

[](#group)

A group is a simple field to store other fields under a name. The following example shows a group of three fields:

```
$date = F::group([
	'day' => F::number()->min(1)->max(31)->label('Day'),
	'month' => F::number()->min(1)->max(12)->label('Month'),
	'year' => F::number()->min(1900)->max(2013)->label('Year')
]);

//Set values to group
$date->val([
	'day' => 21,
	'month' => 6,
	'year' => 1979
]);

//Get values
$values = $date->val();

//Use array syntax to access to the fields by name
$year = $date['year']->val();

//Add more fields dinamically
$date['hour'] = F::number()->min(0)->max(23)->label('Hour');

//Add other html attributes to the group:
$date->addClass('field-day')->attr(['id' => 'date-field']);
```

### Choose

[](#choose)

This field stores other fields with the same name but different values. Useful for radio inputs or to define various submit buttons.

```
//Create a choose container
$colors = F::choose();

//Add some fields. The keys are the values
$colors->add([
	'red' => F::radio()->label('Red'),
	'blue' => F::radio()->label('Blue'),
	'green' => F::radio()->label('Green')
]);

//Access to the fields by value
$red_radio = $colors['red'];

//Add more fields dinamically
$colors['yellow'] = F::radio()->label('Yellow');

//Set the value
$colors->val('red');

//Get value
$color_choosen = $colors->val();
```

### Collection

[](#collection)

It's like a [group](#group), but stores a collection of values:

```
//Create a collection container
$people = F::collection([
	'name' => F::text()->label('Name'),
	'email' => F::email()->label('email'),
	'age' => F::number()->label('Age')
]);

//Set two values
$people->val([
	[
		'name' => 'Xaquín',
		'email' => 'xaquin@email.com',
		'age' => '24'
	],[
		'name' => 'Uxío',
		'email' => 'uxio@email.com',
		'age' => '37'
	]
]);

//Access to the first group of values:
$group = $people[0];

//Access to any field
echo $people[0]['name']->val(); //returns 'Xaquín'

//Push a new value
$people->pushVal([
	'name' => 'Manoela',
	'email' => 'manoela@email.com',
	'age' => '18'
]);

//Returns the group container used as template for each value inserted.
//useful to use the html template in javascript

$template = $people->getTemplate();

echo ''.$template.'';
```

### CollectionMultiple

[](#collectionmultiple)

If you need different types of values in your collection, CollectionMultiple is the answer:

```
//Create a collectionMultiple container
$article = F::collectionMultiple([
	'section' => [
        'title' => F::text()->label('Title'),
        'text' => F::textarea()->label('Text')
    ],
    'picture' => [
        'caption' => F::text()->label('Caption'),
        'image' => F::file()->label('Image')
    ],
    'quote' => [
        'text' => F::textarea()->label('Text'),
        'author' => F::text()->label('Author')
    ]
]);

//Set values. Note that we need a "type" value to know the type of each row
$article->val([
	[
		'type' => 'section',
		'title' => 'This is the section title',
        'text' => 'Lorem ipsum...',
	],[
		'type' => 'quote',
		'text' => 'You have to learn the rules of the game. And then you have to play better than anyone else.',
		'author' => 'Albert Einstein'
	]
]);

// Note that a hidden input will be created for you to store the group type
$article[0]['type']->val(); //section
$article[0]['type']->attr('type'); //hidden

//Push more values
$article->pushVal([
	'type' => 'section',
	'title' => 'This is another section',
    'text' => 'The world of dogs are better than the cats because...'
]);

//Add new types
$article->add([
	'video' => [
		'title' => F::text()->label('Title'),
		'video' => F::url()->label('Youtube url')
	]
]);

//Returns an array with all templates used
$templates = $article->getTemplate();

foreach ($templates as $name => $template) {
	echo ''.$template.'';
}
```

Loader
------

[](#loader)

The main aim of the loader field is to separate the way to load the data with the way to store and keep this data once it's loaded. Let's say for example, an input type file: if a file is loaded, the value is an array with the same structure than any $\_FILES value, but if user doesn't upload anything, the value is empty. So, what is supposed to do in this case? remove the file or keep the previous value? The loader field has two fields: a "loader" field and a "field" field. The first one is responsive to load the new values (for example, it can be an input type file) and the second keeps the previous value (for example, it can be an input type hidden, or text, etc). Let's see an example:

```
$fileUpload = F::loader([
    'loader' => F::file()->label('Upload a file here'),
    'field' => F::hidden() //this hidden input stores the old value
]);

//Set a value
$fileUpload->val('my-file.png');

//we have this value
echo $fileUpload->val(); //my-file.png

//load empty data
$fileUpload->load(null);

//Nothing was loaded, so we keep the old value
echo $fileUpload->val(); //my-file.png

//load new value
$fileUpload->load($_FILES['file-upload']);

//we have the new value
echo ($fileUpload->val() === $_FILES['file-upload']); //true
```

Forms
-----

[](#forms)

We need a form to put all this things together. The form is just another field, in fact, it's like a [Group](#group).

```
$form = F::form();

//Set the form attributes:
$form->attr([
	'action' => 'test.php',
	'method' => 'post'
]);

//Add some fields and containers
$form->add([
	'name' => F::text()->maxlength(50)->required()->label('Your name'),
	'email' => F::email()->label('Your email'),
	'telephone' => F::tel()->label('Telephone number'),

	'gender' => F::choose([
		'm' => F::radio()->label('Male'),
		'f' => F::radio()->label('Female')
	]),

	'born' => F::group([
		'day' => F::number()->min(1)->max(31)->label('Day'),
		'month' => F::number()->min(1)->max(12)->label('Month'),
		'year' => F::number()->min(1900)->max(2013)->label('Year')
	]),

	'language' => F::select()->options(array(
		'gl' => 'Galician',
		'es' => 'Spanish',
		'en' => 'English'
	))->label('Language'),

	'friends' => F::collection([
		'name' => F::text()->label('Name'),
		'email' => F::email()->label('email'),
		'age' => F::number()->label('Age')
	]),

	'action' => F::choose([
		'save' => F::submit()->html('Save changes'),
		'duplicate' => F::submit()->html('Save changes')
	])
]);

//You can also add new fields using the array syntax (the key will be the input name):
$form['new-input'] = F::range()->min(0)->max(100)->val(50);

//Print the form
echo $form;

//Access to the fields using key names
echo $form['website'];

//Or fields inside fields
echo $form['born']['day'];

//Set the values to all fields:
$form->val([
	'name' => 'Oscar',
	'email' => 'oom@oscarotero.com',
	'gender' => 'm',
	'born' => [
		'day' => 21,
		'month' => 6,
		'year' => 1979
	],
	'language' => 'gl',
	'friends' => [
		[
			'name' => 'Friend 1',
			'email' => 'friend1@email.com',
			'age' => 25,
		],[
			'name' => 'Friend 2',
			'email' => 'friend2@email.com',
			'age' => 30,
		],[
			'name' => 'Friend 3',
			'email' => 'friend3@email.com',
			'age' => 35,
		]
	],
	'action' => 'save'
]);

//Get the values
$values = $form->val();

//To load the raw values from globals $_GET, $_POST and $_FILES:
$form->loadFromGlobals();

//Or specify your own globals
$form->loadFromGlobals($_my_GET, $_my_POST, $_my_FILES);

//Check the errors
if (!$form->validate()) {
	echo 'there are errors in the form';
}
```

Builder
-------

[](#builder)

The `Builder` class is used to ease the creation of fields and containers. For example, instead of this:

```
use FormManager\Containers\Form;
use FormManager\Inputs\Text;
use FormManager\Inputs\Textarea;

$form = new Form([
	'name' => new Text(),
	'bio' => new Textarea(),
]);
```

You can do simply this:

```
use FormManager\Builder as F;

$form = F::form([
	'name' => F::text(),
	'bio' => F::textarea()
]);
```

The `FormManager\Builder` handles the instantation of all theses classes for you using factories. By default, it contains the `FormManager\Factory`, responsible of instantation of all fields and containers.

But you can add your owns factories, creating classes implementing `FormManager\FactoryInterface`.

This is useful for a lot of things. For example, to create custom fields:

```
use FormManager\Builder as F;
use FormManager\FactoryInterface;

class CustomFields implements FactoryInterface
{
	/**
	 * Method required by the interface
	 */
	public function get($name, array $arguments)
	{
		if (method_exists($this, $name)) {
			return $this->$name();
		}
	}

	public function Year()
	{
		return F::number()->min(1900)->max(date('Y'));
	}
}
```

Use it in your app:

```
use FormManager\Builder as F;

F::addFactory(new CustomFields());

$date = F::form([
	'name' => F::text(),
	'born-year' => F::year(),
	'dead-year' => F::year(),
]);
```

Other usage is to save all forms of your app under a namespace:

```
namespace MyApp\Forms;

use FormManager\Builder as F;
use FormManager\Fields\Form;

class EditUserForm extends Form
{
	public function __construct()
	{

		$this->add([
			'name' => F::text()->maxlength(200)->label('Name'),
			'email' => F::email()->label('Email'),
			'password' => F::password()->label('Password'),
			'repeat_password' => F::password()->label('Repeat password')
		]);

		//Add a validator to check the password
		$this->addValidator('password-check', function($form)
		{
			$password1 = $form['password']->val();
			$password2 = $form['repeat_password']->val();

			if ($password1 !== $password2) {
				throw new FormManager\InvalidValueException('The passwords does not match');
			}
		});
	}
}
```

And create a factory

```
use FormManager\FactoryInterface;

class MyForms implements FactoryInterface
{
	public function get($name, array $arguments)
	{
		$class = 'MyApp\\Forms\\'.ucfirst($name);

		if (class_exists($class)) {
			return new $class();
		}
	}
}
```

Use it:

```
use FormManager\Builder as F;

F::addFactory(new MyForms());

$editUser = F::editUserForm();
```

Note: Each time you register a new factory, it will be prepended to the already registered ones, so if you register fields/containers called "Form", "Textarea", etc, they will be used instead the default. This allows extend them.

Builder instances
-----------------

[](#builder-instances)

The static builder is fine for most cases, but sometimes you need to combine differents builders with different factories. So you can create instances:

```
use FormManager\Builder;
use FormManager\Factory;

//Create a builder instance adding the default FormManager factory:
$b1 = new Builder(new Factory());

//Create another builder instance with your custom factory:
$b2 = new Builder();
$b2->add(new MyCustomFactory());

//Now, you're ready to combine them:
$form = $b1->form([
	'name' => $b1->text(),
	'description' => $b2->textarea(),
	'email' => Builder::email()
]);
```

###  Health Score

28

—

LowBetter than 52% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~2 days

Total

6

Last Release

3195d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/bde0917196a65a6134bf7aa9d1b3969ae4ef3b92907662fdf68070d033de6843?d=identicon)[Jazz-Man](/maintainers/Jazz-Man)

---

Top Contributors

[![Jazz-Man](https://avatars.githubusercontent.com/u/6892898?v=4)](https://github.com/Jazz-Man "Jazz-Man (12 commits)")

---

Tags

psr-7validatordatahtmlform

### Embed Badge

![Health badge](/badges/jazzman-form-html-generator/health.svg)

```
[![Health](https://phpackages.com/badges/jazzman-form-html-generator/health.svg)](https://phpackages.com/packages/jazzman-form-html-generator)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.1B3.8k](/packages/guzzlehttp-psr7)[cakephp/cakephp

The CakePHP framework

8.8k19.1M1.7k](/packages/cakephp-cakephp)[symfony/psr-http-message-bridge

PSR HTTP message bridge

1.3k312.3M931](/packages/symfony-psr-http-message-bridge)[league/uri-interfaces

Common tools for parsing and resolving RFC3987/RFC3986 URI

538226.9M39](/packages/league-uri-interfaces)[mezzio/mezzio

PSR-15 Middleware Microframework

3913.8M120](/packages/mezzio-mezzio)[form-manager/form-manager

PHP-HTML form manager

15542.1k7](/packages/form-manager-form-manager)

PHPackages © 2026

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