asgard / form
Requires
- php: >=5.5.9
- asgard/common: ~0.3.0
- asgard/container: ~0.3.0
- asgard/http: ~0.3.0
- asgard/validation: ~0.3.0
- nesbot/carbon: ^1.0
- symfony/translation: ^3.0
This package is not auto-updated.
Last update: 2024-09-14 15:58:04 UTC
README
#表单
表单库使得构建表单、渲染它们、在提交后记住输入以及自动处理、验证并防止CSRF攻击变得非常容易。
##安装 如果你正在开发Asgard项目,你不需要安装这个库,因为它已经是标准库的一部分。
composer require asgard/form 0.*
使用表单服务的优点是它会为表单提供所有必要的依赖
$container->make('form', [
'name', #name (optional)
[ #params (optional)
'action' => 'form.php',
'enctype' => 'multipart/form-data',
'attrs' => [
'class' => 'formClass'
]
],
\Asgard\Http\Request::CreateFromGlobals(), #request (optional, Asgard will feed the form with the current request)
[ #fields (optional)
'name' => new TextField(),
'content' => new TextField(),
]
]);
在控制器(或任何使用视图容器的类)中,可以通过 $this->getContainer() 获取 $container。您也可以通过 \Asgard\Container\Container::singleton() 访问它。
在这里,您必须自己提供依赖(请参阅下一节)
$form = new \Asgard\Form\Form(
'name', #name (optional)
[ #params (optional)
'action' => 'form.php',
'enctype' => 'multipart/form-data',
'attrs' => [
'class' => 'formClass'
]
],
\Asgard\Http\Request::CreateFromGlobals(), #request (optional)
[ #fields (optional)
'name' => new TextField(),
'content' => new TextField(),
]
);
如果没有提供enctype,当表单包含文件时,它将自动使用 "multipart/form-data"
###请求
$form->setRequest(\Asgard\Http\Request::createFromGlobals());
###翻译器
$form->setTranslator(new \Symfony\Component\Translation\Translator('en'));
访问或修改表单参数
$param = $form->getOption('action');
$form->setOption('action', $action);
一些常见的参数包括
- action(例如,/url/to/page)
- enctype(例如,multipart/form-data)
默认情况下,表单从POST请求获取输入,但如果您想创建一个只使用GET输入的表单
$form->setMethod('get');
字段是表单的单个输入。所有字段都扩展了 \Asgard\Form\Field 类。 以下是当前所有可用字段的列表。
###验证
要为字段添加特定的验证规则,请使用 'validation' 选项
$form['field'] = new \Asgard\Form\Field\TextField(['validation'=>[
'minlength' => 5,
'maxlength' => 5,
]]);
检查输入是否有效
$form->isValid(); #returns true|false
获取错误
$errors = $form->errors();
获取字段或组错误
$errors = $form['title']->errors();
获取仅通用错误或不属于特定字段的错误
$errors = $form->getGeneralErrors();
验证组
$form['field'] = new \Asgard\Form\Field\TextField(['validation'=>[
'minlength' => [
5,
'groups' => ['registration']
]
]]);
使用少于5个字符的文本
$form->isValid(['registration']); #false
$form->isValid(); #true
验证在验证文档中有进一步解释。
###字段默认值
要为字段设置默认值,请使用 'default' 选项
$form['field'] = new \Asgard\Form\Field\TextField(['default'=>'placeholder']);
###渲染字段
字段使用小部件进行渲染。每种类型的字段都使用默认小部件,但有时您可以使用不同的一个。有关渲染字段的多种方式,请参阅以下字段列表。
要使用默认小部件渲染字段,请使用以下方法
echo $form['field']->def();
###小部件
小部件通过短名称(如 "text"、"password"、"select" 等)标识,并在渲染字段时调用,例如
echo $form['field']->text();
"text" 是我们想要用于渲染字段的 Widget 名称。
默认情况下,表单将在 \Asgard\Form\Widget 中查找对应的控件。但是,您也可以管理可用的控件。
###字段标签
显示字段的标签
echo $form['field']->label();
或整个标签标签
echo $form['field']->labelTag();
布尔值
$form['field'] = new \Asgard\Form\Field\BooleanField;
显示复选框。
国家
$form['field'] = new \Asgard\Form\Field\BooleanField;
显示包含所有国家的选择字段。
csrf
$form['field'] = new \Asgard\Form\Field\CSRFField;
向表单添加隐藏字段以防止CSRF攻击。
日期
$form['field'] = new \Asgard\Form\Field\DateField;
渲染三个选择字段(日/月/年)
$form['field']->def();
#or
$form['field']->date();
渲染文本字段
$form['field']->text();
日期时间
$form['field'] = new \Asgard\Form\Field\DatetimeField;
渲染六个选择字段(秒/分/时/日/月/年)
$form['field']->def();
#or
$form['field']->datetime();
渲染文本字段
$form['field']->text();
时间
$form['field'] = new \Asgard\Form\Field\TimeField;
渲染三个选择字段(秒/分/时)
$form['field']->def();
#or
$form['field']->time();
渲染文本字段
$form['field']->text();
日
$form['field'] = new \Asgard\Form\Field\DayField;
添加一个单选字段,包含从1到31天的选项。
文件
$form['field'] = new \Asgard\Form\Field\FileField;
添加一个文件字段。
隐藏
$form['field'] = new \Asgard\Form\Field\HiddenField;
向表单添加一个隐藏字段。
月
$form['field'] = new \Asgard\Form\Field\MonthField;
添加一个单选字段,包含从1到12个月的选项。
多选
$form['field'] = new \Asgard\Form\Field\SelectField(['choices'=>['bob', 'joe', 'david']);
渲染多选
$form['field']->def();
#or
$form['field']->multipleselect();
渲染复选框
$form['field']->checkboxes();
#or
foreach($form['field']->getCheckboxes() as $checkbox)
echo $checkbox->label().': '.$checkbox;
选择
$form['field'] = new \Asgard\Form\Field\SelectField(['choices'=>['bob', 'joe', 'david']);
添加一个单选字段。
文本
$form['field'] = new \Asgard\Form\Field\TextField;
年
$form['field'] = new \Asgard\Form\Field\YearField;
添加一个单选字段,包含过去50年的选项。
##组和表单 组是一组字段。例如,您可能有一个用于运货地址字段的组,另一个用于账单地址字段的组。您还可以有包含其他组的组。表单本身是一个包含组和字段的组。
要了解组或表单有多少字段或子组
$count = $group->size();
表单和组就像数组一样构建。要添加字段
$form['title'] = new \Asgard\Form\Field\TextField;
要获取表单提交后的值
$value = $form['title']->value();
您可以将整个组添加到表单中
$form['address'] = [
'number' => new Field\TextField,
'street' => new Field\TextField,
'city' => new Field\TextField,
'zipcode' => new Field\TextField
];
在表单中,数组将转换为 \Asgard\Form\Group 对象。您可以通过像表单一样访问组字段
$value = $form['address']['street']->value();
因为表单也是一个组,所以您也可以嵌入表单
$personForm = new \Asgard\Form\Form;
$personForm['firstname'] = new Field\TextField;
$personForm['lastname'] = new Field\TextField;
$form['person'] = $personForm;
并且像这样访问字段
$form['person']['firstname']->value();
您还可以遍历组或表单字段
foreach($group as $field) {
// do something with the field
}
###用法 动态组在您在一个组中有不确定数量的字段时非常有用。例如,一个用户可以添加任意多的名字,每个名字对应一个字段的表单。
要添加动态组,使用
$callback = function($data) {
return new \Asgard\Http\Field\TextField;
};
$form['names'] = \Asgard\Form\DynamicGroup($callback);
这将自动为组 "names" 中的每个输入创建一个 TextField。如果用户发送5个名字,表单将适应并创建5个 TextField 来包含这5个名字。
###预填充 您甚至可以预填充动态组
$form['names'][] = new \Asgard\Http\Field\TextField(['default'=>'name1']);
$form['names'][] = new \Asgard\Http\Field\TextField(['default'=>'name2']);
###渲染
echo $form->open();
foreach($form['names'] as $field)
echo $field->def();
echo $form->submit();
echo $form->close();
您可以为动态组的字段设置匿名函数以进行渲染
$form['names']->setDefaultRender(function($field) {
return $field->label().': '.$field->def();
});
然后在视图中使用以下代码
echo $form->open();
foreach($form['names'] as $field)
echo $form['names']->def($field);
echo $form->submit();
echo $form->close();
###使用jQuery在前端处理多个字段
要允许用户自行添加字段,使用以下代码片段
<script>
function add() {
var newfield = $('<?php echo $form['names']->renderTemplate("'+$('.name').length+'") ?>');
$('#slides').append(newfield);
}
</script>
echo $form->open();
echo '<div id="names">';
foreach($form['names'] as $field)
echo '<div>'.$field->label().': '.$field-def(['attrs'=>['class'=>'name']]).'</div>';
echo '</div>';
<input type="button" name="add" value="Add a name" onclick="add()">
echo $form->submit();
echo $form->close();
方法 renderTemplate 在用户点击 "添加" 按钮时生成创建新HTML字段的javascript模板。
检查表单是否已发送
$form->sent(); #returns true|false
保存表单
$form->save($validationGroups=[]);
验证组在上面的 "验证组" 中解释。
如果发生错误,将引发异常
try {
$form->save();
} catch(\Asgard\Form\FormException $e) {
//...
}
如果输入有效,它将执行表单的 doSave() 方法,默认情况下不执行任何操作。它还会尝试保存每个嵌套表单。
但是,您可以创建扩展表单类并重写 "doSave" 方法或使用回调的自定义类
$form->setPreSaveCallback(function($form) {
// do something before validation
});
$form->setSaveCallback(function($form) {
// do something to save the form
});
$form->save()
要启用表单的CSRF保护
$form->csrf();
禁用它
$form->csrf(false);
如果没有 CSRF 令牌,表单将无效。错误信息可以通过 $form->getGeneralErrors() 或 $form['_csrf_token']->error() 获取。
从已发送的表单中获取数据
$data = $form->data();
重置数据
$form->reset();
手动设置数据
$form->setData(['title' => 'abc']);
echo $form->open($params=[]); #prints the opening tag. Params will override the parameters passed to the form instancefd
//render fields e.g. $form['title']->def();
echo form->submit('Send'); #prints a simple submit button with text "Send"
echo $form->close(); #prints the closing tag and an hidden input for csrf if enabled
###实例
在 Asgard 框架中,你可以使用服务
$wm = $container['widgetManager'];
否则,你也可以通过以下方式访问表单小部件管理器
$wm = $form->getWidgetManager();
###注册小部件
$wm->setWidget('text', 'MyClasses\Widget\TextWidget');
###注册命名空间
$wm->addNamespace('MyClasses\Widgets');
当使用未知的小部件时,小部件管理器将尝试在所有已注册的命名空间中查找小部件。如果存在类 MyClasses\Widget\TextWidget,它将被用来渲染字段。
###注册小部件工厂
这对于依赖注入非常有用。
$wf = new WidgetFactory($dep);
$wm->setWidgetFactory('text', $wf);
小部件工厂必须实现 \Asgard\Form\WidgetFactoryInterface,该接口有一个方法
public function create($name, $value, $options, $form);
此方法必须构建并返回一个 Widget 对象。
###示例
$form = $container->make('form');
#or
$form = new \Asgard\Form\Form;
$form->getWidgetManager()->setWidget('text', 'MyClasses\Widget\TextWidget');
$form['title'] = new \Asgard\Field\TextField;
echo $form['title']->text();
###用户注册
构建表单
$form = $container->make('form', ['user']);
#or
$form = new \Asgard\Form\Form('user');
$form['username'] = new \Asgard\Form\Field\TextField(['validation'=>'required']);
$form['password'] = new \Asgard\Form\Field\TextField(['validation'=>'required', 'widget' => 'password']);
if($form->sent()) {
if($form->isValid()) {
$username = $form['username']->value();
$password = $form['password']->value();
// save in database..
echo 'Good :)';
}
else {
echo 'Bad :(';
foreach($form->errors() as $error)
echo "\n".$error;
}
}
显示表单
echo $form->open();
echo $form['username']->def();
echo $form['password']->password();
echo $form->close();
//todo widgetfactory
###贡献
请将所有问题和拉取请求提交到 asgardphp/asgard 仓库。
许可证
Asgard 框架是开源软件,许可协议为 MIT 许可证