How add custom attribute in zend framework 2 using zend from - php

I want to use angularJS in a zend framework project and in this project forms are generated using zend form. How can I add angular directive such as "ng-model" in the form elements but whenever i was trying to add this custom attribute in the zend-form elements (input, select etc) in view I am not getting this attribute ----
Here is my lead form
class LeadForm extends Form {
public function __construct() {
parent::__construct('lead_form');
$this->setAttributes(array(
'action' => '',
'method' => 'post',
'name' => 'lead_form',
'id' => 'lead_form',
'class' => 'smart-form',
'role' => 'form',
'novalidate' => 'novalidate'
));
$this->add(array(
'name' => 'first_name',
'type' => 'text',
'options' => array(
'label' => 'First Name',
),
'attributes' => array(
'class' => 'form-control validate[required,custom[onlyLetterSp]]',
'placeholder' => 'First name',
**'ng-model' => "first_name", // this attribute is not generating in view**
),
));
}
}
Here is my controller which is calling this form and send to view for displaying
$createLeadForm = new \Admin\Form\LeadForm();
return new ViewModel(array(
'form' => $createLeadForm,
));
Here is my code in view for showing element
<?php echo $this->formInput($this->form->get('first_name')); ?>
But after prinnting this form element i am getting see no "ng-model" in the input element
<input type="text" value="" placeholder="First name" class="form-control validate[required,custom[onlyLetterSp]]" name="first_name" >
I have set one attribute "ng-model " but this attribute is not appearing in the view
I want this element like (using zend form ) -
<input type="text" ng-model="first_name" value="" placeholder="First name" class="form-control validate[required,custom[onlyLetterSp]]" name="first_name" >
How can I do that using zend form and what need to change in this form and why i can not able to add custom attribute? please help me.
Thanks in Advance

You always can use data-ng-*:
$this->add(array(
// ...
'attributes' => array(
// ...
'data-ng-model' => 'first_name',
),
));

Zend does not support other attribute if that attribute start other than data-* so for adding attribute for ng-* I had to modify the View Helper class
under this namespace ( Zend\Form\View\Helper ) inside the main library you will find a class named "AbstractHelper" and in this class you can get a method named "prepareAttributes" and here you have to change the following lines -
if (!isset($this->validGlobalAttributes[$attribute])
&& !isset($this->validTagAttributes[$attribute])
&& 'data-' != substr($attribute, 0, 5)
)
to
if (!isset($this->validGlobalAttributes[$attribute])
&& !isset($this->validTagAttributes[$attribute])
&& 'data-' != substr($attribute, 0, 5)
&& 'ng-' != substr($attribute, 0, 3)
)
see here I add
&& 'ng-' != substr($attribute, 0, 3)
so that ng-* attributes can be added using zend form
Thanks Again

This worked for me.
class FooForm extends Form
{
public function __construct(LookupService $lookupService)
{
parent::__construct('fooForm');
$this->setAttribute('novalidate', true);
}
...
}

Try this: (data attribute)
ZF2:
public function __construct() {
parent::__construct('lead_form');
$this->setAttributes(array(
'action' => '',
'method' => 'post',
'name' => 'lead_form',
'id' => 'lead_form',
'class' => 'smart-form',
'role' => 'form',
'novalidate' => 'novalidate'
));
$this->add(array(
'name' => 'first_name',
'type' => 'text',
'options' => array(
'label' => 'First Name',
),
'attributes' => array(
'class' => 'form-control validate[required,custom[onlyLetterSp]]',
'placeholder' => 'First name',
'data-ng' => json_encode(
array(
'ng-model' => 'first_name',
'ng-123' => '123',
), true
)
),
));
}
Call this JS function after your HTML-Manipulation:
/**
* ZF2 supports no custom attributs
* this function converts data-ng attributes to ng attributes
*/
function addNgAttributes() {
$('[data-ng]').each(function () {
var ngdata = $(this).data('ng');
var _this = this;
$.each(ngdata, function (key, value) {
$(_this).attr(key, value)
});
})
}

You should extend Zend\Form\View\Helper\FormFile and replace it via factory:
namespace YourNamespace;
use Zend\Form\View\Helper\FormFile;
class FormFile extends FormFile {
/**
* Attributes valid for the input tag type="file"
*
* #var array
*/
protected $validTagAttributes = [
'name' => true,
'accept' => true,
'autofocus' => true,
'disabled' => true,
'form' => true,
'multiple' => true,
'required' => true,
'type' => true,
'yourCustomAttribute' => true, //<--- here add Your attribute
];
}
and in module.php:
public function getViewHelperConfig() {
return array(
'factories' => array(
'Zend\Form\View\Helper\FormFile' => function($sm) {
$helper = new \YourNamespace\FormFile();
return $helper;
}
)
);
}
then You can use yourCustomAttribute in form class as other attributes.

