How to use subforms in Zend Framework2 - zend-framework2

Is there a way how I can use zend subforms in Zend Framework2. When I did a search in the internet I have landed upon many examples showing how to use zend subforms but using Zend Framework1.
In case if somebody has a link/example where one can go through a basic example, would be great.
Any information is appreciated.

Because Zend\Form is tree structure, you could add another form into your form with a form name. Such like this:
$form = new \Zend\Form\Form();
$form->add(array(
'name' => 'username',
'type' => 'Zend\Form\Element\Text',
));
$subForm = new \Zend\Form\Form();
$subForm->setName('subform');
$subForm->add(array(
'name' => 'email',
'type' => 'Zend\Form\Element\Text',
));
$form->add($subForm);
$form->prepare();
$helper = new Zend\Form\View\Helper\FormText();
echo $helper($form->get('username')); //<input type="text" name="username" value="">
echo $helper($form->get('subform')->get('email')); //<input type="text" name="subform[email]" value="">
Notice that the "subform" input name will be add form name as prefix automatic.

I've been using it for a few hours, and in my understanding, zf1 subforms funcionalities are solved in zf2 by using nested fieldsets.
\Zend\Form\Fieldset is also the parent class of \Zend\Form\Form.
The previous answer seems correct to me, but if you prefer to keep forms and subforms in separate classes, read this:
http://zf2.readthedocs.org/en/latest/modules/zend.form.collections.html
Ignore the entity and hydration stuff if you are not interested for now, and look at CreateProduct class, it's a form that uses the FieldSet ProductFieldset as a subform. At rendering time, subform fields will be named like
<input ...name="product[el1]" ... >
(where product is the name of the subform).
And $form->getData() will return
array('product'=>array(...))
Note: you need to call $form->prepare(); before rendering, or the nesting won't be processed.

Related

ZF2 Form: How to provide field hints

I've been learning how to use ZF2 from the book Learn ZF2: Learning by Example by Slavey Karadzhov. In it, he shows how to build forms using annotations. One particularly helpful feature is the "pattern" attribute. If you add a pattern to the form, there's a really cool JavaScript function that checks does client-side validation. If a field's input doesn't match the desired pattern, a groovy little tooltip of sorts pops up pointing out the field(s) that have problems and telling you what needs to be fixed.
I was wondering: is there a similar system in ZF2 so that, when a field is highlighted, a similar tooltip pops up to give hints on what exactly needs to be entered into a field? For example, for a password field it could give the requirements for the password. And if this isn't built in, is there a module out there somewhere that does this? I've done a bunch of Googling on this subject, but I've come up empty so far.
Since zf2 come's with an Twitter Bootstrap implementation you could just use the Tooltip functionality.
I personally do not use anotation's in my forms for various reasons, one being the performance hit you take.
within your YourForm.php just set some data attributes and you should be good to go:
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Save',
'id' => 'submitbutton',
'data-toggle' => 'tooltip',
'data-placement' => 'left',
'title' => 'Press me I am a button :D',
),
));
The annotation equivalent would be:
* #Annotation\Attributes({"data-toggle":"tooltip", "data-placement":"left", "title":"Press me I am a button :D"})
don't forget to initialize
$(function () {
$('[data-toggle="tooltip"]').tooltip();
})

Dynamically created CJuiAutoComplete in Yii not working

