来自另一个 table yii2 的复选框并保留选中的值

Checkboxes from another table yii2 and retaining checked values

我有三张表

--
-- Table structure for table `tbl_ticket`
--

CREATE TABLE IF NOT EXISTS `tbl_ticket` (
`id` int(9) NOT NULL,
  `complain_id` varchar(250) CHARACTER SET latin1 NOT NULL,
  `section_id` varchar(250) CHARACTER SET latin1 NOT NULL,
  `location_id` varchar(250) CHARACTER SET latin1 NOT NULL,
  `status` varchar(250) CHARACTER SET latin1 NOT NULL,
  `remarks` varchar(250) CHARACTER SET latin1 NOT NULL,
  `r_date` datetime NOT NULL,
  `d_date` datetime NOT NULL,
  `hd_user_username` varchar(250) CHARACTER SET latin1 NOT NULL,
  `hd_user_email` varchar(250) CHARACTER SET latin1 NOT NULL,
  `description` varchar(250) NOT NULL,
  `attachment` varchar(250) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_ticket`
--
ALTER TABLE `tbl_ticket`
 ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_ticket`
--
ALTER TABLE `tbl_ticket`
MODIFY `id` int(9) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;

--
-- Table structure for table `tbl_ticket_complain`
--

CREATE TABLE IF NOT EXISTS `tbl_ticket_complain` (
`id` int(9) NOT NULL,
  `ticket_id` varchar(250) NOT NULL,
  `complain_id` varchar(250) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_ticket_complain`
--
ALTER TABLE `tbl_ticket_complain`
 ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_ticket_complain`
--
ALTER TABLE `tbl_ticket_complain`
MODIFY `id` int(9) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;

   --
-- Table structure for table `tbl_complain_type`
--

CREATE TABLE IF NOT EXISTS `tbl_complain_type` (
`id` int(9) NOT NULL,
  `section_id` varchar(250) NOT NULL,
  `complains` varchar(250) NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `tbl_complain_type`
--
ALTER TABLE `tbl_complain_type`
 ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `tbl_complain_type`
--
ALTER TABLE `tbl_complain_type`
MODIFY `id` int(9) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=20;

我想显示 tbl_complain_type 的内容,即 id 和 complains 在视图中显示为复选框。 tbl_ticket 将有多个 tbl_complain_type.id as values and this is related through the table tbl_ticket_complain .ticket_id =tbl_ticket.id 。如何在 Yii2 视图中为 CRUD 完成此操作?

在控制器中,我已经像这样创建了 actionCreate

$model = new Ticket();
        $ticket_complain=new TicketComplain();
        $complain_type=ComplainType ::find ()->all();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
                    'complain_type'=>$complain_type,
                    'ticket_complain'=>$ticket_complain
            ]);
        }

并在视图中将它们显示为复选框 我添加了这样的代码

<?php 

$model->complains = $complain_type;

$list = $complain_type;

$options = \yii\helpers\ArrayHelper::map($list, 'id', 'complains');


echo $form->field($model, 'complains')->checkboxList($options);

?>

我面临的问题是保留复选框值和保存/更新值。另外我不确定是否使用 checkBox 而不是 checkboxList ,即

$complains = [];
      if($complain_type ) {
         foreach($complain_type  as $complain) {
             $complains[] = $complain->complains;
             $id[]= $complain->id;
             echo $form->field($ticket_complain, 'id')
             ->checkBox(['label' => $complain->complains, 'uncheck' => null, 'selected' => true]);
         }
      }

或者让我简化一下

如何将模型值设置为从数据库中选择的复选框,并在提交时基于提交的值?

三个表之间的关系可以通过这个sql

来说明
SELECT  `tbl_ticket`.* , tbl_complain_type.complains  FROM tbl_ticket JOIN
tbl_ticket_complain ON tbl_ticket.id =tbl_ticket_complain.ticket_id JOIN
tbl_complain_type ON tbl_complain_type.id=tbl_ticket_complain.complain_id

在模型\app\models\Ticket.php中添加以下变量,

class Ticket extends \yii\db\ActiveRecord
{
    public $complains_field; //A custom variable to hold the value of checkboxlist

    /*Remaining contents of Ticket model */

    public function rules()
    {
        return [
            [['complains_field'], 'safe']
        ];
    }

    public function getComplains() //Relation between ticket & ticket_complain table
    {
        return $this->hasMany(TicketComplain::className(), ['ticket_id' => 'id']);
    }

    public function afterSave($insert, $changedAttributes){
        \Yii::$app->db->createCommand()->delete('tbl_ticket_complain', 'ticket_id = '.(int) $this->id)->execute(); //Delete existing value
        foreach ($this->complains_field as $id) { //Write new values
            $tc = new TicketComplain();
            $tc->ticket_id = $this->id;
            $tc->complain_id = $id;
            $tc->save();
        }
    }
}

在控制器上的 actionCreate() 中

$model = new Ticket();
$complain_type= ComplainType::find()->all();

if ($model->load(Yii::$app->request->post()) && $model->save()) {
    return $this->redirect(['view', 'id' => $model->id]);
} 
else {
    return $this->render('create', [
        'model' => $model,
        'complain_type'=>$complain_type
    ]);
}

在控制器上的 actionUpdate() 中

$model = $this->findModel($id);
$complain_type = ComplainType::find()->all();

//Retrieve the stored checkboxes
$model->complains_field = \yii\helpers\ArrayHelper::getColumn(
    $model->getComplains()->asArray()->all(),
    'complain_id'
);

if ($model->load(Yii::$app->request->post()) && $model->save()) {
    return $this->redirect(['view', 'id' => $model->id]);
} 
else {
    return $this->render('create', [
        'model' => $model,
        'complain_type'=>$complain_type
    ]);
}

在视图中

<?php 
$options = \yii\helpers\ArrayHelper::map($complain_type, 'id', 'complains');
echo $form->field($model, 'complains_field')->checkboxList($options, ['unselect'=>NULL]);
?>

控制器中的所有逻辑都移到了模型中。在控制器中只需要做 load() 和 save()


/**
* special for form extend model. No good practice automatically load checkbox 
* records for each loaded model.
*/
class CwbrForm extends Cwbr
{

    /** @var int[] */
    public $chkList = [];
    public $oldchkList;

    public function rules()
    {
        return array_merge(parent::rules(),[
            ['chkList', 'each', 'rule' => ['integer']]
        ]);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getCwbrChk()
    {
        return $this->hasMany(CwbrChk::className(), ['cwbr_ide_id' => 'id']);
    }

    public function load($data, $formName = null)
    {
        $this->oldchkList = $this->chkList;
        if(!parent::load($data, $formName)){
            return false;
        }
        if(!$this->chkList){
            $this->chkList = [];
        }
        return true;
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        foreach(array_diff($this->chkList,$this->oldChkList) as $newChkId){
            $chk = new CwbrChk();
            $chk->cwbr_id = $this->id;
            $chk->chk_id = $newChkId;
            $chk->save();
        }

        CwbrChk::deleteAll([
            'chk_id' => array_diff($this->oldChkList,$this->chkList),
            'cwbr_id' => $this->id
        ]);

    }

    public function afterFind()
    {
        parent::afterFind();
        $this->chkList = ArrayHelper::getColumn($this->cwbrChk,'chk_id', false);
    }
}

查看

$options = [1 => 'One', 2 => 'Two'];
echo $form->field($model, 'chkList')->checkboxList($options, ['unselect'=>NULL]);