Related

Zend Form 2 multiselect field is empty after validation

I'm not sure what's going on. I'm using Zend Form 2 with a multiselect field. When I submit the code, the values exist in post. When I run the values through zend form 2, I get no validation errors but the multiselect field is suddenly empty.
class Form extends \Zend\Form\Form
{
// input filter to set up filters and validators
protected $myInputFilter;
public function __construct()
{
// create the zend form
parent::__construct();
// make it a bootstrap form
$this->setAttribute('class', 'form-horizontal');
$this->setAttribute('role', 'form');
// set the default objects we'll use to build the form validator
$this->myInputFilter = new \Zend\InputFilter\InputFilter();
}
}
class AddPublicationForm extends Form
{
public function __construct()
{
// create the zend form
parent::__construct();
$this->setAttribute('class', 'form-horizontal');
$this->setAttribute('id', 'add-publication-form');
$this->add([
'name' => 'author[]',
'attributes' => [
'class' => 'form-control',
'data-placeholder' => 'Author',
'multiple' => 'multiple',
'placeholder' => 'Author',
],
'required' => false,
'type' => \Zend\Form\Element\Select::class,
'options' => [
'value_options' => [
'check1' => 'check1',
'check2' => 'check2',
],
],
]);
$this->myInputFilter->add([
'filters' => [],
'name' => 'author[]',
'required' => false,
'validators' => [],
]);
// attach validators and filters
$this->setInputFilter($this->myInputFilter);
// prepare the form
$this->prepare();
}
}
These are the zend form objects that I am using. I am using Slim Framework 2 as my backend. Here is the controller object:
public function addAction()
{
$request = $this->app->request;
$form = new Form\AddPublicationForm();
if ($request->isPost()) {
$params = $request->params();
// DUMP 1: exit('<pre>'.print_r($params, true).'</pre>');
$form->setData($params);
if ($form->isValid()) {
$data = $form->getData();
// DUMP 2: exit('<pre>'.print_r($data, true).'</pre>');
}
}
}
DUMP 1:
Array
(
[author] => Array
(
[0] => check1
[1] => check2
)
}
DUMP 2:
Array
(
[author[]] =>
)
I realize that I could very easily just bypass the validation here because I'm not using any validators on that field. I'm more concerned with the underlying cause though.
Why is the validated author data empty?
When you specify multiple in attributes, Zend\Form and Zend\InputFilter add []after the name. You should not do it yourself otherwise, in the html code, the element appears under the name author[][] and the setData method don't match.
To see it, replace required by true and look at the html code of the form.
$this->add([
'name' => 'author',
'attributes' => [
'class' => 'form-control',
'data-placeholder' => 'Author',
'multiple' => 'multiple',
'placeholder' => 'Author',
],
'required' => false,
'type' => \Zend\Form\Element\Select::class,
'options' => [
'value_options' => [
'check1' => 'check1',
'check2' => 'check2',
],
],
]);
$this->myInputFilter->add([
'filters' => [],
'name' => 'author',
'required' => false,
'validators' => [],
]);

How to call a controller function inside the form in zend 2

i am new in zend framework
i need to add dynamic values inside the form selection elements
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'SECTOR_ID',
'attributes' => array(
'class' => 'form-control select2drop',
'id' => 'Sector_ID'
),
'options' => array(
'value_options' => $this->getOptionsForSectorSelect(),
),
'disable_inarray_validator' => true
));
above code help me to get dynamic values
but i need to call a controller function for getting value , now i wrote getOptionsForSectorSelect inside the form
Please help me
You could make the method inside your Controller static
class IndexController extends AbstractActionController {
public static function getOptionsForSectorSelect() {
// Building dynamic array ...
return $dynamicArray;
}
// More code ...
}
Or you could pass the array with your form when creating it in your action like so:
public function indexAction() {
$dynamicArray = $this->getOptionsForSectorSelect();
$myForm = new YourForm($dynamicArray);
// more action code...
}
And then in your form:
class YourForm extends Form {
private $dynamicArray;
public function __construct(array $dynamicArray) {
$this->dynamicArray = $dynamicArray;
}
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'SECTOR_ID',
'attributes' => array(
'class' => 'form-control select2drop',
'id' => 'Sector_ID'
),
'options' => array(
'value_options' => $this->dynamicArray,
),
'disable_inarray_validator' => true,
));
}
Hope it helps! :)

