flsouto/htform

此包的最新版本(1.0.2)没有可用的许可信息。

构建HTML表单的库,无需痛苦

1.0.2 2021-01-27 13:49 UTC

This package is not auto-updated.

Last update: 2024-09-19 08:23:47 UTC


README

安装

要安装此包,请使用composer

composer require flsouto/htform

概览

忘记您之前看到的关于表单构建工具和库的一切。您将在这里看到的是一种全新的、直接的方法

  • 无需实例化和/或配置大量对象。
  • 无需定义和连接表单到模型。
  • 无需有xml或yml文件定义表单的行为。
  • 无需定义自己的表单和字段类。
  • 无需在表单渲染之前设置“渲染引擎”。
  • 无需从DIC(依赖注入容器)获取表单构建器。

用法

您只需做这些:创建一个表单对象,添加一些字段并输出它

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->textin('email');
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75c0f3" action="?">
 <div class="widget field_60116ef75c373" style="display:block">
   <input id="field_60116ef75c373" name="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75c3dd" name="submit" style="display:block" value="field_60116ef75c3dd">Submit
   </button>
 </div>
</form>

这很简单,对吧?

为字段添加标签

默认情况下,字段没有标签,但您可以通过调用字段实例上的label设置器来添加一个

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->textin('email')->label('E-mail: ');
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75d523" action="?">
 <div class="widget field_60116ef75d52e" style="display:block">
   <label style="display:block" for="field_60116ef75d52e">E-mail: </label>
   <input id="field_60116ef75d52e" name="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75d53b" name="submit" style="display:block" value="field_60116ef75d53b">Submit
   </button>
 </div>
</form>

使字段标签内联

默认情况下,字段的标签是块级元素。您可以通过传递inline => true标志来更改这一点

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->textin('email')->label(['text'=>'E-mail:','inline'=>true]);
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75d6ae" action="?">
 <div class="widget field_60116ef75d6b6" style="display:block">
   <label style="display:inline-block;margin-right:10px" for="field_60116ef75d6b6">E-mail:</label>
   <input id="field_60116ef75d6b6" name="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75d6c2" name="submit" style="display:block" value="field_60116ef75d6c2">Submit
   </button>
 </div>
</form>

定义占位符

您可以使用placeholder设置器,它实际上只是设置字段'placeholder'属性的快捷方式

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->textin('email')->placeholder('user@domain.com');
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75d81f" action="?">
 <div class="widget field_60116ef75d828" style="display:block">
   <input id="field_60116ef75d828" name="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75d834" name="submit" style="display:block" value="field_60116ef75d834">Submit
   </button>
 </div>
</form>

其他属性可以通过将关联数组传递给字段的attrs方法来设置。

添加不同类型的字段

表单就是将一些字段附加起来以获取用户输入。此库中提供了不同类型的字段

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();

$form->textin('email')->label('Email:')->size(50)->attrs(['class'=>'email']);
$form->textar('comment')->label('Comment:')->cols(50)->rows(10);
$form->checkb('newsletter','Receive Newsletter?')->fallback(1); // checked by default
$form->hidden('key','value');
$form->select('gender')->options(['M'=>'Male','F'=>'Female'])->caption('Choose Gender: ');
$form->upload('portfolio',__DIR__)->label('Choose a pdf file')->required('Please provide a portfolio')->accept(['application/pdf']);
$form->button('Submit');
$form->button('Cancel'); // more than one button can be added

echo $form;

输出

<form id="form_60116ef75d988" action="?" enctype="multipart/form-data" method="post">
 <div class="widget field_60116ef75d990" style="display:block">
   <label style="display:block" for="field_60116ef75d990">Email:</label>
   <input id="field_60116ef75d990" name="email" size="50" class="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75da1d" style="display:block">
   <label style="display:block" for="field_60116ef75da1d">Comment:</label>
   <textarea id="field_60116ef75da1d" name="comment" cols="50" rows="10"></textarea>
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75dada" style="display:block">
   <label style="display:block" for="field_60116ef75dada">
   <input id="field_60116ef75dada" name="newsletter" type="checkbox" value="1" checked="checked" /> Receive Newsletter?</label>
   <input type="hidden" name="newsletter_submit" value="1" />
 </div>
 <div>
   <input id="field_60116ef75dc38" name="key" type="hidden" value="value" />
   <div class="widget field_60116ef75dd23" style="display:block">
     <select id="field_60116ef75dd23" name="gender">
       <option value="0">Choose Gender:
       </option>
       <option value="M">Male
       </option>
       <option value="F">Female
       </option>
     </select>
     <div style="color:yellow;background:red" class="error">
     </div>
   </div>
   <div class="widget field_60116ef75de16" style="display:block">
     <input id="field_60116ef75de16" name="portfolio_submit" type="file" style="display:none" />
     <label style="display:block;cursor:pointer" for="field_60116ef75de16">Choose a pdf file</label>
     <input type="hidden" name="portfolio" value="" />
     <div style="color:yellow;background:red" class="error">
     </div>
   </div>
   <button id="field_60116ef75de26" name="submit" style="display:block" value="field_60116ef75de26">Submit
   </button>
   <button id="field_60116ef75de31" name="Cancel" style="display:block" value="field_60116ef75de31">Cancel
   </button>
 </div>
