刚刚开始使用 Yii web 应用程序并遇到这个问题,欢迎任何建议:)
我想要实现的目标: - 要显示带有选项卡的表单,每个选项卡内容都包含来自同一模型的复选框列表。 - 因此用户可以从选项卡 1 中选择一些项目,从选项卡 2 中选择一些项目等,然后单击提交按钮进行处理。
问题: 但我无论如何也想不到最后一个选项卡 activecheckboxlist 不会破坏前一个选项卡。 我正在尝试类似的事情:[www.yiiframework.com/forum/index.php/topic/20388-2-checkboxlist-and-1-model]
但我的不是将其固定为 2,而是动态的。
到目前为止我做了什么:
<?php
$tabArray = array();
foreach ((Product::model()->listParentChild(0)) as $productparent) {
array_push($tabArray, array(
'label' => $productparent['name'],
'content' => CHtml::activeCheckBoxList(
$model, 'products', CHtml::listData(Product::model()->listParentChild($productparent['id']), 'id', 'name'), array(
'labelOptions' => array('style' => 'display:inline'),
'template' => '<div class="check-option">{input} {label}</div>',
'separator' => '',
)
), 'active' => ($productparent['id'] == 1 ? true : false),
));
}
?>
<?php
$this->widget('bootstrap.widgets.TbTabs', array(
'type' => 'tabs', // 'tabs' or 'pills'
'placement' => 'left',
'tabs' => $tabArray,
));
?>
在我的产品模型中:
public function listParentChild($parentid) {
$sql = "SELECT * FROM piki_product WHERE parentid=:parentid";
$productlist = Yii::app()->db->createCommand($sql);
$productlist->bindValue(":parentid", $parentid, PDO::PARAM_INT);
return $productlist->queryAll();
}
任何建议将不胜感激..:/
我可能是错的,但我不认为克利夫巴恩斯关于动态嵌套的评论走在正确的轨道上。 据我所知,您只处理一级儿童产品;只是这些子产品可能有多套。
在这种情况下,您放置的链接实际上提供了正确的解决方案:
<?php echo CHtml::checkBoxList('array1', CHtml::listData(Atributos::model()-> findAllByAttributes(array('tipo'=>'talla')), 'id_atributo','valor'))?>
<?php echo CHtml::checkBoxList('array2', CHtml::listData(Atributos::model()-> findAllByAttributes(array('tipo'=>'talla')), 'id_atributo','valor'))?>
每组复选框都有不同的名称(array1 和 array2),以便每个字段的选定值不会覆盖另一个字段。 对于您的情况,解决方案是相同的;您只需要使字段名称动态化即可。即
foreach ((Product::model()->listParentChild(0)) as $productparent) {
$fieldname = 'product' . $productparent['id'];
echo CHtml::checkBoxList($fieldname, ... (etc)
在控制器中,您将检查每个动态字段名称是否有结果。
foreach ((Product::model()->listParentChild(0)) as $productparent) {
if (isset($_POST['product' . $productparent['id']]) {
// Add values to $model->product
}
}
更好的解决方案是单独输出每个复选框,这样您就可以创建一个结果数组,并按子 ID 索引。
foreach ((Product::model()->listParentChild(0)) as $productparent) {
foreach (Product::model()->listParentChild($productparent['id']) as $child) {
CHtml::checkBox("product[{$child['id']}]", ... (etc)
然后在你的控制器中,你所要做的就是这样:
if (isset($_POST['product']) && count($_POST['product']) > 0) {
$model->product = array_keys($_POST['product']);
}
此解决方案不适用于 activeCheckBoxList()。 如果您想重写
__get()
和 __set()
魔术方法以使这些动态属性名称可用于您的模型,那么它会起作用,但这可能太过分了。
编辑(根据要求)
如果您需要为复选框设置默认选择,您可以将它们作为
CHtml::checkBoxList()
的第二个参数传递。 http://www.yiiframework.com/doc/api/1.1/CHtml#checkBoxList-detail
但是如果您仍然想使用
__get()
和 __set()
,这里有一个例子:
class YourModel extends CActiveRecord {
// I usually create a placeholder to contain the values of my virtual attribute
protected $_childValues = array();
public function __get($name) {
// The following regular expression finds attributes
// with the name product_{parent ID}
if (preg_match("/^product_\d+$/", $name)) {
// I put the underscore in the name so I could get
// parent ID easier.
list($junk, $id) = explode("_", $name);
if (!isset($this->_childValues[$id])) {
$this->_childValues[$id] = array();
}
return $this->_childValues[$id];
}
else {
// Make sure to still call the parent's __get() method
return parent::__get($name);
}
}
public function __set($name, $value) {
// Same regex as above
if (preg_match("/^product_\d+$/", $name)) {
list($junk, $id) = explode("_", $name);
$this->_childValues[$id] = $value;
}
else {
// Make sure to still call the parent's __set() method
parent::__set($name, $value);
}
}
}
$model = new YourModel;
// Any property in the format of product_{parent ID} is available
// through your model.
echo $model->product_1;
$model->product_300 = array();
您还可以考虑检查属性名称中的父 ID 是否与数据库中的父 ID 相对应,而不是只允许该格式的任何属性通过。