I have used jQuery's autocomplete plugin in the past, but never before through Yii's implementation of it as a widget.
I am dynamically creating another autocomplete field and not able to set it to live:
$('input.ui-autocomplete-input').live("keydown.autocomplete", function() {
$(this).autocomplete();
});
or simply calling .autocomplete() when it is created to get it to work. Any ideas why this would work differently through Yii than through just using the plugin itself, or am I missing something really simple?
Thanks for any help!
My solution was overly simple.
Each autocomplete field must have a unique name attribute. I was using
<input name="family[]"/>
<input name="family[]"/>
<input name="family[]"/>
Fixed by changing it to:
<input name="family_0"/>
<input name="family_1"/>
<input name="family_2"/>
Just a little embarrassing, but worth posting in case anyone else ever overlooks such a simple issue.
Note: the code above isn't exact, the point is to make sure you are using unique names for each of the fields that are using jQueryUI's autocomplete.
CJuiAutoComplete relies on jQuery UI's autocomplete so please be sure that jQuery UI is registered for the view you create a field dynamically in:
Yii::app()->clientScript->registerCoreScript("jquery.ui");
Also be sure that source parameter with your autocomplete tags is provided for autocomplete() call. The following works fine for me:
<?php
$source = array(
"hello",
"test"
);
?>
<div id="wrapper">
</div>
<?php
Yii::app()->clientScript->registerScript("autocomplete", "
$('<input />')
.addClass('ui-autocomplete-input')
.appendTo($('#wrapper'));
$('input.ui-autocomplete-input').autocomplete({
'source': " . CJavaScript::encode($source) . "
});
", CClientScript::POS_READY);

Why doesn't TextBoxFor include validation elements if called twice for the same model property?

Simple question... Here is an example of some razor code:
#Html.TextBoxFor(c => c.RevisedEstimate)
#Html.TextBoxFor(c => c.RevisedEstimate)
Here is how this renders:
<input data-val="true" data-val-number="The field Revised Estimate must be a number." id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
<input id="RevisedEstimate" name="RevisedEstimate" type="text" value="0" />
The obvious question you ask is, "Why are you doing that?". The razor view is actually building client side detail-row templates that are used in KendoUI grids. There are two similar grids and we use the same viewmodel server side. We actually do provide the id element for the template so each field in each row ends up with a unique id.
Why does the second input element not have the data-val and data-val-number elements?
Off the top of my head knowing what the JS does in the background, it seems to do this to prevent conflicts. The JS looks for the elements with the data- attributes to do it's validation, along with other functions, so it could possibly pick the wrong one if there are multiple instances of it.
since we were generating HTML for use in a client side template what we did was just create a variable to hold the HTML generated by the helper, and then render out that code in the Views..
Something like:
#{
var revisedEstimateInput = Html.TextBoxFor(c => c.RevisedEstimate)
}
Then later in the view:
#(revisedEstimateInput)
...in as many places as needed. This way the validation and other metadata attributes were in place in our client templates and all the kenodUI validation worked correctly.

.Net MVC replacement for Formtastic

I've found myself working on a .Net MVC3 project and sorely missing having Formtastic available in my rails apps.
Are there any good .Net MVC replacements for Formtastic?
I suggest using MVC3s HTML Helpers.
#model mynspace.MyModel
#Html.EditorForModel()
This html helper generates editor fields for every field in your model, choosing the most likely option. Editing the Editor template, you can change the way it is layed out as well. See this question on changing the template
It can of course be used more customizable by each field with things like:
#Html.Label("Daily Rate")
#Html.EditorFor(model => model.DailyRate)
#Html.ValidationMessageFor(model => model.DailyRate, "Please enter a valid Daily Rate (2 d.p.)")
This can be custom layed out by putting tags around it, i.e. things like <p> or <td>
You can also force an input type using options like:
#Html.TextBoxFor(model => model.DailyRate)
#Html.CheckBoxFor(model => model.DailyRate)
#Html.DropDownBoxFor(model => model.DailyRate, ViewBag.DailyRates)
see here for a full list of options
I have a project called FormFactory that lets you do much of the stuff formastic does http://formfactory.apphb.com/
It transforms model objects into PropertyVm objects, which are a viewmodel for an input basically. You could manually create the PropertyVms if you want.

How to concatenate the id of the HTML element using Razor ASp.NET MVC

I have a grid column with checkboxes and I want to give them a different id. Id is based on the CustomerId in the Model. What syntax should I use to concatenate the chk_#item.CustomerId.
// using the telerik grid
id="chk_#item.OrderNumber" // does not work
// this will put the value of #item.Customernumber as the checkbox id
columns.Template(#<text><input type='checkbox' id="#item.Customernumber" name="#item.CustomerNumber" value="#item.OrderNumber" /></text>).Width(50)
second option:
columns.Template(#<text><input type='checkbox' id="chk_#item.Customernumber" name="#item.CustomerNumber" value="#item.OrderNumber" /></text>).Width(50)
the above will render as
<input type="checkbox" id="chk_#item.Customernumber" value=... />
chk_#item.OrderNumber will not work because razor thinks of it as of an e-mail, you need to do it like this instead: chk_#(item.OrderNumber)
Correct Syntax
id="#("chk_"+#item.Id)"
This does works now in latest MVC:
id="chk_#item.OrderNumber"
Happy coding.

Resources