0

刚启动Yii web app,遇到了这个问题,欢迎提出建议:)

我想要实现的目标: - 要显示带有选项卡的表单,每个选项卡内容都包含来自同一模型的复选框列表。- 所以用户可以从选项卡 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();
}

任何建议将不胜感激.. :/

4

1 回答 1

0

我可能是错的,但我认为cliffbarnes 对动态嵌套的评论并没有走在正确的轨道上。据我所知,您只处理一个级别的子产品;只是这些子产品可能有多套。

在这种情况下,您找到的链接实际上提供了正确的解决方案:

<?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),因此每个字段的选定值不会覆盖另一个。就您而言,解决方案是相同的;您只需要使字段名称动态化。IE

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()and __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 对应,而不是只允许该格式的任何属性通过。

于 2013-08-06T14:35:28.697 回答