I want to add multiple school locations in zend-form on click of anchor tag or button.
So that zend form validation can be applied to all dynamically created fields
Please see attached image.I want to clone div with in red border in image
Below is SchoolController Class
<?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
]);
}
}
Below is 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
],
],
],
]);
}
}
Below is view file 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 -->
I want to clone div with class schoollocation
Note*: I tried below solutions but nothing worked for me as those are not the solution for Zend Framework-3
What you're looking for is the usage of Collections (which you linked) and Fieldsets.
You use a Fieldset to represent an Entity. In this example the Fieldset is
Location, attached toSchool.Also, the
Schoolas aOne To Manyrelation withLocation.As such, you would have a
SchoolFieldsetclass, which needs aCollectionElement.Below a very simplified example of the setup.
Backend
LocationFieldset
SchoolFieldset
SchoolForm
Front-end
In the view of the form, I load a bit of JavaScript. It's based on the demo data given in the Zend Framework documentation.
Please note that those docs do not account for removal (so if you have HTML objects with id's 0-1-2 and you remove 1, it will count, come to 2 and create another 2, giving you 0-2-2 and thus an overwrite for the second one you already had).
The JavaScript I have in a project at the moment is this (sorry, cannot give you all of it, but this should get you started):
Buttons
Usage
Note: the "Remove" button is placed IN every Fieldset within the Collection. The "Add another" button is placed below the Collection.
How you solve that issue, is up to you.
View
Controller action
ControllerFactory
FormFactory
FormFactory
If you have a few moments to spare, I would advise you to check out more examples in a repo I created to help quickly create forms in ZF and ZF with Doctrine. The ReadMe with examples is here