Zend Framework 3 - 使用 javascript 添加和删除新的输入元素部分
Zend Framework 3 - Add and Remove new input element section using javascript
我想在单击锚标记或按钮时以 zend 形式添加多个学校位置。
这样 zend 表单验证就可以应用于所有动态创建的字段
请参阅附件 image.I 想要克隆 div 并在图像中使用红色边框
下面是SchoolControllerClass
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use School\Service\SchoolManager;
use Doctrine\ORM\EntityManager;
use Zend\View\Model\ViewModel;
use Application\Form\AddSchoolForm;
use School\Entity\School;
use School\Entity\SchoolLocation;
class SchoolController extends AbstractActionController {
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* School manager.
* @var School\Service\SchoolManager
*/
private $schoolManager;
public function __construct($entityManager, $schoolManager) {
$this->entityManager = $entityManager;
$this->schoolManager = $schoolManager;
}
public function addAction() {
$form = new AddSchoolForm();
// Check if user has submitted the form
if ($this->getRequest()->isPost()) {
// Fill in the form with POST data
$data = $this->params()->fromPost();
$form->setData($data);
// Validate form
if ($form->isValid()) {
$reqData = array(
'name' => $data['name'],
'description' => $data['description'],
'active' => 1,
'school_location' => (object) array(
(object) array(
"apartment_number" => $data['apartment_number'],
"street_name" => $data['street_name'],
"city" => $data['city'],
"state" => $data['state'],
"pin" => $data['pin'],
"active" => 1)
)
);
$this->schoolManager->addSchool((object) $reqData);
} else {
print_r($form->getMessages());
die("not valid data");
$isLoginError = true;
}
}
return new ViewModel([
'form' => $form
]);
}
}
下面是AddSchoolForm Class:
<?php
namespace Application\Form;
use Zend\Form\Element;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
/**
* This form is used to collect user's login, password and 'Remember Me' flag.
*/
class AddSchoolForm extends Form {
/**
* Constructor.
*/
public function __construct() {
// Define form name
parent::__construct('addschool-form');
// Set POST method for this form
$this->setAttribute('method', 'post');
$this->addElements();
$this->addInputFilter();
}
/**
* This method adds elements to form (input fields and submit button).
*/
protected function addElements() {
$this->add([
'attributes' => array(
'name' => 'name',
'type' => 'text',
'id' => 'name',
'class' => 'form-control',
'required' => 'required',
),
'options' => [
'label' => 'School Name',
],
]);
// Add "desc" field
$this->add([
'attributes' => array(
'name' => 'description',
'type' => 'text',
'id' => 'description',
'class' => 'form-control',
'required' => 'required',
),
'options' => [
'label' => 'Description',
],
]);
$this->add([
'type' => 'hidden',
'name' => 'active',
'value' => 1
]);
// Add "school location" field
$this->add([
'attributes' => array(
'name' => 'apartment_number',
'type' => 'text',
'id' => 'apartment_number',
'class' => 'form-control'
),
'options' => [
'label' => 'Apartment Number',
],
]);
$this->add([
'attributes' => array(
'name' => 'street_name',
'type' => 'text',
'id' => 'street_name',
'class' => 'form-control'
),
'options' => [
'label' => 'Street Name',
],
]);
$this->add([
'attributes' => array(
'name' => 'city',
'type' => 'text',
'id' => 'city',
'class' => 'form-control'
),
'options' => [
'label' => 'City',
],
]);
$this->add([
'attributes' => array(
'name' => 'state',
'type' => 'text',
'id' => 'state',
'class' => 'form-control'
),
'options' => [
'label' => 'State',
],
]);
$this->add([
'attributes' => array(
'name' => 'pin',
'type' => 'text',
'id' => 'pin',
'class' => 'form-control'
),
'options' => [
'label' => 'PIN',
],
]);
// Add the Submit button
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Sign in',
'id' => 'submit',
],
]);
}
/**
* This method creates input filter (used for form filtering/validation).
*/
private function addInputFilter() {
// Create main input filter
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
// Add input for "email" field
$inputFilter->add([
'name' => 'name',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 5,
'max' => 20
],
],
],
]);
$inputFilter->add([
'name' => 'description',
'required' => true,
'filters' => [
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 5,
'max' => 64
],
],
],
]);
}
}
下面是查看文件add.phtml
<script type="text/javascript">
function addSchoolLocation(){
$( ".schoolLocation" ).clone().appendTo( ".schoolLocation" );
}
</script>
<!-- Content Header (Page header) -->
<section class="content-header">
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Add School</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<!-- left column -->
<div class="col-md-12">
<!-- general form elements -->
<div class="box box-primary form-custome">
<div class="box-header with-border">
<h3 class="box-title">Add School <ul class="add-icon-new">
<li><a href="#" class="i-down"><i class="fa fa-angle-down"></i></a></li>
<li><a href="#" class="i-refresh"><i class="fa fa-refresh" aria-hidden="true"></i>
</a></li>
<li><a href="#" class="i-close"><i class="fa fa-times" aria-hidden="true"></i></a></li>
</ul>
</h3>
</div>
<h5 class="form-heading">School Information</h5>
<form role="form" method="post">
<div class="box-body">
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('name')); ?>
<?= $this->formElement($form->get('name')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('description')); ?>
<?= $this->formElement($form->get('description')); ?>
</div>
<?= $this->formElement($form->get('active')); ?>
<h5 class="form-heading">School Location</h5>
<div class="schoolLocation">
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('apartment_number')); ?>
<?= $this->formElement($form->get('apartment_number')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('street_name')); ?>
<?= $this->formElement($form->get('street_name')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('city')); ?>
<?= $this->formElement($form->get('city')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('state')); ?>
<?= $this->formElement($form->get('state')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('pin')); ?>
<?= $this->formElement($form->get('pin')); ?>
</div>
</div>
<div>
<a href="javascript:void(0);" onclick="addSchoolLocation();">Add School Location</a>
<a href="javascript:void(0);" id="addElement">Add School Location</a>
</div>
<div class=" form-group col-sm-12">
<button class="save">Save</button>
<button class="reset">Reset</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- /.row -->
</section>
<!-- /.content -->
我想用 class schoollocation
克隆 div
注意*: 我尝试了以下解决方案,但对我没有任何效果,因为这些不是 Zend Framework-3 的解决方案
Zend Framework - Add new input element using javascript
https://docs.zendframework.com/zend-form/collections/#form-collections
您要查找的是 Collections (which you linked) and Fieldsets 的用法。
您使用 Fieldset 来表示实体。在此示例中,Fieldset 是 Location
,附加到 School
.
此外,School
作为与 Location
的 One To Many
关系。
因此,您将有一个 SchoolFieldset
class,它需要一个 Collection
Element。
下面是一个非常简化的设置示例。
后端
位置字段集
class LocationFieldset
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
// ... Add whatever for Location
}
}
学校田野集
class SchoolFieldset
{
/**
* @var LocationFieldset
*/
protected $locationFieldset;
public function __construct(LocationFieldset $locationFieldset)
{
$this->locationFieldset($locationFieldset);
}
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
$this->add([
'type' => Collection::class,
'required' => true,
'name' => 'locations',
'options' => [
'label' => _('Locations'),
'count' => 1, // Initial amount of Fieldsets on-load
'allow_add' => true, // Allows creation of 0/multiple
'allow_remove' => true, // Allows removal
'should_create_template' => true, // Creates template in the HTML in a <span data-template="the whole html here"></span> -> JavaScript this bit for duplication/removal
'target_element' => $this->locationFieldset, // A pre-loaded Fieldset must be passed here, not just the FQCN as you would for including a Fieldset not in a Collection
],
]);
// ... Add whatever
}
}
学校形式
class SchoolForm extends CustomAbstractForm
{
public function init()
{
$this->add([
'name' => 'school',
'type' => SchoolFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
//Call parent initializer. (Default for me it adds a submit button)
parent::init();
}
}
Front-end
在表格的视图中,我加载了一点JavaScript。它基于 Zend Framework 文档中提供的演示数据。
请注意,这些文档不考虑删除(因此,如果您有 HTML objects 且 ID 为 0-1-2,并且您删除了 1,它将被计算在内,来到 2 并创建另一个 2,给你 0-2-2,从而覆盖你已经拥有的第二个。
我目前在一个项目中的JavaScript是这样的(抱歉,不能给你所有的,但这应该让你开始):
按钮
var $addButton = $('<button type="button" data-action="add-fieldset" class="btn btn-primary">Add another</button>');
var $removeButton = $('<button type="button" data-action="remove-fieldset" class="btn btn-danger">Remove</button>');
用法
$('body').on('click', 'button[type="button"][data-action="add-fieldset"]', function () {
addCollectionFieldset(this);
});
$('body').on('click', 'button[type="button"][data-action="remove-fieldset"]', function () {
removeCollectionFieldset(this);
});
function addCollectionFieldset(element) {
var $element = $(element);
var $fieldsetDataSpan = $element.siblings('span[data-name="fieldset-data"]');
var fieldsetCount = $fieldsetDataSpan.data('fieldset-count');
var escapedTemplate = $element.siblings('span[data-template]').data('template');
var $replaced = $(escapedTemplate.replace(/__index__/g, fieldsetCount));
$replaced.append($removeButton.clone());
$($replaced).insertAfter($element.siblings('fieldset:last'));
$('<hr>').insertBefore($element.siblings('fieldset:last'));
$fieldsetDataSpan.data('fieldset-count', fieldsetCount + 1); // Up the count by one fieldset
}
function removeCollectionFieldset(element) {
$(element).parent().remove();
}
注意: "Remove" 按钮位于 Collection 中的每个字段集中。 "Add another" 按钮位于 Collection 下方。
如何解决这个问题,由您决定。
查看
<?= $this->form($form) ?>
<?php $this->inlineScript()->prependFile($this->basePath('js/form.js')) ?>
控制器动作
public function addAction()
{
/** @var SchoolForm $form */
$form = $this->getSchoolForm();
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
/** @var School $school */
$school = $form->getObject();
$this->getObjectManager()->persist($school);
try {
$this->getObjectManager()->flush();
} catch (Exception $e) {
throw new Exception(
'Could not save. Error was thrown, details: ' . $e->getMessage(),
$e->getCode(),
$e->getPrevious()
);
}
return $this->redirectToRoute('schools/view', ['id' => $school->getId()]);
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
控制器工厂
class AddControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
/** @var ObjectManager $objectManager */
$objectManager = $container->get(EntityManager::class);
/** @var FormElementManagerV3Polyfill $formElementManager */
$formElementManager = $container->get('FormElementManager');
/** @var SchoolForm $schoolForm */
$schoolForm = $formElementManager->get(SchoolForm::class);
return new AddController($objectManager, $schoolForm);
}
}
FormFactory
class SchoolFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$objectManager = $container->get(EntityManager::class);
$translator = $container->get('MvcTranslator');
$inputFilterPluginManager = $container->get('InputFilterManager');
$inputFilter = $inputFilterPluginManager->get(SchoolFormInputFilter::class); // Did not show this one
/** @var SchoolForm $form */
$form = new SchoolForm();
$form->setObjectManager($objectManager);
$form->setTranslator($translator);
$form->setInputFilter($inputFilter);
return $form;
}
}
FormFactory
class SchoolFieldsetFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$objectManager = $container->get(EntityManager::class);
$translator = $container->get('MvcTranslator');
$fieldset = new SchoolFieldset();
$fieldsetObject = new School();
/** @var SchoolFieldset $fieldset */
$fieldset = new $fieldset($objectManager(), 'school');
$fieldset->setHydrator(
new DoctrineObject($objectManager())
);
$fieldset->setObject($fieldsetObject);
$fieldset->setTranslator($translator);
return $fieldset;
}
}
如果您有空闲时间,我建议您查看我创建的存储库中的更多示例,以帮助在 ZF 和 ZF with Doctrine 中快速创建表单。带有示例的自述文件 is here
我想在单击锚标记或按钮时以 zend 形式添加多个学校位置。
这样 zend 表单验证就可以应用于所有动态创建的字段
请参阅附件 image.I 想要克隆 div 并在图像中使用红色边框
下面是SchoolControllerClass
<?php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use School\Service\SchoolManager;
use Doctrine\ORM\EntityManager;
use Zend\View\Model\ViewModel;
use Application\Form\AddSchoolForm;
use School\Entity\School;
use School\Entity\SchoolLocation;
class SchoolController extends AbstractActionController {
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* School manager.
* @var School\Service\SchoolManager
*/
private $schoolManager;
public function __construct($entityManager, $schoolManager) {
$this->entityManager = $entityManager;
$this->schoolManager = $schoolManager;
}
public function addAction() {
$form = new AddSchoolForm();
// Check if user has submitted the form
if ($this->getRequest()->isPost()) {
// Fill in the form with POST data
$data = $this->params()->fromPost();
$form->setData($data);
// Validate form
if ($form->isValid()) {
$reqData = array(
'name' => $data['name'],
'description' => $data['description'],
'active' => 1,
'school_location' => (object) array(
(object) array(
"apartment_number" => $data['apartment_number'],
"street_name" => $data['street_name'],
"city" => $data['city'],
"state" => $data['state'],
"pin" => $data['pin'],
"active" => 1)
)
);
$this->schoolManager->addSchool((object) $reqData);
} else {
print_r($form->getMessages());
die("not valid data");
$isLoginError = true;
}
}
return new ViewModel([
'form' => $form
]);
}
}
下面是AddSchoolForm Class:
<?php
namespace Application\Form;
use Zend\Form\Element;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
/**
* This form is used to collect user's login, password and 'Remember Me' flag.
*/
class AddSchoolForm extends Form {
/**
* Constructor.
*/
public function __construct() {
// Define form name
parent::__construct('addschool-form');
// Set POST method for this form
$this->setAttribute('method', 'post');
$this->addElements();
$this->addInputFilter();
}
/**
* This method adds elements to form (input fields and submit button).
*/
protected function addElements() {
$this->add([
'attributes' => array(
'name' => 'name',
'type' => 'text',
'id' => 'name',
'class' => 'form-control',
'required' => 'required',
),
'options' => [
'label' => 'School Name',
],
]);
// Add "desc" field
$this->add([
'attributes' => array(
'name' => 'description',
'type' => 'text',
'id' => 'description',
'class' => 'form-control',
'required' => 'required',
),
'options' => [
'label' => 'Description',
],
]);
$this->add([
'type' => 'hidden',
'name' => 'active',
'value' => 1
]);
// Add "school location" field
$this->add([
'attributes' => array(
'name' => 'apartment_number',
'type' => 'text',
'id' => 'apartment_number',
'class' => 'form-control'
),
'options' => [
'label' => 'Apartment Number',
],
]);
$this->add([
'attributes' => array(
'name' => 'street_name',
'type' => 'text',
'id' => 'street_name',
'class' => 'form-control'
),
'options' => [
'label' => 'Street Name',
],
]);
$this->add([
'attributes' => array(
'name' => 'city',
'type' => 'text',
'id' => 'city',
'class' => 'form-control'
),
'options' => [
'label' => 'City',
],
]);
$this->add([
'attributes' => array(
'name' => 'state',
'type' => 'text',
'id' => 'state',
'class' => 'form-control'
),
'options' => [
'label' => 'State',
],
]);
$this->add([
'attributes' => array(
'name' => 'pin',
'type' => 'text',
'id' => 'pin',
'class' => 'form-control'
),
'options' => [
'label' => 'PIN',
],
]);
// Add the Submit button
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Sign in',
'id' => 'submit',
],
]);
}
/**
* This method creates input filter (used for form filtering/validation).
*/
private function addInputFilter() {
// Create main input filter
$inputFilter = new InputFilter();
$this->setInputFilter($inputFilter);
// Add input for "email" field
$inputFilter->add([
'name' => 'name',
'required' => true,
'filters' => [
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 5,
'max' => 20
],
],
],
]);
$inputFilter->add([
'name' => 'description',
'required' => true,
'filters' => [
],
'validators' => [
[
'name' => 'StringLength',
'options' => [
'min' => 5,
'max' => 64
],
],
],
]);
}
}
下面是查看文件add.phtml
<script type="text/javascript">
function addSchoolLocation(){
$( ".schoolLocation" ).clone().appendTo( ".schoolLocation" );
}
</script>
<!-- Content Header (Page header) -->
<section class="content-header">
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
<li class="active">Add School</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<div class="row">
<!-- left column -->
<div class="col-md-12">
<!-- general form elements -->
<div class="box box-primary form-custome">
<div class="box-header with-border">
<h3 class="box-title">Add School <ul class="add-icon-new">
<li><a href="#" class="i-down"><i class="fa fa-angle-down"></i></a></li>
<li><a href="#" class="i-refresh"><i class="fa fa-refresh" aria-hidden="true"></i>
</a></li>
<li><a href="#" class="i-close"><i class="fa fa-times" aria-hidden="true"></i></a></li>
</ul>
</h3>
</div>
<h5 class="form-heading">School Information</h5>
<form role="form" method="post">
<div class="box-body">
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('name')); ?>
<?= $this->formElement($form->get('name')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('description')); ?>
<?= $this->formElement($form->get('description')); ?>
</div>
<?= $this->formElement($form->get('active')); ?>
<h5 class="form-heading">School Location</h5>
<div class="schoolLocation">
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('apartment_number')); ?>
<?= $this->formElement($form->get('apartment_number')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('street_name')); ?>
<?= $this->formElement($form->get('street_name')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('city')); ?>
<?= $this->formElement($form->get('city')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('state')); ?>
<?= $this->formElement($form->get('state')); ?>
</div>
<div class="form-group col-md-3 col-sm-6">
<?= $this->formLabel($form->get('pin')); ?>
<?= $this->formElement($form->get('pin')); ?>
</div>
</div>
<div>
<a href="javascript:void(0);" onclick="addSchoolLocation();">Add School Location</a>
<a href="javascript:void(0);" id="addElement">Add School Location</a>
</div>
<div class=" form-group col-sm-12">
<button class="save">Save</button>
<button class="reset">Reset</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- /.row -->
</section>
<!-- /.content -->
我想用 class schoollocation
克隆 div注意*: 我尝试了以下解决方案,但对我没有任何效果,因为这些不是 Zend Framework-3 的解决方案
Zend Framework - Add new input element using javascript
https://docs.zendframework.com/zend-form/collections/#form-collections
您要查找的是 Collections (which you linked) and Fieldsets 的用法。
您使用 Fieldset 来表示实体。在此示例中,Fieldset 是 Location
,附加到 School
.
此外,School
作为与 Location
的 One To Many
关系。
因此,您将有一个 SchoolFieldset
class,它需要一个 Collection
Element。
下面是一个非常简化的设置示例。
后端
位置字段集
class LocationFieldset
{
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
// ... Add whatever for Location
}
}
学校田野集
class SchoolFieldset
{
/**
* @var LocationFieldset
*/
protected $locationFieldset;
public function __construct(LocationFieldset $locationFieldset)
{
$this->locationFieldset($locationFieldset);
}
public function init()
{
parent::init();
$this->add([
'name' => 'name',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Name'),
],
]);
$this->add([
'type' => Collection::class,
'required' => true,
'name' => 'locations',
'options' => [
'label' => _('Locations'),
'count' => 1, // Initial amount of Fieldsets on-load
'allow_add' => true, // Allows creation of 0/multiple
'allow_remove' => true, // Allows removal
'should_create_template' => true, // Creates template in the HTML in a <span data-template="the whole html here"></span> -> JavaScript this bit for duplication/removal
'target_element' => $this->locationFieldset, // A pre-loaded Fieldset must be passed here, not just the FQCN as you would for including a Fieldset not in a Collection
],
]);
// ... Add whatever
}
}
学校形式
class SchoolForm extends CustomAbstractForm
{
public function init()
{
$this->add([
'name' => 'school',
'type' => SchoolFieldset::class,
'options' => [
'use_as_base_fieldset' => true,
],
]);
//Call parent initializer. (Default for me it adds a submit button)
parent::init();
}
}
Front-end
在表格的视图中,我加载了一点JavaScript。它基于 Zend Framework 文档中提供的演示数据。
请注意,这些文档不考虑删除(因此,如果您有 HTML objects 且 ID 为 0-1-2,并且您删除了 1,它将被计算在内,来到 2 并创建另一个 2,给你 0-2-2,从而覆盖你已经拥有的第二个。
我目前在一个项目中的JavaScript是这样的(抱歉,不能给你所有的,但这应该让你开始):
按钮
var $addButton = $('<button type="button" data-action="add-fieldset" class="btn btn-primary">Add another</button>');
var $removeButton = $('<button type="button" data-action="remove-fieldset" class="btn btn-danger">Remove</button>');
用法
$('body').on('click', 'button[type="button"][data-action="add-fieldset"]', function () {
addCollectionFieldset(this);
});
$('body').on('click', 'button[type="button"][data-action="remove-fieldset"]', function () {
removeCollectionFieldset(this);
});
function addCollectionFieldset(element) {
var $element = $(element);
var $fieldsetDataSpan = $element.siblings('span[data-name="fieldset-data"]');
var fieldsetCount = $fieldsetDataSpan.data('fieldset-count');
var escapedTemplate = $element.siblings('span[data-template]').data('template');
var $replaced = $(escapedTemplate.replace(/__index__/g, fieldsetCount));
$replaced.append($removeButton.clone());
$($replaced).insertAfter($element.siblings('fieldset:last'));
$('<hr>').insertBefore($element.siblings('fieldset:last'));
$fieldsetDataSpan.data('fieldset-count', fieldsetCount + 1); // Up the count by one fieldset
}
function removeCollectionFieldset(element) {
$(element).parent().remove();
}
注意: "Remove" 按钮位于 Collection 中的每个字段集中。 "Add another" 按钮位于 Collection 下方。
如何解决这个问题,由您决定。
查看
<?= $this->form($form) ?>
<?php $this->inlineScript()->prependFile($this->basePath('js/form.js')) ?>
控制器动作
public function addAction()
{
/** @var SchoolForm $form */
$form = $this->getSchoolForm();
/** @var Request $request */
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
/** @var School $school */
$school = $form->getObject();
$this->getObjectManager()->persist($school);
try {
$this->getObjectManager()->flush();
} catch (Exception $e) {
throw new Exception(
'Could not save. Error was thrown, details: ' . $e->getMessage(),
$e->getCode(),
$e->getPrevious()
);
}
return $this->redirectToRoute('schools/view', ['id' => $school->getId()]);
}
}
return [
'form' => $form,
'validationMessages' => $form->getMessages() ?: '',
];
}
控制器工厂
class AddControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
/** @var ObjectManager $objectManager */
$objectManager = $container->get(EntityManager::class);
/** @var FormElementManagerV3Polyfill $formElementManager */
$formElementManager = $container->get('FormElementManager');
/** @var SchoolForm $schoolForm */
$schoolForm = $formElementManager->get(SchoolForm::class);
return new AddController($objectManager, $schoolForm);
}
}
FormFactory
class SchoolFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$objectManager = $container->get(EntityManager::class);
$translator = $container->get('MvcTranslator');
$inputFilterPluginManager = $container->get('InputFilterManager');
$inputFilter = $inputFilterPluginManager->get(SchoolFormInputFilter::class); // Did not show this one
/** @var SchoolForm $form */
$form = new SchoolForm();
$form->setObjectManager($objectManager);
$form->setTranslator($translator);
$form->setInputFilter($inputFilter);
return $form;
}
}
FormFactory
class SchoolFieldsetFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$objectManager = $container->get(EntityManager::class);
$translator = $container->get('MvcTranslator');
$fieldset = new SchoolFieldset();
$fieldsetObject = new School();
/** @var SchoolFieldset $fieldset */
$fieldset = new $fieldset($objectManager(), 'school');
$fieldset->setHydrator(
new DoctrineObject($objectManager())
);
$fieldset->setObject($fieldsetObject);
$fieldset->setTranslator($translator);
return $fieldset;
}
}
如果您有空闲时间,我建议您查看我创建的存储库中的更多示例,以帮助在 ZF 和 ZF with Doctrine 中快速创建表单。带有示例的自述文件 is here