我希望使用装饰器将表格格式化为以下Zend_Form,将描述放在第一列和第二列中的Zend_Form_Element_Radio选项和在每行中添加2 select ,如稍后在html示例中所示。
我需要一个具体/有效的例子。
FORM
class My_Form extends Zend_Form
{
const KIND_1 = 'dineer1';
const KIND_2 = 'dineer2';
const KIND_3 = 'dineer3';
const KIND_4 = 'dineer4';
const KIND_5 = 'dineer5';
const KIND_6 = 'dineer6';
public static $KINDS = array(
1 => self::KIND_1,
2 => self::KIND_2,
3 => self::KIND_3,
4 => self::KIND_4,
5 => self::KIND_5,
6 => self::KIND_6,
);
const DRINK_C = 'c';
const DRINK_M = 'm';
const DRINK_W = 'w';
public static $DRINKS = array(
self::DRINK_C => "cole",
self::DRINK_M => "milk",
self::DRINK_W => "water",
);
const FOOD_B = 'b';
const FOOD_F = 'f';
const FOOD_M = 'm';
const FOOD_P = 'p';
const FOOD_V = 'v';
const FOOD_W = 'w';
public static $FOODS = array(
self::FOOD_B => "burger",
self::FOOD_F => "fruit",
self::FOOD_M => "Meat",
self::FOOD_P => "pizza",
self::FOOD_V => "vegetables",
self::FOOD_W => "Wursterl",
);
public function init()
{
$_please_select = array("" => " please select ");
$this->setMethod(Zend_Form::METHOD_POST);
$input_lunch = new Zend_Form_Element_Radio('lunch');
$input_lunch ->setMultiOptions(self::$KINDS) ;
$this->addElement($input_lunch );
foreach (self::$KINDS as $k => $_descriprion) {
$input_drink = new Zend_Form_Element_Select('drink_' . $k);
$input_drink->addMultiOptions(self::$DRINKS);
$input_food = new Zend_Form_Element_Select('food_' . $k);
$input_food->addMultiOptions($_please_select)
->addMultiOptions(self::$FOODS);
$this->addElement($input_drink);
$this->addElement($input_food);
}
}
}
预期的HTML
<html>
<body>
<form action="/" method="POST">
<table>
<thead>
<tr>
<th></td>
<th>kind</td>
<th>drink</td>
<th>food</td>
</tr>
</thead>
<tbody>
<tr>
<td>Description row 1</td>
<td><input type="radio" name="lunch" value "dinner1"></td>
<td>
<select name="drink_1">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_1">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
<tr>
<td>Description row 2</td>
<td><input type="radio" name="lunch" value "dinner2"></td>
<td>
<select name="drink_2">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_2">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
<tr>
<td>Description row 3</td>
<td><input type="radio" name="lunch" value "dinner3"></td>
<td>
<select name="drink_3">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_3">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
<tr>
<td>Description row 4</td>
<td><input type="radio" name="lunch" value "dinner4"></td>
<td>
<select name="drink_4">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_4">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
<tr>
<td>Description row 5</td>
<td><input type="radio" name="lunch" value "dinner5"></td>
<td>
<select name="drink_5">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_5">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
<tr>
<td>Description row 6</td>
<td><input type="radio" name="lunch" value "dinner6"></td>
<td>
<select name="drink_6">
<option value="w">Water</option>
<option value="m">Milk</option>
<option value="b">Beer</option>
</select>
</td>
<td>
<select name="food_6">
<option value="">please select</option>
<option value="b">Burger</option>
<option value="f">Fruit</option>
<option value="m">Meat</option>
<option value="p">Pizza</option>
<option value="v">Vegetable</option>
<option value="w">Wurstel</option>
</select>
</td>
</tr>
</tbody>
<table>
</form>
</body>
</html>
答案 0 :(得分:1)
这可能不是完美的解决方案,但它可能对您有所帮助!
class My_Form extends Zend_Form
{
const KIND_1 = 'dineer1';
const KIND_2 = 'dineer2';
const KIND_3 = 'dineer3';
const KIND_4 = 'dineer4';
const KIND_5 = 'dineer5';
const KIND_6 = 'dineer6';
public static $KINDS = array(
1 => self::KIND_1,
2 => self::KIND_2,
3 => self::KIND_3,
4 => self::KIND_4,
5 => self::KIND_5,
6 => self::KIND_6,
);
const DRINK_C = 'c';
const DRINK_M = 'm';
const DRINK_W = 'w';
public static $DRINKS = array(
self::DRINK_C => "cole",
self::DRINK_M => "milk",
self::DRINK_W => "water",
);
const FOOD_B = 'b';
const FOOD_F = 'f';
const FOOD_M = 'm';
const FOOD_P = 'p';
const FOOD_V = 'v';
const FOOD_W = 'w';
public static $FOODS = array(
self::FOOD_B => "burger",
self::FOOD_F => "fruit",
self::FOOD_M => "Meat",
self::FOOD_P => "pizza",
self::FOOD_V => "vegetables",
self::FOOD_W => "Wursterl",
);
public function init()
{
$_please_select = array("" => " please select ");
$this->setMethod(Zend_Form::METHOD_POST);
$this->setDisableLoadDefaultDecorators(true);
$countRows = count(self::$KINDS)+1;
foreach (self::$KINDS as $k => $_descriprion) {
$rowForm = new Zend_Form_SubForm();
$input_lunch = new Zend_Form_Element_Radio('lunch',
array('disableLoadDefaultDecorators' => true,
'label' => 'kind',
'label_placement' => 'prepend'));
$input_lunch ->setMultiOptions(self::$KINDS) ;
$input_lunch->addDecorators(array(
array('ViewHelper'),
array('Label',
array('style' => 'display:block;font-weight:bold', // just for this example
'placement'=>'PREPEND',
'tag'=>'span', //if you want to use other tag
'disableFor'=>true)
),
array(array('data' => 'HtmlTag'), array('tag' => 'td', 'rowspan' => $countRows )),
));
$this->addElement($input_lunch);
// add label just for the first element
$drinkLabel = array('disableLoadDefaultDecorators' =>true);
$drinkDecorators = array(
array('ViewHelper'),
array(array('data' => 'HtmlTag'), array('tag' => 'td')),
);
if ($k == 1) {
$drinkLabel['label'] = 'drink';
$drinkDecorators = array(
array('ViewHelper'),
array('Label',
array('style' => 'display:block;font-weight:bold',
'placement'=>'PREPEND',
'tag'=>'span', //if you want to use other tag
'disableFor'=>true)
),
array(array('data' => 'HtmlTag'), array('tag' => 'td')),
);
}
$input_drink = new Zend_Form_Element_Select('drink', $drinkLabel);
$input_drink->addMultiOptions(self::$DRINKS);
$input_drink->addDecorators($drinkDecorators);
$input_food = new Zend_Form_Element_Select('food', $drinkLabel);
$input_food->addMultiOptions($_please_select)
->addMultiOptions(self::$FOODS);
$input_food->addDecorators($drinkDecorators);
$rowForm->addElement($input_drink);
$rowForm->addElement($input_food);
$rowForm->setSubFormDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'tr')),
));
$rowForm->setDisableLoadDefaultDecorators(true);
$this->addSubForm($rowForm, 'row_' . $k);
}
$this->setSubFormDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'tr')),
));
$this->setDecorators(array(
'FormElements',
array('HtmlTag', array('tag' => 'table')),
'Form'
));
}
}
此外,这里有一些资源可以使用表和Zend Form
http://www.packtpub.com/article/create-shopping-cart-using-zend-framework-2 http://davidcaylor.com/2008/03/24/building-table-based-forms-in-zend_form/ http://blog.kosev.net/2010/06/tutorial-create-zend-framework-form.html
答案 1 :(得分:1)
我会建议基于此答案的解决方案https://stackoverflow.com/a/8451723/212940
你的表格: -
class My_Form extends Zend_Form
{
const KIND_1 = 'dineer1';
const KIND_2 = 'dineer2';
const KIND_3 = 'dineer3';
const KIND_4 = 'dineer4';
const KIND_5 = 'dineer5';
const KIND_6 = 'dineer6';
public static $KINDS = array(
1 => self::KIND_1,
2 => self::KIND_2,
3 => self::KIND_3,
4 => self::KIND_4,
5 => self::KIND_5,
6 => self::KIND_6,
);
const DRINK_C = 'c';
const DRINK_M = 'm';
const DRINK_W = 'w';
public static $DRINKS = array(
self::DRINK_C => "cole",
self::DRINK_M => "milk",
self::DRINK_W => "water",
);
const FOOD_B = 'b';
const FOOD_F = 'f';
const FOOD_M = 'm';
const FOOD_P = 'p';
const FOOD_V = 'v';
const FOOD_W = 'w';
public static $FOODS = array(
self::FOOD_B => "burger",
self::FOOD_F => "fruit",
self::FOOD_M => "Meat",
self::FOOD_P => "pizza",
self::FOOD_V => "vegetables",
self::FOOD_W => "Wursterl",
);
public function init()
{
$this->addDecorators(
array(
array('ViewScript', array('viewScript' => 'forms/_form_test.phtml'))
)
); //added as part of answer. Note all default decorators are still available.
$_please_select = array("" => " please select ");
$this->setMethod(Zend_Form::METHOD_POST);
$input_lunch = new Zend_Form_Element_Radio('lunch');
$input_lunch ->setMultiOptions(self::$KINDS) ;
$this->addElement($input_lunch );
foreach (self::$KINDS as $k => $_descriprion) {
$input_drink = new Zend_Form_Element_Select('drink_' . $k);
$input_drink->addMultiOptions(self::$DRINKS);
$input_food = new Zend_Form_Element_Select('food_' . $k);
$input_food->addMultiOptions($_please_select)
->addMultiOptions(self::$FOODS);
$this->addElement($input_drink);
$this->addElement($input_food);
}
$this->setElementDecorators(array('ViewHelper'));//added as part of answer
}
}
正如您所看到的,只需要进行两处小改动
然后,您需要创建包含以下内容的文件scripts/forms/_form_test.phtml
: -
<form
id='contact'
action='<?php echo $this->element->getAction(); ?>'
method='<?php echo $this->element->getMethod(); ?>'
>
<table>
<thead>
<tr>
<th></td>
<th>kind</td>
<th>drink</td>
<th>food</td>
</tr>
</thead>
<tbody>
<?php
$elements = $this->element->getElements();
$options = $this->element->lunch->getMultiOptions();
foreach($options as $key => $option){
echo "<tr>\n";
echo "<td>Description row $key</td>\n";
echo "<td><input type='radio' name='lunch' value='$option'</td>\n";
echo "<td>{$elements['drink_' . $key]}</td>\n";
echo "<td>{$elements['food_' . $key]}</td>\n";
echo "</tr>\n";
}
?>
</tbody>
<table>
</form>
文件_form_test.phtml
实际上是渲染表单的装饰器。这是一种使用Zend_Form的非常灵活的方式,我通过阅读this article here
此方法仍然可以使用默认装饰器,例如“错误”。
在我的系统上,我得到了你要求的确切html输出。试试吧,看看。
答案 2 :(得分:0)
在我看来,你无法用视图助手做你想做的事情!
您应该进行自定义表单打印,例如:
<form action="/" method="POST">
<table>
<thead>
<tr>
<th></th>
<th>kind</th>
<th>drink</th>
<th>food</th>
</tr>
</thead>
<tbody>
<?for ($i = 1; $i <= 6; $i++) : ?>
<?
$drink = 'drink_' . $i;
$food = 'food_' . $i;
?>
<tr>
<td>Description row <?=$i?></td>
<td>
<?=$this->form->$drink?>
</td>
<td>
<?=$this->form->$food?>
</td>
</tr>
<? endfor;?>
</tbody>
</table>
</form>
lunch
对于这个领域,不可能像你问的那样使用它,你应该想到另一种策略。目前我能想到的!
答案 3 :(得分:0)
那么我的答案版本。
进入 init 我在表单中添加了自定义装饰器 RadioTable ,并在前缀路径中加载了装饰器
然后我将所有元素装饰成普通表,这很重要,因为我所有的努力都是为了保持标准装饰者提供的设施,如“错误”
请注意 Custom_Form_Element_FirstSelect 以及无线电元素中的 - &gt; setSeparator
我还添加了提交按钮
public function init()
{
$_please_select = array("" => " please select ");
// I add a my custom decorator
$this->addPrefixPath('Custom_Form_Decorator',
'Custom/Form/Decorator',
'decorator');
$this->setMethod(Zend_Form::METHOD_POST);
$input_lunch = new Zend_Form_Element_Radio('lunch');
$input_lunch ->setMultiOptions(self::$KINDS)
->setSeparator("\t__RADIO_SEPARATOR__\t") //set custom separator I'll use in custom decorator
->setDecorators(array(
'ViewHelper', // add a standard decorator
'Label', // I'll use the label decorator to show text
));
$this->addElement($input_lunch );
foreach (self::$KINDS as $k => $_description) {
// to "mark" the first select I extend the Zend_Form_Element_Select
// with Custom_Form_Element_FirstSelect
$input_drink = new Custom_Form_Element_FirstSelect('drink_' . $k);
$input_drink->addMultiOptions(self::$DRINKS)
->setDecorators(array(
'ViewHelper', // add a standard decorator
array(array('data' => 'HtmlTag'),array('tag' => 'td')), // add a standard decorator
));
$input_food = new Zend_Form_Element_Select('food_' . $k);
$input_food->addMultiOptions($_please_select)
->addMultiOptions(self::$FOODS)
->setDecorators(array(
'ViewHelper',
array(array('data' => 'HtmlTag'),array('tag' => 'td')),
));
$this->addElement($input_drink);
$this->addElement($input_food);
}
// add a the submit button
$submit = new Zend_Form_Element_Submit('submit');
$submit->setLabel('SUBMIT');
$submit->setDecorators(array(
'ViewHelper',
'Errors',
array(array('data' => 'HtmlTag'), array('tag' => 'td', )),
array(array('row' => 'HtmlTag'), array('tag' => 'tr')),
));
$this->addElement($submit);
// add the custom decorators to the whole form
$this->setDecorators(array(
'RadioTable',
array('HtmlTag', array('tag' => 'table', )),
'Form'
));
}
Custom_Form_Element_FirstSelect
class Custom_Form_Element_FirstSelect extends Zend_Form_Element_Select{
}
Custom_Form_Decorator_RadioTable
class Custom_Form_Decorator_RadioTable extends Zend_Form_Decorator_Abstract {
public function render($content){
$wrap = '';
// I'll take the element
$radioElement = $this->getElement()->getElement('lunch');
// then I render it and explode in array using the separator
$arrayRadio = explode("\t__RADIO_SEPARATOR__\t", $radioElement->__toString());
$count = 0;
$arrayElement = $this->getElement()->getElements();
// loop on all form elements and I render them
foreach ($arrayElement as $keyForm => $element){
// I skip the radio element
if($element instanceof Zend_Form_Element_Radio){
continue;
}
if($element instanceof Custom_Form_Element_FirstSelect ){
// when I found the custom select element I'll prefix with "open-row-tag" and radio button in column
$wrap .= "<tr>". "<td>". $arrayRadio[$count++] . "</td>" . $element->__toString();
// note that the select elements are already decorated
} else if($element instanceof Zend_Form_Element_Select){
// after the last select I close the row
$wrap .= $element->__toString() ."</tr>";
}
if($element instanceof Zend_Form_Element_Submit){
// add the SUBMIT button
$wrap .= $element->__toString() ;
}
}
return $content.$wrap;
}
}
当然我可以使用元素的名称而不是使用自定义元素类来打开表格行,但这样我感觉更灵活。