</form>

每种字段类型都在其自己的类中定义。这些类也有自己的存储库。有关字段API的更多信息,请查看以下存储库

  • HtField - 所有字段的抽象基类

  • HtWidget - 所有小部件类型的基类(扩展HtField)

    • HtTextin - 单行文本输入小部件
    • HtTextar - 多行文本输入小部件
    • HtCheckb - 布尔输入(复选框)小部件
    • HtSelect - 从列表中选择选项的小部件
    • HtUpload - 文件上传小部件

注意:添加“上传”字段时,表单将自动具有enctype=multipart/form-data和method=POST

一次性使所有字段内联

有时您需要构建“快速搜索”类型的表单,其中所有字段都在一行中渲染。为此,您可以在表单实例上使用inline方法

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->inline(true);
$form->textin('fst_name')->label('First Name');
$form->textin('lst_name')->label('Last Name');
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75e211" action="?">
 <div class="widget field_60116ef75e21b" style="display:inline-block;vertical-align:text-top">
   <label style="display:block" for="field_60116ef75e21b">First Name</label>
   <input id="field_60116ef75e21b" name="fst_name" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75e225" style="display:inline-block;vertical-align:text-top">
   <label style="display:block" for="field_60116ef75e225">Last Name</label>
   <input id="field_60116ef75e225" name="lst_name" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75e22d" name="submit" style="display:inline-block;vertical-align:text-top" value="field_60116ef75e22d">Submit
   </button>
 </div>
</form>

一次性将所有字段设置为只读

有时您可能想要重用相同的表单布局/结构,但在只读模式下。在这种情况下,您可以通过调用表单对象的 readonly 方法来禁用所有字段的编辑。

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->readonly(true);
$form->textin('fst_name')->label('First Name');
$form->textin('lst_name')->label('Last Name');
$form->button('Submit');

echo $form;

输出

<form id="form_60116ef75e413" action="?">
 <div class="widget field_60116ef75e41c" style="display:block">
   <label style="display:block" for="field_60116ef75e41c">First Name</label>
   <input id="field_60116ef75e41c" name="fst_name" value="" readonly="readonly" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75e425" style="display:block">
   <label style="display:block" for="field_60116ef75e425">Last Name</label>
   <input id="field_60116ef75e425" name="lst_name" value="" readonly="readonly" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75e42d" name="submit" style="display:block" value="field_60116ef75e42d">Submit
   </button>
 </div>
</form>

更改表单属性

默认情况下,表单以以下属性渲染

  • method: GET
  • action: ?
  • id: 随机id

但是,可以通过调用表单实例上的相应设置器轻松更改这些属性。

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->method('POST')
    ->action('some_script.php')
    ->attrs(['class'=>'some_class','id'=>'my_form']);

$form->textin('email');
$form->button('Submit');

echo $form;

输出

<form id="my_form" action="some_script.php" method="post" class="some_class">
 <div class="widget field_60116ef75e604" style="display:block">
   <input id="field_60116ef75e604" name="email" value="" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75e60d" name="submit" style="display:block" value="field_60116ef75e60d">Submit
   </button>
 </div>
</form>

用数据填充表单

为了用数据填充表单,您必须调用表单对象上的 context 方法,并传递一个关联数组给它。关联数组的键必须与您添加到表单中的字段名称匹配。

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$form = new HtForm();
$form->textin('name')->label('Name');
$form->textin('email')->label('Email');
$form->select('job')->caption("Job:")->options([1=>'Secretary',2=>'Manager',3=>'Programmer']);
$form->button('Submit');

$form->context([
    'name' => 'Mary',
    'email' => 'dontmaryme@doman.com',
    'job' => 1
]);

echo $form;

输出