ZF2 remove isEmpty validation for form element

I need use form element with out isEmpty validation. This is my code.
$this->add(array(
'name' => 'test',
'type' => 'Zend\Form\Element\Number',
'attributes' => array(
'class' => 'form-control',
)
));
But following validation message is given.
[test] => Array
(
[isEmpty] => Value is required and can't be empty
)
How can i remove it?
Look here:
https://github.com/zendframework/zf2/blob/master/library/Zend/Form/Element/Number.php#L95
You can extend this class and overload getInputSpecification function and return array without 'required' => true
Like this:
namespace Your\Form\Elements;
use Zend\Form\Element\Number;
class NumberWithoutRequired extends Number{
public function getInputSpecification()
{
return array(
'name' => $this->getName(),
'required' => false,
'filters' => array(
array('name' => 'Zend\Filter\StringTrim')
),
'validators' => $this->getValidators(),
);
}
}
And then use this class for input in Your form instead of original Zend\Form\Element\Number class
If you have a specific form class, add a getInputFilterSpecification method with your validation rules:
class MyForm extends \Zend\Form\Form
{
public function init() // or __construct() if not using element manager
{
$this->add(array(
'name' => 'test',
'type' => 'Zend\Form\Element\Number',
'attributes' => array(
'class' => 'form-control',
)
));
}
public function getInputFilterSpecification()
{
return [
'test' => [
'required' => false,
]
];
}
}
You could do that by creating new ValidatorChain, and then loop through the validators attached to your element and dettach the Zend\Validator\NotEmpty validator. Just like this :
$newValidatorChain = new \Zend\Validator\ValidatorChain;
foreach ($form->getInputFilter()->get('test')->getValidatorChain()->getValidators()
as $validator)
{
//Attach all validators except the \Zend\Validator\NotEmpty one
if (!($validator['instance'] instanceof \Zend\Validator\NotEmpty)) {
$newValidatorChain->addValidator($validator['instance'],
$validator['breakChainOnFailure']);
}
}
$form->getInputFilter()->get('test')->setValidatorChain($newValidatorChain);

Add a dynamic grid as input in custom extension Admin HTML from phtml file.

