composer require nitroxy/php-forms
or install manually.
Forms can be created using three different constructors: create
, fromArray
and fromObject
. Among the three create
is the simplest and most manual, only taking an ID and a closure.
Form::create('example1', function($f){ $f->textField('name', 'My field name'); });
<form id="example1" class="form table" method="POST" action=""> <table class="layout"> <tr > <th class="form-label"><label for="example1_name">My field name</label></th> <td class="form-field"><input id="example1_name" name="name" type="text" /></td> <td class="form-hint" ></td> <td class="form-error"></td> </tr> </table> </form>
PHP-Forms supports a few default layout engines or you can create your own custom. The layout engines is used to render each field.
Form::create("example2-$layout", function($f){ $f->textField('name', 'My field name'); }, ['layout' => $layout]);
The default layout is table-based and will put the labels and fields in columns. Quick-and-dirty way to get a form.
Plain layout is similar to tables but will instead use spans and divs.
Outputs fields with bootstrap classes.
A special layout called unbuffered
also exists which allow full freedoom when creating the form. All fields is outputted directly as is, no labels, hints etc. Useful when you want to create a very custom form but still wants features such as value persistance, CRSF-protection, etc.
To enable CSRF protection you need to extend Form
. This will ensure the token is present on all forms (using a special hidden called csrf_token
). The developer must validate the token when POSTing the form.
class MyForm extends Form { protected static function csrfToken(){ return get_current_csrf_token(); } }; MyForm::create("example_csrf", function($f){ /* ... */ });
<form id="example_csrf" class="form table" method="POST" action=""> <input value="my-current-csrf-token" name="csrf_token" type="hidden" /> </form>
To support other methods than GET and POST Form
inserts a hidden field _method
and uses POST to submit.
Form::create("example_method", function($f){ /* ... */ }, ['method' => 'patch']);
<form id="example_method" class="form table" method="POST" action=""> <input value="PATCH" name="_method" type="hidden" /> </form>
Method | Submitted as | _method | |
---|---|---|---|
GET | GET | unset | |
POST | POST | unset | |
PATCH | POST | PATCH | |
DELETE | POST | DELETE | |
... and so on. |
By utilizing either fromArray
or fromObject
values can be stored and automatically filled into the form.
Objects will use the classname by default (e.g. MyCustomClass in the example) and fromArray
has an argument for ID. In addition there is also an form option prefix
which can be used to customize it. Field names are set as prefix[fieldname]
. The major reason is to read the entire object at once by accessing $_POST['prefix']
.
If you are using BasicObject you can use $model = MyModel::update_attributes($_POST['MyCustomClass'], ['permit' => ['name', 'age', role', description']);
to update the model.
class MyCustomClass extends stdClass { }; $myObject = new MyCustomClass; $myObject->name = 'John Doe'; $myObject->age = 46; $myObject->role = 2; /* frobnicator */ $myObject->description = 'Lorem ipsum dot sit amet.'; Form::fromObject($myObject, function($f){ $f->textField('name', 'Name'); $f->textField('age', 'Age', ['type' => 'number', 'min' => 1]); $f->select('role', 'Role', FormOptions::fromArray(['', 'Manager', 'Frobnicator', 'Developer'])); $f->textarea('description', 'Description'); }, ['layout' => 'bootstrap']);
Forms can be nested by using fieldsFor
to allow either sending to unrelated objects or multiple instances of the same class.
class MyClassA {}; class MyClassB {}; $a = new MyClassA; $a->name = 'Name A'; $b = new MyClassB; $b->name = 'Name B'; Form::create('example6', function($f) use ($a, $b) { $f->fieldsFor('A', $a, function($f){ $f->textField('name', 'Name'); }); $f->fieldsFor('B', $b, function($f){ $f->textField('name', 'Name'); }); }, ['layout' => 'bootstrap']);