Framework agnostic form helpers.
I’ve never found form libraries terribly useful. In my experience, they either work only for the most simple forms, or end up being way more difficult to use than just writing the HTML by hand.
That said, I do need some really basic form helpers to easily pre-populate form fields (like from previous POST to correct errors or from a database) and build drop down boxes.
The primary goal of this library is to solve those 2 problems in a way I don’t hate. If I can make some more robust form helpers that don’t get in my way while I’m at it, all the better.
This library provides helpers for setting default values in otherwise static html form elements as well as an input builder for dynamically creating form elements.
All examples below assume you are using the Composer Autoloader and have imported the correct namespace.
use werx\Forms\Form;
Open a form:
<?=Form::open(['method' => 'POST', 'action' => 'home/submit'])?>
Close a form:
<?=Form::close()?>
Whether using the included input builder or hand writing your html, you can set an array of data that will be available for pre-populating form input values.
<?php
Form::setData($_POST);
?>
When using Form::setData()
, you can dynamically populate text boxes and textareas and pre-select dropdowns, radios, and checkboxes.
<input type="text" name="username" id="username" value="<?=Form::getValue('username')?>">
We can also pre-populate with a default value if the data isn’t available from Form::setData()
. It defaults to null, but you can override this with a 2nd parameter to Form::getValue()
.
<input type="text" name="username" id="username" value="<?=Form::getValue('username', 'josh')?>">
There is also a third parameter to
Form::getValue()
that controls whether or not to escape the value. Default: true
Textareas work the same way.
<textarea name="comments" id="comments"><?=Form::getValue()?></textarea>
Pre-select an item in a drop down using Form::getSelected('name', 'option value')
<select name="state">
<option value="AR" <?=Form::getSelected('state', 'AR')?>>Arkansas</option>
<option value="TX" <?=Form::getSelected('state', 'TX')?>>Texas</option>
<option value="OK" <?=Form::getSelected('state', 'OK')?>>Oklahoma</option>
</select>
Checkboxes and Radios work the same way as Selects, using Form::getChecked()
.
<input type="checkbox" name="pets" value="Cat" <?=Form::getChecked('pets', 'Cat')?> /> Cat
<input type="checkbox" name="pets" value="Dog" <?=Form::getChecked('pets', 'Dog')?> /> Dog
<input type="checkbox" name="pets" value="Fish" <?=Form::getChecked('pets', 'Fish')?> /> Fish
<input type="radio" name="color" value="Red" <?=Form::getChecked('color', 'Red')?> /> Red
<input type="radio" name="color" value="Blue" <?=Form::getChecked('color', 'Blue')?> /> Blue
<input type="radio" name="color" value="Green" <?=Form::getChecked('color', 'Green')?> /> Green
When using the input builders to generate your html, values are automatically pre-populated / selected / checked based on the array passed to Form::setData()
<?=Form::text('username')?>
Renders: <input name="test" id="test" type="text" value="josh" />
Or you can try to automatically determine the value with a fall back value if not found.
<?=Form::text('username')->getValue('josh')?>
You can also manually set the value and ignore anything from Form::setData()
.
<?=Form::text('username')->value('josh')?>
Other text-based input types are also supported and work identically to Form::text()
.
Form::textarea();
Form::hidden();
Form::password();
Form::email();
Form::url();
Form::tel();
You can use the builder to create a select box and specify the options and an optional label. If this key was included in the array passed to Form::setData()
, the proper item will be pre-selected.
<?=Form::select('state')->data(['TX' => 'Texas', 'AR' => 'Arkansas', 'OK' => 'Oklahoma'])->label('Choose');?>
Or you can manually select an option.
<?=Form::select('state')->selected('AR')->data(['AR' => 'Arkansas', 'TX' => 'Texas', 'OK' => 'Oklahoma'])?>
You can also dynamically select an option with default override if the value wasn’t set in Form::setData()
.
<?=Form::select('state')->getValue('AR')->data(['AR' => 'Arkansas', 'TX' => 'Texas', 'OK' => 'Oklahoma'])?>
In the previous example, we’ve used an associative array where the array keys were used for the option values and the array values where used for the option display text.
<select name="state" id="state">
<option value="TX">Texas</option>
<option value="AR">Arkansas</option>
<option value="OK">Oklahoma</option>
</select>
Sometimes, you may want to use the array values for both the option values and the display text. To accomplish this, pass true
as the second parameter to data()
.
<?=Form::select('color')->data(['Red', 'White', 'Blue'], true)->selected('White')?>
<select name="color" id="color">
<option value="Red">Red</option>
<option selected="selected" value="White">White</option>
<option value="Blue">Blue</option>
</select>
Two custom select boxes are provided: selectState()
and selectCounty()
. These behave exactly as the standard select()
, but come preloaded with data.
<?=Form::selectState('state')?>
Note: In addition to the 50 U.S. States, the District of Columbia is also presented.
By default, the 2 character state code will be used as the value. If you want to use the full display name as both the display and the value:
<?=Form::selectState('state')->useDisplayNameForValue()?>
To generate a <select>
list of counties, just tell it which U.S. State you want counties for.
<?=Form::selectCounty('county')->forState('AR')?>
If you want, you can get the array of state/county data easily enough.
$counties = \werx\Forms\DataSets::counties('AR');
/*
Array
(
[0] => Arkansas
[1] => Ashley
[2] => Baxter
[3] => Benton
[4] => Boone
[5] => Bradley
...
*/
$states = \werx\Forms\DataSets::states();
/*
Array
(
[AL] => Alabama
[AK] => Alaska
[AZ] => Arizona
[AR] => Arkansas
[CA] => California
[CO] => Colorado
[CT] => Connecticut
[DE] => Delaware
...
*/
You can also use the builder to create checkboxes and radios. As with the other elements, items will be pre-checked if they were passed to Form::setData()
.
<?=Form::checkbox('pets')->value('Cat')?> Cat
<?=Form::checkbox('pets')->value('Dog')?> Dog
<?=Form::checkbox('pets')->value('Fish')?> Fish
<?=Form::radio('color')->value('Red')?> Red
<?=Form::radio('color')->value('Blue')?> Blue
<?=Form::radio('color')->value('Green')?> Green
You can force an item to be checked.
<?=Form::checkbox('pets')->value('Cat')?> Cat
<?=Form::checkbox('pets')->value('Dog')->checked()?> Dog
<?=Form::checkbox('pets')->value('Fish')?> Fish
<?=Form::radio('color')->value('Red')?> Red
<?=Form::radio('color')->value('Blue')->checked()?> Blue
<?=Form::radio('color')->value('Green')?> Green
Use the checkedWhen()
method if you want to check something pending some condition. Pass any condition you like. If it evaluates to true, it will call checked()
on the element.
<?=Form::radio('color')->value('Red')->checkedWhen($some_value == 'Red')?> Red
<?=Form::radio('color')->value('Blue')->checkedWhen($some_value == 'Blue')?> Blue
<?=Form::radio('color')->value('Green')->checkedWhen($some_value == 'Green')?> Green
checkedWhen()
works for both radios and checkboxes.
<?=Form::button('reset')->type("reset")->value('submit')->label('Start Over')?>
<?=Form::submit('submit')->value('Submit')->label('Search')?>
With all dynamic form builders, you can chain methods together to add additional attributes like CSS classes or Inline Styles. Just call the method that corresponds to the attribute name you want, passing in the attribute value.
<?=Form::text('name')->class('form-control')->style('width: 250px')?>
<?=Form::submit('submit')->class('btn btn-primary')->value('Submit')->label('Submit')?>
You can also add the “required” attribute to any form element.
<?=Form::text('name')->required()?>
This package is installable and autoloadable via Composer as werx/forms. If you aren’t familiar with the Composer Dependency Manager for PHP, you should read this first.
$ composer require werx/forms --prefer-dist
$ vendor/bin/phpunit
This library uses PHP_CodeSniffer to ensure coding standards are followed.
I have adopted the PHP FIG PSR-2 Coding Standard EXCEPT for the tabs vs spaces for indentation rule. PSR-2 says 4 spaces. I use tabs. No discussion.
To support indenting with tabs, I’ve defined a custom PSR-2 ruleset that extends the standard PSR-2 ruleset used by PHP_CodeSniffer. You can find this ruleset in the root of this project at PSR2Tabs.xml
Executing the codesniffer command from the root of this project to run the sniffer using these custom rules.
$ ./codesniffer