where do addElement method defined zend 2? - zend-framework2

$form = new Zend_Form();
$form->addElement('text', 'fname', array('belongsTo' => 'user'));
I need to know where is addElement method defined? I have searched \vendor\ZF2\library\Zend([\Form]) directory but could not find this method!. If there is no such method then please help me to understand how this above two line work and what are other array conf & parameter of this method.
Edit: thanks Crisp. Actually I am trying to make an input array in zf2 like
<input name="val[one]" type="text" />
<input name="val[two]" type="text" />
<input name="val[three]" type="text" />
Or at least... like this
<input name="val[0]" type="text" />
<input name="val[1]" type="text" />
<input name="val[2]" type="text" />
I have found a example with above code and its not working as it is zf1.

In ZF2, programmatic form creation has changed from ZF1. There is no more addElement function, instead you add an element using $form->add($element);
The basic steps to create a form in ZF2 are:
Create a form element
Create a form
Add element to the form
Create a form element:
use Zend\Form\Element;
use Zend\Form\Form;
$name = new Element('name');
$name->setLabel('Your name');
$name->setAttributes(array(
'type' => 'text'
));
$send = new Element('send');
$send->setValue('Submit');
$send->setAttributes(array(
'type' => 'submit'
));
Create a form:
$form = new Form('contact');
Add element to the form:
$form->add($name);
$form->add($send);
However in ZF2, another way would be to use a Factory to generate the form from an array configuration:
use Zend\Form\Factory;
$factory = new Factory();
$form = $factory->createForm(array(
'hydrator' => 'Zend\Stdlib\Hydrator\ArraySerializable',
'elements' => array(
array(
'spec' => array(
'name' => 'name',
'options' => array(
'label' => 'Your name',
),
'type' => 'Text',
)
),
array(
'spec' => array(
'name' => 'send',
'type' => 'Submit',
'attributes' => array(
'value' => 'Submit',
),
),
),
),
));
The form is then referenced from the view and is rendered using form view helpers.
References:
http://framework.zend.com/manual/2.3/en/modules/zend.form.quick-start.html
https://zf2.readthedocs.org/en/develop/modules/zend.form.advanced-use-of-forms.html
http://akrabat.com/category/zend-framework-2/

Related

ZF2 convert empty posted fields to Null

I'm using fieldsets in order to fill forms in ZF2. If an empty field is postedm, the field is also empty in the db. How do I force a Null in the db for empty fields?
In ZF2 I think you need to use Zend\Filter\Null or Zend\Filter\ToNull depending on which version of ZF2 you are using, Zend\Filter\Null became deprecated in ZF2.4.
In your fieldset, assuming you are using the Zend\InputFilter\InputFilterProviderInterface use:
public function getInputFilterSpecification()
{
return array(
'your_field' => array(
'filters' => array(
array('name' => 'ToNull'),
),
),
);
}

Prevent ZF2 formHelper escaping attributes

Hi I have a form with a number field. I use regex to validate the field. For that reason I added the pattern attribute the element. However when I use formText it html escapes the regex pattern.
//inside the form _construct
$this->add(array(
'name' => 'number',
'type' => 'text',
'options' => array(
'label' => 'Number',
),
'attributes' => array(
'pattern' => '/^(\+)?((\d)+(-|\s)?)+$/',
'maxLength' => '20',
'id' => 'number',
),
));
And in the form
<?php echo $this->formText($form->get('number')); ?>
The result is then
<input type="text" name="number" pattern="/^(\+)?((\d)+(-|\s)?)+$/" id="number" value="" maxlength="20">
How can I add the number field to my form without escaping the regex pattern?
Form view helpers are supposed to work that way, providing some baseline security features and automating stuff. So if you don't won't that don't use them:
<input type="<?php echo $form->get('number')->getType(); ?>" pattern="type="<?php echo $form->get('number')->getAttribute('pattern'); ?>" value="<?php echo $form->get('number')->geValue(); ?>">
Not sure what you need displayed, but it should give you a general idea of "my" approach. You can also manually escape stuff like value:
$this->escape($form->get('number')->geValue())
If you find this tedious, you can always write a helper that does this. You can also make PR with an option to turn of the escaping for attributes, but having them on by default is a sensible.

How to make a Razor template for a frequently used Kendo control?