<form id="form_60116ef75e78b" action="?">
 <div class="widget field_60116ef75e793" style="display:block">
   <label style="display:block" for="field_60116ef75e793">Name</label>
   <input id="field_60116ef75e793" name="name" value="Mary" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75e79d" style="display:block">
   <label style="display:block" for="field_60116ef75e79d">Email</label>
   <input id="field_60116ef75e79d" name="email" value="dontmaryme@doman.com" />
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div class="widget field_60116ef75e7a3" style="display:block">
   <select id="field_60116ef75e7a3" name="job">
     <option value="0">Job:
     </option>
     <option value="1" selected="selected">Secretary
     </option>
     <option value="2">Manager
     </option>
     <option value="3">Programmer
     </option>
   </select>
   <div style="color:yellow;background:red" class="error">
   </div>
 </div>
 <div>
   <button id="field_60116ef75e7ac" name="submit" style="display:block" value="field_60116ef75e7ac">Submit
   </button>
 </div>
</form>

处理表单提交

处理表单就是用传入的数据填充它并调用 process 方法。检查是否存在表示表单已发送的标志也是良好的实践。请查看以下示例

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

// Simulate form submition
$_REQUEST = [
    'name' => 'Mary',
    'email' => 'dontmaryme@doman.com',
    '_submit' => 1
];

$form = new HtForm();
$form->textin('name')->label('Name');
$form->textin('email')->label('Email');
$form->button('_submit','Submit');

// Populate form with data sent from request
$form->context($_REQUEST);

// Check if there is a flag
if($form->value('_submit')){

    // Extract all fields, except those prefixed with underscore
    $result = $form->process();

    print_r($result);

}

输出

FlSouto\HtFormResult Object
(
    [data] => Array
        (
            [name] => Mary
            [email] => dontmaryme@doman.com
        )

    [errors] => Array
        (
        )

)

验证表单提交

您可以在表单提交时添加验证规则。验证规则按字段添加,并在出现错误时提供错误消息。这些错误在处理方法返回的结果对象中可用。请看以下示例

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

// Simulate INVALID form data
$_REQUEST = [
    'name' => '',
    'email' => 'dontmaryme__doman.com',
    '_submit' => 1
];

$form = new HtForm();
$form->textin('name')->label('Name')->required();
$form->textin('email')->label('Email')
    ->required()
    ->filters()->ifnot('@', "Invalid email address");

$form->button('_submit','Submit');

$form->context($_REQUEST);

if($form->value('_submit')){

    // Extract data and check for errors
    $result = $form->process();
    print_r($result);
}

输出

FlSouto\HtFormResult Object
(
    [data] => Array
        (
            [name] => 
            [email] => dontmaryme__doman.com
        )

    [errors] => Array
        (
            [name] => This field is required
            [email] => Invalid email address
        )

)

表单字段的命名空间

您表单背后的数据结构不必是扁平的。您可以将字段分组到逻辑部分中,以下是一个示例

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

// The data is sent by the form in the following structure:
$_REQUEST = [
    'user' => [ // these fields are in the "user" section
        'name' => 'Mary',
        'email' => '' // this should result in an error
    ],
    'person' => [ // these fields are in the "person" section
        'number' => 666,
        'city' => 'Nowhereland'
    ],
    '_submit' => 1 // this field is in the "root" section
];

$form = new HtForm();
// Namespacing is achieved using square brackets:
$form->textin('user[name]')->label('Username');
$form->textin('user[email]')->label('E-mail')->required("Email is required!");
$form->textin('person[number]')->label('Number');
$form->textin('person[city]')->label('City');
$form->button('_submit','Submit');

$form->context($_REQUEST);

if($form->value('_submit')){

    $result = $form->process();

    print_r($result);

}

输出

FlSouto\HtFormResult Object
(
    [data] => Array
        (
            [user[name]] => Mary
            [user[email]] => 
            [person[number]] => 666
            [person[city]] => Nowhereland
        )

    [errors] => Array
        (
            [user[email]] => Email is required!
        )

)

展开表单数据

如您在最后一个示例中看到的,尽管我们可以处理通过请求发送的复杂数据结构,但数据是按扁平格式提取的。幸运的是,结果对象提供了一个名为 unfold 的方法,可以用来将数据重构为多维数组。

<?php
require 'vendor/autoload.php';
use FlSouto\HtForm;

$_REQUEST = [
    'user' => [
        'name' => 'Mary',
        'email' => ''
    ],
    '_submit' => 1
];

$form = new HtForm();
$form->textin('user[name]')->label('Username');
$form->textin('user[email]')->label('E-mail')->required("Email is required!");
$form->button('_submit','Submit');

$form->context($_REQUEST);

if($form->value('_submit')){
    $result = $form->process()->unfold();
    print_r($result);
}

输出

FlSouto\HtFormResult Object
(
    [data] => Array
        (
            [user] => Array
                (
                    [name] => Mary
                    [email] => 
                )

        )

    [errors] => Array
        (
            [user] => Array
                (
                    [email] => Email is required!
                )

        )

)