I've got this problem that I can't solve. Partly because I can't explain it with the right terms. I'm new to this so sorry for this clumsy question.
Below you can see an overview of my goal.
I'm using Magento CE1.7.0.2
you can see here i want to get like this in my custom module
Here is my Form.php
<?php
class Company_Web_Block_Adminhtml_Web_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('web_form', array('legend'=>Mage::helper('web')->__('Item information')));
$fieldset->addField('title', 'text', array(
'label' => Mage::helper('web')->__('Title'),
'class' => 'required-entry',
'required' => true,
'name' => 'title',
));
$fieldset->addField('filename', 'file', array(
'label' => Mage::helper('web')->__('File'),
'required' => false,
'name' => 'filename',
));
$fieldset->addField('status', 'select', array(
'label' => Mage::helper('web')->__('Status'),
'name' => 'status',
'values' => array(
array(
'value' => 1,
'label' => Mage::helper('web')->__('Enabled'),
),
array(
'value' => 2,
'label' => Mage::helper('web')->__('Disabled'),
),
),
));
$fieldset->addField('content', 'editor', array(
'name' => 'content',
'label' => Mage::helper('web')->__('Content'),
'title' => Mage::helper('web')->__('Content'),
'style' => 'width:700px; height:500px;',
'wysiwyg' => false,
'required' => true,
));
if ( Mage::getSingleton('adminhtml/session')->getWebData() )
{
$form->setValues(Mage::getSingleton('adminhtml/session')->getWebData());
Mage::getSingleton('adminhtml/session')->setWebData(null);
} elseif ( Mage::registry('web_data') ) {
$form->setValues(Mage::registry('web_data')->getData());
}
return parent::_prepareForm();
}
}
How do i get this ?
Any ideas ?
Create a Renderer file like below
NameSpace\ModuleName\Block\Adminhtml\ModuleName\Edit\Renderer\Display.php
The file relates to below code adminhtml_modulename_edit_renderer_display
Try adding below fieldset in your Form.php
<?php
// This code is being used to sort the renderer display in form using element of your own
$fieldset->addType('modulename', Mage::getConfig()->getBlockClassName('modulename/adminhtml_modulename_edit_renderer_display'));
$fieldset->addField('yourdbfield_name', 'modulename', array(
'name' => 'yourdbfield_name',
'label' => Mage::helper('modulename')->__('Title you want to show'),
'required' => true,
));
// This code is being used to sort the renderer display in form using element of your own
?>
You can also add renderer like this
'renderer' => 'modulename/adminhtml_modulename_edit_renderer_display',
Now in your display.php add below HTML code along with the JS code.
<table id="modulename_tbl_data" cellspacing="0">
<button id="add_your_component" class="add" type="button" title="Add"><span><span><span>Add</span></span></span></button>
</table>
jQuery Code
jQee('#add_your_component').click(function() {
var jQee = jQuery.noConflict();
jQee(document).ready(function(){
var i = jQee('input').size() + 1;
jQee('#add').click(function() {
var one = '<input id="yourID" name="yourName[]" value="" class="required-entry validate-number input-text required-entry"/>';
var remove = '<button onclick="javascript:jQuery(this).parent().parent().remove();" class="delete" type="button" title="Remove"><span><span><span>Remove</span></span></span></button>';
var tr = '<tr class="div_class"><td style="padding:0px 10px;">'+one+'</td><td style="padding:0px 10px;">'+remove+'</td></tr>';
jQuery('#modulename_tbl_data').append(tr);
i++;
});
});
This will allow you add options and remove them just like Magento.
Note: This is a just a demo and not complete code. You can alter it according to your needs.

Zend Framework 2 - I can't manage to validate form when using fieldsets

I have a Registration form.
namespace User\Form;
use Zend\Form\Form;
class Register extends Form {
public function __construct() {
parent::__construct('register');
$this->setAttribute('action', 'new-account');
$this->setAttribute('method', 'post');
//$this->setInputFilter(new \User\Form\RegisterFilter); - used this prior to learning Fieldset
$this->add(new \User\Form\RegisterFieldsetUser);
// Submit
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Register',
'class' => 'btn btn-primary',
),
));
}
}
and the User fieldset:
(to make this short I've only left on field)
namespace User\Form;
use Zend\Form\Fieldset;
class RegisterFieldsetUser extends Fieldset {
public function __construct() {
parent::__construct('user');
// User Identifier
$identifier = new \Zend\Form\Element\Email();
$identifier->setName('identifier');
$identifier->setAttributes(array(
'id' => 'user-email',
'placeholder' => 'Email'
));
$identifier->setLabel('Your email:');
$this->add($identifier);
}
public function getInputFilterSpecification() {
return array(
'identifier' => array(
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
\Zend\Validator\NotEmpty::IS_EMPTY => 'You really have to enter something!',
),
),
),
array(
'name' => 'EmailAddress',
'options' => array(
'messages' => array(
\Zend\Validator\EmailAddress::INVALID_FORMAT => 'Hmm... this does not look valid!',
),
),
),
),
),
);
}
}
this is my action:
public function registerAction() {
$registerForm = new \User\Form\Register;
if ($this->getRequest()->isPost()) {
// Form processing
$formData = $this->getRequest()->getPost();
if ($registerForm->isValid()) {
// Yeeeeei
} else {
$registerForm->setData($formData);
return new ViewModel(array(
'form' => $registerForm,
));
}
} else {
return new ViewModel(array(
'form' => $registerForm,
));
}
}
Now, if I submit the form without entering anything, I get the message : "Value is required and can't be empty" (which is NOT the message I have set). But it's not an issue with the messages I set, because if I submit the form with an invalid email address ("asd/") then it doesn't say anything, no validation error. So, I assume no validation happens here.
Any clue why?
Before learning to use filedset, I had an InputFilter which worked perfectly fine, but following the book's learning curve, I got to using Fieldset.
I'm just a zf newb, learning from this book I've bought from leanpub (Michael Romer's "Web development with zf2"). I don't know the version used in the book (it was last updated in august 2013), but I use the latest (2.2.5).
If you want to add filter specification by getInputFilterSpecification method your form class (or fieldset class) MUST implement InputFilterProviderInterface. So:
<?php
use Zend\InputFilter\InputFilterProviderInterface;
class RegisterFieldsetUser extends Fieldset
implements InputFilterProviderInterface
{
...
}

Categories