Helper classes for escaping input values, generating HTML tags, and managing data.
MIT Licence
PSR-1, PSR-2, and PSR-4.
composer require "tuum/form: ^1.0"
There are many helpers, and some are related. It would be easier to use DataView
object to manage helpers. For instance,
$view = new Tuum\Form\DataView();
$view->setData([
'name' => 'my-name',
'bold' => '<b>bold</b>',
'list' => ['v1', 'v2'],
]);
$view->setInputs([
'name' => 'old-name',
'more' => [
'key' => 'val'
]
]);
// getting escaped data.
echo $view->data['name']; // 'my-name'
echo $view->data['bold']; // escaped <b>bold</b>
echo $view->data->get('bold'); // escaped <b>bold</b>
echo $view->data->raw('bold'); // raw <b>bold</b>
// and arrays.
$list = $view->data->extractKey('list');
echo $list[0]; // 'v1'
echo $list[1]; // 'v2'
// getting old inputs
echo $view->inputs->get('name', $data['name']); // 'old-name'
echo $view->inputs->get('more[key]'); // val
// and use it in form generator.
echo $view->forms->text('name', 'default');
// will output <input type="text" value="old-name">
The DataView
object injects Inputs
object into Forms
helper so that it can generate HTML tags using old input values (i.e. old-name) instead of given value (default).
These helpers help to manage data to be viewed in a template. There are,
Escape
for escaping string,Data
for managing data,Inputs
for managing input-data,Errors
for managing input-errors,Message
for messages,Forms
for generating form elements, andDates
for generating complex form elements.
The Escape
class manages the escaping string to securely display text in a certain content, such as HTML.
As a default, strings will be escaped using Escape::htmlSafe($string)
method (which internally uses htmlspecialchars
function for HTML files). There are some other way to escape.
$esc = new Escape();
echo $esc('<danger>safe</danger>'); // or
echo $esc->escape('<danger>safe</danger>');
You can specify another escape method at the construction or using withEscape
method:
$esc = new Escape('addslashes');
// or
$esc = $esc->setEscape('rawurlencode');
The escape method must be a callable; either a function name, or a closure with string as an argument.
The DataView
object contains an Escape
object to be shared with other helpers, such as Data
and Inputs
.
Specify the escape at the construction.
$view = new DataView(new Escape('addslashes'));
$view->inputs->get('with-slash'); // escaped with addslashes.
// or change how to escape
$view->escape->setEscape('rawurlencode');
Use Data
class to display strings and values to template while escaping the values.
// construct yourself.
$data = Data::forge(['view'=>'<i>val</i>'], $escape);
// or use DataView class.
$view = new DataView();
$view->setData(['some'=>'value']);
$data = $view->data;
to access data, any of the following works.
echo $data['view']; // escaped
echo $data->view; // escaped
echo $data->get('view'); // escaped
echo $data->raw('view'); // raw value
echo $data->get('none', 'non\'s'); // show escaped default value
the Data
object implements IteratorAggregate interface.
$data1 = [
'text' => 'testing',
'more' => '<b>todo</b>',
];
$data2 = [
'text' => 'tested',
'more' => '<i>done</i>',
];
$data = Data::forge([$data1, $data2]);
foreach($data as $key => $val) {
echo "$key: ", $val->text;
echo "$key: ", $val->more; // escaped.
}
only works for an array. so do not do this...
$data = Data::forge([ 'text' => 'tested', 'more' => '<i>done</i>', ]); foreach($data as $key => $val) { echo "$key: ", $val->get(null); // won't work! }
Use extractKey
method to create a subset of Data
object if the data is an array of another array (or object).
$data = Data::forge([
'obj'=>new ArrayObject['type' => 'object']
]);
$obj = $data->extractKey('obj');
echo $obj->type; // object
Hidden Tag
There is a simple method to show a hidden tag:
$data = Data::forge(['_method'=>'put']);
echo $data->hiddenTag('_method');
// <input type="hidden" name="_method" value="put" />
Use Inputs
class to convenient access array of data using HTML form element names.
<?php
$input = Inputs::forge([
'name' => '<my> name',
'gender' => 'male',
'types' => [ 'a', 'c' ],
'sns' => [
'twitter' => 'example@twitter.com',
'facebook' => 'example@facebook.com',
],
], $esc);
echo $input->get('name'); // escaped '<my> name'
echo $input->get('sns[twitter]'); // 'example@twitter.com'
vardump($input->get('types')); // ['a', 'c']
There is selected
and checked
methods to simplify checking some form elements.
// supply name of elements and its value.
echo $input->selected('gender', 'male'); // 'selected'
echo $input->selected('gender', 'female'); // empty
echo $input->checked('types', 'a'); // ' checked'
echo $input->checked('types', 'b'); // empty
The Errors
manages error messages associated with input values, which works just like Inputs
class except that this class has a method, p
which outputs the error message in a pre-defined format.
<?php
$errors = Errors::forge([
'name' => 'message for name',
'gender' => 'gender message',
'types' => [ 2 => 'message for type:B' ],
'sns' => [
'facebook' => 'love messaging facebook?',
],
], $esc);
// default format is: <p class="text-danger">%s</p>
echo $errors->p('name'); // message for name
echo $errors->p('gender'); // gender message
echo $errors->p('types[2]'); // message for type:B
echo $errors->p('sns[facebook]'); // love messaging facebook?
To change the format of the error message, just do:
$errors->format = '<div>(*_*) %s</div>';
This helper may not be that generic. Message class is for general message to be displayed in a main contents of a web page.
$message = Message::forge();
$message->add('hello');
$message->add('whoops', Message::ERROR);
echo $message;
// shows two divs for hello and whoops.
echo $message->onlyOne();
// <div class="alert alert-danger">Whoops</div>
The onlyOne
method shows only one first message that is most severe.
There are 3 formats for each severity of messages. Alter the format as necessary.
$message->formats = [
self::MESSAGE => '<div>:) %s</div>',
self::ALERT => '<div>:| %s</div>',
self::ERROR => '<div>:( %s</div>',
];
The Forms
helper class generates various HTML form tags.
$form = new Form();
// or using DataView
$view = new DataView();
$form = $view->forms;
Inject Inputs
object into Forms
object to use it when generating HTML tags.
$forms = $forms->withInputs($inputs);
The Forms
class does not escape its property nor values. It assumes that the values are given by the programmer. So, use Data
helper when displaying user's input.
$forms->text('safe', $data->get('safe'));
Creates various form input element. The most generic method is input
.
<?= $form->input('text', 'name', 'default value'); ?>
will generate
<input type="text" name="name" value="default value" />
Already various methods exists for html's input tags, such as: text, hidden, email, password, radio, and checkbox.
The extra html attribute can be added by method as follows.
<?= $form->date('radio')->class('form')->placeholder('date')->checked; ?>
There are many shortcut methods defined in Forms
object, such as text
, hidden
, datetime
, etc. All these shortcuts has the same signature:
$form->$method(string $name, string $value = null);
To start and close a form;
<?= $form->open()->action('to')->method('post')->uploader(); ?>
<?= $form->close(); ?>
if a non-standard method is given, it will generate a hidden tag with the method in the open()
method. The default name is _method
which can be altered by the second argument to method
, as;
<?= $form->open()->action('to')->method('put', 'method_token'); ?>
<form method="post" action="to" >
<input type="hidden" name="method_token" value="put" />
can output label as;
$form->label('label string', 'for-id');
currently, two buttons are supported.
$form->submit('button name');
$form->reset('cancel me');
text-area is supported.
$form->textArea('area-name', 'default value');
it's easy to create a select box.
$list = [
'1' => 'selecting',
'2' => 'made',
'3' => 'easy',
];
echo $form->select('name', $list, '2');
The first argument being name of the element, second is the index of options, and 3rd is the selected item.
Often you want to generate a list of checkbox or radio buttons. You can build it a bit like a select box.
$list = [
'1' => 'checkbox',
'2' => 'radio',
];
echo $form->checkList('checks', $list, '1');
will output the list of checkboxes inside ul > li
surrounded with label
;
<ul>
<li><label><input type="checkbox" name="checks" value="1" />checkbox</label></li>
<li><label><input type="checkbox" name="radio" value="1" />radio</label></li>
</ul>
You can construct the HTML using own code.
$list = $form->checkList('radio', $list, '2');
foreach($list as $key => $html) {
echo $list->getLabel($key), ': ', $html, '<br/>';
}
The Dates
helper class aims to help construct a complex form elements, such as date (which have year, month, and day form elements). For instance,
$form = new Dates();
echo $dates->setYear(
Lists::years(2014, 2016)
)->dateYMD('my-date', '2015-06-18');
will generate html for years between 2014 and 2016;
<select name="my-date_y">...</select>
<select name="my-date_m">...</select>
<select name="my-date_d">...</select>
When constructing a date with year list, it generates ranging from last year till next year as a default. You can change this by using setYear
method.
There are set*
methods for Year, Month, Day, Hour, Minute, and Second. Each method expects to get ListInterface
, Traversable
object, or an array. There are also List
objects for each type with specific method to displayed in various format.
echo $date->setYear(
Lists::years(2014, 2016)->useJpnGenGou()
)->setMonth(
Lists::months()->useFullText()
)->withClass('tested-class')
->dateYM('test')
->resetWidth('123px');
will generate some HTML like,
<select name="test_y" class="tested-class" style="width: 123px" >
<option value="2014">平成26年</option>
<option value="2015">平成27年</option>
<option value="2016">平成28年</option>
</select>/<select name="test_m" class="tested-class" style="width: 123px" >
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>