2013-08-06 45 views
0

剛剛開始了Yii的Web應用程序,並遇到了這個問題,有什麼建議,歡迎:)的Yii:多activeCheckboxlist與同型號

什麼,我想實現: - 要顯示與選項卡的形式,每個選項卡內容包含來自同一模型的複選框列表。 -so用戶可以從標籤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(); 
} 

任何建議,將感激..:/

+0

這不是一個Yii的東西,更多的是軟件架構的一般東西 - 動態嵌套的常見問題。所以,首先,你的數據庫結構如何?爲什麼 - 如果這是你想要做的 - 你是否沒有爲子 - 父關係創建單獨的關係數據庫表。接下來,您將不得不在控制器中編寫一個方法來首先對數據中存在的父子層次結構進行排序和設置。那麼你可以創建UI。這就是你以後的事,對吧? – cliffbarnes

+0

我沒有額外的子女 - 父母關係表。稍後我會補充說明一下。 但是再一次,這將如何使我能夠更新一個具有多個activecheckboxlist的模型? – Kengary

+0

是的,我不知道你必須這樣做,但是當構建動態嵌套列表時,這是一種常見的做法。關鍵是你的控制器上的方法將對記錄進行排序並對它們進行分類。這是困難的部分。關係表的部分原因 - 在進行這些計算時無需混淆全部數據表。 – cliffbarnes

回答

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'))?> 

每個組複選框被賦予了不同的名稱(數組1和數組2),使每個字段的選定值不重寫另一個。在你的情況下,解決方案是一樣的;你只需要使字段名稱動態。 I.E.

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對應,而不僅僅是允許該格式的任何財產通過。

+0

您好艾恩,感謝您的建議。你能不能粗略分享我將如何重寫'魔術'方法? 原因是我可能無法使用您提到的2種方法,因爲某些複選框已經過預先檢查。但我會先試一試,因爲我已經想不出其他方法了。 – Kengary

+0

請參閱上面對我的回答的編輯。 – ethan

+0

我根據你的建議使用了CHtml :: checkBoxList(),並得到了一些工作。非常感謝!猜猜我接下來要做一些優化工作,因爲我總共有3個嵌套for循環用於這個功能,它甚至會在本地主機上放慢速度。看到你身邊! – Kengary