I want the following html with two radio button groups in zend form
<label class="inline">
<input type="radio" name="form-field-radio">
<span class="lbl"> Male</span>
</label>
<label class="inline">
<input type="radio" name="form-field-radio">
<span class="lbl"> Female</span>
</label>
and i'm using the following code to make this button in Zend Form
$gender = $this->CreateElement('radio','gender')
->addFilter(new Zend_Filter_StringTrim())
->setMultiOptions(array('M'=>'Male', 'F'=>'Female'))
->setDecorators(array( array('ViewHelper') ));
But I don't know where to set the lable and span classes in this code.
Please help.
Thanks.
I am not sure whether its the perfect method to do this its the first time i am using zend framework, But still here are the steps that i did, if you may find useful:
First I created a custom decorator which extends Zend_Form_Decorator_Abstract and saved it in the location 'decorator/My_Form_Decorator.php'. decorator is a directory created by me in root.
.
/decorator
/application
etc...
Then i included it in a controller. I have read that there are certain methods for adding the decorator like addPrefixPath() but for time sake i just included the decorator file in top with 'include "../decorator/My_Form_Decorator.php";'. Then instead of using the CreateElement method i used Zend_Form_Element.
The following is the code of custom radio decorator
My_Form_Decorator.php
class My_Decorator_RadioInput extends Zend_Form_Decorator_Abstract
{
public function render($content)
{
$element = $this->getElement();
$label = htmlentities($element->getLabel());
$type = $element->type;
$name = $element->elemName;
$multiOptions = $element->multiOptions;
$labelClass = $element->labelClass;
$spanClass = $element->spanClass;
$markup='';
if(!empty($type) && !empty($name) && !empty($multiOptions) && is_array($multiOptions)){
foreach($multiOptions as $key=>$value){
$markup .='<label class="'.$labelClass.'"><input type="radio" name="'.$name.'" value="'.$key.'"> <span class="'.$spanClass.'">'.$value.'</span></label>';
}
}
return $markup;
}
}
and this is the code in my controller function
IndexController.php
$decorator = new My_Decorator_RadioInput();
$form = new Zend_Form();
$form->setAttrib('id', 'test');
$element = new Zend_Form_Element('foo', array(
'elemName'=>'gender',
'type' =>'radio',
'multiOptions' => array('M'=>'Male', 'F'=>'Female'),
'labelClass'=>'inline',
'spanClass'=>'lbl',
'decorators' => array($decorator),
));
$form->addElement($element);
$this->view->form = $form;
And in view index.phtml
echo $this->form
Hope this is helpful to you..
Related
I created a form using formBuilder in Symfony. I add some basic styling to the form inputs using an external stylesheet and referencing the tag id. The form renders correctly and processes information correctly.
However, it outputs an unwanted unordered list with a list item containing the following text: This form should not contain extra fields.
I am having a really hard time getting rid of this notice. I was wondering if someone can help me understand why it being rendered with my form and how to remove it?
Many thanks in advance!
Controller
$form = $this->createFormBuilder($search)
->add('searchinput', 'text', array('label'=>false, 'required' =>false))
->add('search', 'submit')
->getForm();
$form->handleRequest($request);
Twig Output (form is outputted and processed correctly
This form should not contain extra fields.
Rendered HTML
<form method="post" action="">
<div id="form">
<ul>
<li>This form should not contain extra fields.</li>
</ul>
<div>
<input type="text" id="form_searchinput" name="form[searchinput]" />
</div>
<div>
<button type="submit" id="form_search" name="form[search]">Search</button>
</div>
<input type="hidden" id="form__token" name="form[_token]" value="bb342d7ef928e984713d8cf3eda9a63440f973f2" />
</div>
</form>
It seems to me that you have the problem because of the token field. If it is so, try to add options to createFormBuilder():
$this->createFormBuilder($search, array(
'csrf_protection' => true,
'csrf_field_name' => '_token',
))
->add('searchinput', 'text', array('label'=>false, 'required' =>false))
->add('search', 'submit')
->getForm();
To find out the extra field use this code in controller, where you get the request:
$data = $request->request->all();
print("REQUEST DATA<br/>");
foreach ($data as $k => $d) {
print("$k: <pre>"); print_r($d); print("</pre>");
}
$children = $form->all();
print("<br/>FORM CHILDREN<br/>");
foreach ($children as $ch) {
print($ch->getName() . "<br/>");
}
$data = array_diff_key($data, $children);
//$data contains now extra fields
print("<br/>DIFF DATA<br/>");
foreach ($data as $k => $d) {
print("$k: <pre>"); print_r($d); print("</pre>");
}
$form->bind($data);
This message is also possible if you added/changed fields in your createFormBuilder() and press refresh in your browser...
In this case it's ok after sending the form again ;-)
I got the same message while having multiple forms on the same page. Turns out, symfony defaults to the name 'form' for all of them. Instead of using createFormBuilder, you can change the name of the form to avoid conflicts using
public FormBuilderInterface createNamedBuilder(string $name, string|FormTypeInterface $type = 'form', mixed $data = null, array $options = array(), FormBuilderInterface $parent = null)
See https://stackoverflow.com/a/13366086/1025437 for an example.
I ran into this error when creating a multi-step form.
When the step 1 form is submitted, $request->request contains acme_mybundle_myform array. This created a validation error and stopped the back, forward and form fields from populating correctly. Not to mention "this-form-should-not-contain-extra-fields"
I discovered this thanks to the code by nni6.
The solution in my case was inside the controller:
if ($form->isValid())
{
if($form->has('nextStep') && $form->get('nextStep')->isClicked())
{
$session->getFlashBag()->set('notice', 'Next clicked');
$registerType->incrementStep();
$request->request->remove('acme_mybundle_myform');
return $this->forward("AcmeMyBundle:Default:register", array($request));
}
....
}
I had the same error.
It was because I had a form which, by mistake, had a NULL name.
In the HTML, the name attribute would look like this:
<form name href="..." action"..."></form>
As simple as that.
Might not be the case for everyone, but worth to check.
I have have a view in which there's a form that manages products (either add new product or -if an id passed- editing an existing one). If an id is passed then the form action should be eg 'admin/product/manage/5', if no id passed then it should be like this 'admin/product/manage'.
<?php echo form_open('admin/product/manage/{optional product id}', array('class' => 'ajax-form')); ?>
I have also created and this route:
$route['admin/product/manage'] = "admin/product/manage";
$route['admin/product/manage/(:num)'] = "admin/product/manage/$1";
How can I make my form action work correctly? is it possible to put inside the action the route somehow??
This is my Controller:
public function manage($id = NULL){
//fetch a single product to edit or create a new one
if (isset($id) === true) {
$data['prod'] = $this->product_model->get($id);
$data['vers'] = $this->product_version_model->get_by('product_id',$id);
} else {
$data['prod'] = $this->product_model->make_new();// this returns $product->product_name = ''; in order to be empty the input field and not throughing errors
}
$this->product_model->save_product();
$this->product_version_model->save_version();
// load the view
$this->layout->view('admin/products/manage', $data);
}
This is my view:
<?php echo form_open('admin/product/manage', array('class' => 'ajax-form')); ?>
<p>
<label for="product_name">Product *</label>
<input type="text" name="product_name" value="<?php echo set_value('product_name', $prod->product_name); ?>" />
<?php echo form_error('product_name'); ?>
</p>
<?php echo form_close() . PHP_EOL; ?>
You need to declare both possible routes in order of importance, so:
$route['admin/product'] = "admin/product/manage";
$route['admin/product/(:num)'] = "admin/product/manage/$1";
From the Codeigniter Docs:
Routes will run in the order they are defined. Higher routes will always take precedence over lower ones.
Edit:
According to the changes you have made to your question I can say the following:
First of all isset() returns boolean only, so you don't need the type check "=== true". isset($id) is sufficient.
In order to have your form action set to the id you need to include it either in a hidden field or in the action itself.
So for example:
$action_id = (isset($id) ? '/'.$id : ''); // Using ternary operators here
echo form_open('admin/product/manage'.$action_id, array('class' => 'ajax-form'));
and add the id to the view data in your controller:
$data['id'] = $id;
As a side note: In order to comply with SoC (Separation of Concerns) you'd prepare all data in your controller (with e.g. models all having their own task) and pass the processed data to the view instead of partially generating data in the view itself.
I am trying to add some form to my component, but I am not shure what naming conventions must be applied to work it correctly.
Currently I have a working form - it displays fields stored in XML file and loads data from database to it. However, when i try to submit this form (edit or add new records), it doesn't work. After pressing submit (save() method) it just redirects me and displays that record was edited successfuly but it wasn't. When I try to edit existing record, after pressing submit nothing happens and when I try to add new record, it just adds empty/blank record.
So I was doing a little debug and discovered, that problem is in the JController::checkEditId() method. It always returns false which means that JControllerForm::save() returns false as well and that's why it doesn't save it correctly. HTML code of form is correct and I can access the data by using global array $_POST.
I suspect that this problem is because of naming conventions in methods loadFormData, getForm of JModelAdmin class. I am not sure how to name that form.
So here is my code related to this problem:
Subcontroller for displaying the form - controllers/slideshowform.php
class SlideshowModelSlideshowForm extends JModelAdmin{
public function getForm($data = array(), $loadData = true){
return $this->loadForm('com_slideshow.slideshowform', 'editform', array('load_data' => $loadData, 'control' => 'jform'));
}
protected function loadFormData(){
$data = JFactory::getApplication()->getUserState('com_slideshow.edit.slideshowform.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
public function getTable($table = "biometricslideshow"){
return parent::getTable($table);
}
}
views/slideshowform/view.html.php
class SlideshowViewSlideshowForm extends JView{
public function display($tmpl = null){
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
$this->form = $this->get('form');
$this->item = $this->get('item');
JToolBarHelper::save('slideshowform.save');
parent::display();
}
}
views/slideshowform/tmpl/default.php
<?php
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form method="post" action="<?php echo JRoute::_("index.php?option=com_slideshow&id=".(int) $this->item->id)?>" name="adminForm" id="slideshow-form">
<fieldset class="adminform">
<legend>Edit slide</legend>
<table>
<input type="hidden" name="task" value="">
<?php echo JHtml::_('form.token'); ?>
<?php
foreach($this->form->getFieldset() as $field){
?>
<tr><td><?php echo $field->label ?></td><td><?php echo $field->input ?></td></tr>
<?php
}
?>
</table>
</fieldset>
</form>
Can someone take o look, please?
you have to add controller SlideshowControllerSlideshowForm and code save method. In there you have to validate the form data and call SlideshowModelSlideshowForm->save event, then redirect with success/failure message.
I have a problem, i'm trying to render 2 forms (login and register) on one layout scrpt (header.phtml), every time i submit on one of the forms both actions for the controller are getting fired and i'm unsure how to fix it.
The forms are getting rendered fine within the layout, however when you click 'Login' or 'Register' on the forms the code fires in both the 'login' and 'register actions.
the header layout script snippet:-
<div class="left">
<h1>Already a member? <br>Then Login!</h1>
<?php
echo $this->action('panlogin', 'user');
?>
</div>
<div class="left right">
<h1>Not a member yet? <br>Get Registered!</h1>
<?php
echo $this->action('panregister', 'user');
?>
</div>
the action scripts (phtmls)
panregister.phtml
<div id="pan-register">
<?php
$this->registerForm->setAction($this->url);
echo $this->registerForm;
?>
</div>
panlogin.phtml
<div id="pan-login">
<?php
$this->loginForm->setAction($this->url);
?>
</div>
the user controller actions:-
class Ajfit_UserController extends Zend_Controller_Action
{
protected $_loginForm;
protected $_registerForm;
public function init()
{
$this->_loginForm = new Ajfit_Form_User_Login(array(
'action' => '/user/login',
'method' => 'post',
));
$this->_registerForm = new \Ajfit\Form\User\Registration(array(
'action' => '/user/register',
'method' => 'post'
));
}
//REGISTER ACTIONS
public function panregisterAction(){
$this->registerAction();
}
public function registerAction(){
$request = $this->_request;
if ($this->_request->isPost()){
$formData = $this->_request->getPost();
}
$this->view->registerForm = $this->_registerForm;
}
//LOGIN ACTIONS
public function panloginAction(){
$this->loginAction();
}
public function loginAction(){
$request = $this->_request;
if(!$auth->hasIdentity()){
if ($this->_request->isPost()){
$formData = $this->_request->getPost();
}
}
$this->view->loginForm = $this->_loginForm;
}
}
Please can someone with a little more knowlegde with the action('act','cont'); ?> code with in a layout script help me out with this problem.
Thanks
Andrew
While David is correct where best practices are concerned, I have on occasion just added another if() statement. Kinda like this:
if ($this->getRequest()->isPost()) {
if ($this->getRequest()->getPost('submit') == 'OK') {
just make sure your submit label is unique.
Eventually I'll get around to refactoring all those actions I built early in the learning process, for now though, they work.
Now to be nosy :)
I noticed: $formData = $this->_request->getPost(); while this works, if you put any filters on your forms retrieving the data in this manner bypasses your filters. To retrieve filtered values use $formData = $this->getValues();
from the ZF manual
The Request Object
GET and POST Data
Be cautious when accessing data from the request object as it is not filtered in any way. The router and
dispatcher validate and filter data for use with their tasks, but
leave the data untouched in the request object.
From Zend_Form Quickstart
Assuming your validations have passed, you can now fetch the filtered
values:
$values = $form->getValues();
Don't render the actions in your layout. Just render the forms:
<div class="left">
<h1>Already a member? <br>Then Login!</h1>
<?php
echo new \Ajfit\Form\User\Login(array(
'action' => '/user/login',
'method' => 'post'
));
?>
</div>
<div class="left right">
<h1>Not a member yet? <br>Get Registered!</h1>
<?php
echo new \Ajfit\Form\User\Registration(array(
'action' => '/user/register',
'method' => 'post'
));
?>
</div>
Then, whichever form gets used will post to its own action.
I'm trying to get the option item selected in a form select element using Codeigniter...
I have a controller named results with this code in it
//get form data
if($_SERVER['REQUEST_METHOD'] == "POST"){
$data['searchdata'] = array(
"ionum" => $this->input->post('ionum'),
"thisdb" => $this->input->post('thisdb')
);
}
which loads into a view, the 'ionum' is a text input which I can retrieve, the 'thisdb' is the select, I get no results for it...how do I pull that?
Ensure your html looks like:
<form action="<?= site_url('mycontroller/myfunction');?>" method='post'>
<input type='text' name='ionum'/>
<select name='thisdb'>
<option value='db1'>DB1</option>
<option value='db2'>DB2</option>
</select>
</form>
Then in your controller, you would write:
class Mycontroller extends CI_Controller{
function myfunction(){
$p = $this->input->post();
if($p){
//you can now access the ionum and thisdb... try echo
echo $p['ionum'];
echo $p['thisdb'];
}
}
}
It is unnecessary to run the if($_SERVER['REQUEST_METHOD'] == "POST") conditional. Just check if $p exists as above.