2013-11-22 43 views
0

我有三個表格。項目,製造和這兩個ItemManufacture的連接表。 商品有ID和商品名稱。製造商有製造ID和製造商名稱。 物品製造商有物品ID和製造ID。使用Yii連接表格的Combobox篩選器CGridview

我使用Yii的CGridView控制,以顯示與項目名稱和相應的製造商名稱該商品的所有項目。我可以使用http://www.yiiframework.com/wiki/385/displaying-sorting-and-filtering-hasmany-manymany-relations-in-cgridview/

中給出的教程成功地在網格視圖中顯示這些內容。我還可以添加文本字段過濾器,如教程中給出的。 我的問題是,我想爲製造商名稱列添加組合框過濾器。 我試圖通過添加過濾器一樣,

'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name') 

但它並沒有奏效。但適用於製造表格,無需任何連接。

然後我嘗試,

'filter'=>CHtml::activeDropDownList(Manufacture::model(),'man_name', CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name')); 

它會顯示所有名稱的組合框,但是當我選擇任何名字,它不過濾輸出。而是顯示一個空的gridview。

任何人都可以解釋發生了什麼以及如何解決它?

PS:

當我打印了CHtml ::的ListData(製造::模型() - >的findAll(), 'man_name', 'man_name')在所述控制器使用的print_r,它顯示的所有名稱制成品。

我ItemManufacture.php(型號)是

<?php 

/** 
* This is the model class for table "item_manufacture". 
* 
* The followings are the available columns in table 'item_manufacture': 
* @property integer $id 
* @property integer $item_id 
* @property integer $manu_id 
* 
* The followings are the available model relations: 
* @property Manufacture $manu 
* @property Item $item 
*/ 
class ItemManufacture extends CActiveRecord 
{ 
    public $searchManu; 
    public $searchItem; 
    /** 
    * @return string the associated database table name 
    */ 
    public function tableName() 
    { 
     return 'item_manufacture'; 
    } 

    /** 
    * @return array validation rules for model attributes. 
    */ 
    public function rules() 
    { 
     // NOTE: you should only define rules for those attributes that 
     // will receive user inputs. 
     return array(
      array('item_id, manu_id', 'required'), 
      array('item_id, manu_id', 'numerical', 'integerOnly'=>true), 
      // The following rule is used by search(). 
      // @todo Please remove those attributes that should not be searched. 
      array('id, item_id, manu_id', 'safe', 'on'=>'search'), 
     ); 
    } 

    /** 
    * @return array relational rules. 
    */ 
    public function relations() 
    { 
     // NOTE: you may need to adjust the relation name and the related 
     // class name for the relations automatically generated below. 
     return array(
      'manu' => array(self::BELONGS_TO, 'Manufacture', 'manu_id'), 
      'item' => array(self::BELONGS_TO, 'Item', 'item_id'), 
     ); 
    } 

    /** 
    * @return array customized attribute labels (name=>label) 
    */ 
    public function attributeLabels() 
    { 
     return array(
      'id' => 'ID', 
      'item_id' => 'Item ID', 
      'manu_id' => 'Manufacture ID', 
     ); 
    } 

    /** 
    * Retrieves a list of models based on the current search/filter conditions. 
    * 
    * Typical usecase: 
    * - Initialize the model fields with values from filter form. 
    * - Execute this method to get CActiveDataProvider instance which will filter 
    * models according to data in model fields. 
    * - Pass data provider to CGridView, CListView or any similar widget. 
    * 
    * @return CActiveDataProvider the data provider that can return the models 
    * based on the search/filter conditions. 
    */ 
    public function search() 
    { 
     // @todo Please modify the following code to remove attributes that should not be searched. 

     $criteria=new CDbCriteria; 

     $criteria->compare('id',$this->id); 
     $criteria->compare('item_id',$this->item_id); 
     $criteria->compare('manu_id',$this->manu_id); 
     $criteria->with = array('item', 'manu'); 
     $criteria->compare('manu.man_name', $this->searchManu->man_name, true); 
     $criteria->compare('item.item_name', $this->searchItem->item_name, true); 
     $criteria->together = true; 
     return new CActiveDataProvider($this, array(
      'criteria'=>$criteria, 
      'sort'=>array(
      'attributes'=>array(
       'manu.man_name'=>array(
        'asc'=>'manu.man_name', 
        'desc'=>'manu.man_name DESC', 
       ), 
       'item.item_name'=>array(
        'asc'=>'item.item_name', 
        'desc'=>'item.item_name DESC', 
       ), 
       '*', 
      ), 
     ), 
     )); 
    } 

    /** 
    * Returns the static model of the specified AR class. 
    * Please note that you should have this exact method in all your CActiveRecord descendants! 
    * @param string $className active record class name. 
    * @return ItemManufacture the static model class 
    */ 
    public static function model($className=__CLASS__) 
    { 
     return parent::model($className); 
    } 

    public function getOptions() 
    { 
     echo "This is output: '". $this->searchItem->item_name. "'"; 
     print_r (CHtml::activeDropDownList(Manufacture::model(),'man_name', CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name'))); 
     //return CHtml::activeDropDownList(Manufacture::model(),'man_name', CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name')); 
     //return CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name'); 
     return CHtml::dropDownList('Manufacture[man_name]', 'man_name', CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name')); 
    } 
} 

我ItemManufactureController.php是,

<?php 

class ItemManufactureController extends Controller 
{ 
    /** 
    * @var string the default layout for the views. Defaults to '//layouts/column2', meaning 
    * using two-column layout. See 'protected/views/layouts/column2.php'. 
    */ 
    public $layout='//layouts/column2'; 

    /** 
    * @return array action filters 
    */ 
    public function filters() 
    { 
     return array(
      'accessControl', // perform access control for CRUD operations 
      'postOnly + delete', // we only allow deletion via POST request 
     ); 
    } 

    /** 
    * Specifies the access control rules. 
    * This method is used by the 'accessControl' filter. 
    * @return array access control rules 
    */ 
    public function accessRules() 
    { 
     return array(
      array('allow', // allow all users to perform 'index' and 'view' actions 
       'actions'=>array('index','view'), 
       'users'=>array('*'), 
      ), 
      array('allow', // allow authenticated user to perform 'create' and 'update' actions 
       'actions'=>array('create','update'), 
       'users'=>array('@'), 
      ), 
      array('allow', // allow admin user to perform 'admin' and 'delete' actions 
       'actions'=>array('admin','delete'), 
       'users'=>array('admin'), 
      ), 
      array('deny', // deny all users 
       'users'=>array('*'), 
      ), 
     ); 
    } 

    /** 
    * Displays a particular model. 
    * @param integer $id the ID of the model to be displayed 
    */ 
    public function actionView($id) 
    { 
     $this->render('view',array(
      'model'=>$this->loadModel($id), 
     )); 
    } 

    /** 
    * Creates a new model. 
    * If creation is successful, the browser will be redirected to the 'view' page. 
    */ 
    public function actionCreate() 
    { 
     $model=new ItemManufacture; 

     // Uncomment the following line if AJAX validation is needed 
     // $this->performAjaxValidation($model); 

     if (isset($_POST['ItemManufacture'])) { 
      $model->attributes=$_POST['ItemManufacture']; 
      if ($model->save()) { 
       $this->redirect(array('view','id'=>$model->id)); 
      } 
     } 

     $this->render('create',array(
      'model'=>$model, 
     )); 
    } 

    /** 
    * Updates a particular model. 
    * If update is successful, the browser will be redirected to the 'view' page. 
    * @param integer $id the ID of the model to be updated 
    */ 
    public function actionUpdate($id) 
    { 
     $model=$this->loadModel($id); 

     // Uncomment the following line if AJAX validation is needed 
     // $this->performAjaxValidation($model); 

     if (isset($_POST['ItemManufacture'])) { 
      $model->attributes=$_POST['ItemManufacture']; 
      if ($model->save()) { 
       $this->redirect(array('view','id'=>$model->id)); 
      } 
     } 

     $this->render('update',array(
      'model'=>$model, 
     )); 
    } 

    /** 
    * Deletes a particular model. 
    * If deletion is successful, the browser will be redirected to the 'admin' page. 
    * @param integer $id the ID of the model to be deleted 
    */ 
    public function actionDelete($id) 
    { 
     if (Yii::app()->request->isPostRequest) { 
      // we only allow deletion via POST request 
      $this->loadModel($id)->delete(); 

      // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser 
      if (!isset($_GET['ajax'])) { 
       $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin')); 
      } 
     } else { 
      throw new CHttpException(400,'Invalid request. Please do not repeat this request again.'); 
     } 
    } 

    /** 
    * Lists all models. 
    */ 
    public function actionIndex() 
    { 
     $manufacture = new Manufacture('search'); 
     $manufacture->unsetAttributes(); 
     if (isset($_GET['Manufacture'])) { 
      $manufacture->attributes = $_GET['Manufacture']; 
     } 
     $item = new Item('search'); 
     $item->unsetAttributes(); 
     if (isset($_GET['Item'])) { 
      $item->attributes = $_GET['Item']; 
     } 
     $dataProvider=new CActiveDataProvider('ItemManufacture'); 
     $dataProvider->model->searchManu = $manufacture; 
     $dataProvider->model->searchItem = $item; 
     $this->render('index',array(
      'dataProvider'=>$dataProvider, 
     )); 
    } 

    /** 
    * Manages all models. 
    */ 
    public function actionAdmin() 
    { 
     $model=new ItemManufacture('search'); 
     $model->unsetAttributes(); // clear any default values 
     if (isset($_GET['ItemManufacture'])) { 
      $model->attributes=$_GET['ItemManufacture']; 
     } 

     $this->render('admin',array(
      'model'=>$model, 
     )); 
    } 

    /** 
    * Returns the data model based on the primary key given in the GET variable. 
    * If the data model is not found, an HTTP exception will be raised. 
    * @param integer $id the ID of the model to be loaded 
    * @return ItemManufacture the loaded model 
    * @throws CHttpException 
    */ 
    public function loadModel($id) 
    { 
     $model=ItemManufacture::model()->findByPk($id); 
     if ($model===null) { 
      throw new CHttpException(404,'The requested page does not exist.'); 
     } 
     return $model; 
    } 

    /** 
    * Performs the AJAX validation. 
    * @param ItemManufacture $model the model to be validated 
    */ 
    protected function performAjaxValidation($model) 
    { 
     if (isset($_POST['ajax']) && $_POST['ajax']==='item-manufacture-form') { 
      echo CActiveForm::validate($model); 
      Yii::app()->end(); 
     } 
    } 
} 

而我的看法是

<?php 
/* @var $this ItemManufactureController */ 
/* @var $dataProvider CActiveDataProvider */ 
?> 

<?php 
$this->breadcrumbs=array(
    'Item Manufactures', 
); 

$this->menu=array(
    array('label'=>'Create ItemManufacture','url'=>array('create')), 
    array('label'=>'Manage ItemManufacture','url'=>array('admin')), 
); 
?> 

<h1>Item Manufactures</h1> 

<?php 
    $this->widget('bootstrap.widgets.TbGridView', array(
    'dataProvider' => $dataProvider->model->search(), 
    'type'=>'striped bordered condensed', 
    'pager'=>array(
     'maxButtonCount'=>'7', 
    ), 
    'filter'=>$dataProvider->model, 
    'pager'=>array 
    (
     'pageSize' => 50, 
    ), 
    'columns' => array 
    (
     'id', 
     array 
     (
      'name' => 'manu.man_name', 
      //'filter' => CHtml::activeTextField($dataProvider->model->searchManu, 'man_name'), 
      //'filter'=>CHtml::listData($dataProvider->model->searchManu, 'man_name', 'man_name') 
      //'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name') 
      //'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name') 
      //'filter'=>Manufacture::model()->manufactureNames 
      //'filter'=>ItemManufacture::model()->options 
      //'filter'=>Manufacture::model()->options 
      'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'man_id', 'man_name') 
      //'filter'=>CHtml::dropDownList('Manufacture[man_name]', 'manu.man_name', array_merge (array(''=>''), CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name'))) 
      //'filter'=>CHtml::activeDropDownList($dataProvider->model,'manu_id', CHtml::listData(Manufacture::model()->findAll(), 'man_name', 'man_name')) 
     ), 
     array 
     (
      'name' => 'item.item_name', 
      'filter' => CHtml::activeTextField($dataProvider->model->searchItem, 'item_name'), 
     ), 
     array 
     (
      'header' => 'Actions', 
      'class'=>'bootstrap.widgets.TbButtonColumn', 
     ), 
    ), 
    )); 
?> 

回答

0

的cHTML第二個參數:: listData是valueField,它應該是id如果是forei gn鍵。試試這個:

'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'id', 'man_name') 

UPD

而且,你的字段名稱是manu_id。所以,右場將是:

array 
(
    'name' => 'manu_id', 
    'filter'=>CHtml::listData(Manufacture::model()->findAll(), 'man_id', 'man_name') 
), 
+0

我也試過這種方式。但它沒有顯示組合。 – Harikrishnan

+0

製造表的ID字段被命名爲「id」還是「man_id」? – A3a

+0

是的,這是man_id和我一起都測試過,仍然沒有希望 – Harikrishnan