I have a Razor MVC webpage that makes heavy use of Kendo charts/grids.
Some of these grids and charts are found in multiple locations and it's important that the look and feel is identical
right now I've been reusing my backend code quite well by copying the .cshtml between views
with this technique, I do get good backend code reuse, but it'd be awesome to reuse the chart, is this possible?
can I somehow put this code into it's own .cshtml file and then reference it from multiple locations? maybe a Razor version of #include? :S
#(Html.Kendo().Chart<AuthTest.Models.HardDriveUsagePieSlice>().Theme("Uniform")
.Name("chart" + s.Key.ToString()).Title(title => title.Position(ChartTitlePosition.Bottom))
.Legend(legend => legend
.Visible(false)
)
.Series(series =>
{
series.Pie(model => model.Percent, model => model.Title)
.Labels(labels => labels
.Template("#= category #: #= value#%")
.Background("transparent")
.Visible(true)
).StartAngle(150);
})
.DataSource(x => x.Read(r => r.Action("_Usage", "Home", new {ID=s.Value.Id, UID=Model.UID})))
.Tooltip(tooltip => tooltip
.Visible(true)
.Format("{0}%")
).Transitions(false)
)
What I have done was create an html helper that returns a kendo grid. Your helper is just a regular extension that can be written like so:
public static class KendoChartHelper
{
public static Kendo.Mvc.UI.Fluent.ChartBuilder<T> RenderPieSlice<T>(this HtmlHelper helper, string chartName, int uid, int id)
where T : AuthTest.Models.HardDriveUsagePieSlice
{return helper.Kendo().Chart<T>()
.Theme("Uniform")
.Name(chartName).Title(title => title.Position(ChartTitlePosition.Bottom))
.Legend(legend => legend
.Visible(false)
)
.Series(series =>
{
series.Pie(model => model.Percent, model => model.Title)
.Labels(labels => labels
.Template("#= category #: #= value#%")
.Background("transparent")
.Visible(true)
).StartAngle(150);
})
.DataSource(x => x.Read(r => r.Action("_Usage", "Home", new {ID = id, UID = uid})))
.Tooltip(tooltip => tooltip
.Visible(true)
.Format("{0}%")
).Transitions(false);
}
Then in your cshtml file, you can call it like so:
#(Html.RenderPieSlice<AuthTest.Models.HardDriveUsagePieSlice>("MyPieSliceName",s.Value.Id, Model.UID))
I havent tested this exact code, but it should be (somewhat) correct. I hope this helps. Good luck!

Using ZfcUser and BjyAuthorize to show or hide views

I have recently installed ZfcUser and BjyAuthorize and would like to use them to show or hide various parts of the layout.phtml file.
I understand that BjyAuthorize is a firewall of sorts and the flowchart from git hub suggests it should be possible to get current permission status and to use that to hide or show a particular section of code.
So for instance:
<ul>
<li>Admin Menu item</li>
<li>Affiliate menu item</li>
<li>Guest Menu item</li>
</ul>
If an admin user is logged in, he will view all three items, the affiliate will only see Affiliate and guest and the guest will only see guest.
How I was thinking of doing this was something like this:
<?php
//Get array of permissions for current user *not certain how to do this*
$permissionArray = $this->GetBjyPermissions($current->user);
?>
<ul>
<?php if in_array('admin',$permissionArray) {?>
<li>Admin Menu item</li>
<?php } ?>
<?php if in_array('affiliate',$permissionArray) {?>
<li>Affiliate Menu item</li>
<?php } ?>
<li>Guest Menu item</li>
</ul>
Essentially this will allow me to hide the sections of code a user is not allowed to use.
If it is not possible to get the permissions via Bjy or Zfc I guess my option would be to simply query the Database and build a permissions array from that directly.
Has anyone else had to do something like this? Is this approach a good approach or is there another way of achieving this?
Many thanks for any input.
You can use the BjyAuthorize's IsAllowed view Helper. It knows the current user's identity, so you just have to check the rule. It works like:
$isMenuAdmin = $this->isAllowed( 'menu', 'menu_admin' );
$isMenuAffiliate = $this->isAllowed( 'menu', 'menu_affiliate' );
$isMenuGuest = $this->isAllowed( 'menu', 'menu_guest' );
menu is a resource and menu_* a rule. You have to define them in the bjyauthorize.global.php. I'd do it this way:
(...)
'resource_providers' => array(
'BjyAuthorize\Provider\Resource\Config' => array(
'menu' => array(),
),
),
'rule_providers' => array(
'BjyAuthorize\Provider\Rule\Config' => array(
'allow' => array(
/*
[0] -> role
[1] -> resource
[2] -> rule
*/
array( array( 'admin' ), 'menu', array( 'menu_admin' ) ),
array( array( 'affiliate' ), 'menu', array( 'menu_affiliate' ) ),
array( array( 'guest' ), 'menu', array( 'menu_guest' ) ),
),
),
),
(...)
BTW, it seems that you're trying to build a menu. I recommend you to check this post about integrating Zend Navigation with BjyAutorize.

putting jquery buttons in clistview widget in yii

I am trying to put a button which will be displayed along with some data in the view file I specified in "itemView" field of the CListView widget, but instead of the styled button for every list item, I am just getting it or the first list item. My code in the _view file is:
<div id="listView">
<div class="thedata">
...some data
</div>
<div id="buttons">
<?php
$this->widget('zii.widgets.jui.CJuiButton', array(
'buttonType'=>'button',
'name'=>'btnJobs',
'caption'=>'Manage Jobs',
'options'=>array('icons'=>'js:{primary:"ui-icon-wrench"}'),
'onclick'=>'js:function(){alert("Manage Jobs clicked."); this.blur(); return false;}',
));
?>
</div>
</div>
and the code for CListView widget is just the bare minimum:
$this->widget('zii.widgets.CListView', array(
'dataProvider' => $dataProvider,
'itemView' => '_view'
));
any suggestions?
Try passing in a unique ID to the CJuiButton, like so:
<?php
$this->widget('zii.widgets.jui.CJuiButton', array(
'id'=>'button'.$data->id, // add a unique ID here (could use $index instead of $data->id)
'buttonType'=>'button',
'name'=>'btnJobs',
'caption'=>'Manage Jobs',
'options'=>array('icons'=>'js:{primary:"ui-icon-wrench"}'),
'onclick'=>'js:function(){alert("Manage Jobs clicked."); this.blur(); return false;}',
));
?>
The problem is that since all of your buttons have the same 'name' (and therefore 'id') jQuery is only binding to the first one. Making sure each button has a unique ID should fix this, so jQuery will bind correctly.

Resources