Yii (CHtml::checkBoxList храним состояние в базе)

Большое спасибо ему
Пойдем по шагам.
1. Создаем таблицы в базе
вот дамп
//
--
-- Current Database: `localdb`
--

/*!40000 DROP DATABASE IF EXISTS `%s` */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `localdb` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `localdb`;

-- MySQL dump 10.13  Distrib 5.6.22, for Win32 (x86)
--
-- Host: localhost    Database: localdb
-- ------------------------------------------------------
-- Server version   5.5.41-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `dep_user`
--

DROP TABLE IF EXISTS `dep_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `dep_user` (
  `du_id` int(11) NOT NULL AUTO_INCREMENT,
  `dep_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`du_id`) USING BTREE,
  UNIQUE KEY `du_id_UNIQUE` (`du_id`),
  KEY `fk_t_dep_has_t_user_t_user1_idx` (`user_id`),
  KEY `fk_t_dep_has_t_user_t_dep_idx` (`dep_id`),
  CONSTRAINT `fk_t_dep_has_t_user_t_dep` FOREIGN KEY (`dep_id`) REFERENCES `t_dep` (`d_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_t_dep_has_t_user_t_user1` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`u_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `dep_user`
--

LOCK TABLES `dep_user` WRITE;
/*!40000 ALTER TABLE `dep_user` DISABLE KEYS */;
INSERT INTO `dep_user` VALUES (3,1,1);
/*!40000 ALTER TABLE `dep_user` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `t_dep`
--

DROP TABLE IF EXISTS `t_dep`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_dep` (
  `d_id` int(11) NOT NULL AUTO_INCREMENT,
  `d_name` varchar(45) NOT NULL,
  PRIMARY KEY (`d_id`),
  UNIQUE KEY `d_id_UNIQUE` (`d_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `t_dep`
--

LOCK TABLES `t_dep` WRITE;
/*!40000 ALTER TABLE `t_dep` DISABLE KEYS */;
INSERT INTO `t_dep` VALUES (1,'root'),(2,'library');
/*!40000 ALTER TABLE `t_dep` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `t_user`
--

DROP TABLE IF EXISTS `t_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_user` (
  `u_id` int(11) NOT NULL AUTO_INCREMENT,
  `u_name` varchar(45) NOT NULL,
  PRIMARY KEY (`u_id`),
  UNIQUE KEY `u_id_UNIQUE` (`u_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `t_user`
--

LOCK TABLES `t_user` WRITE;
/*!40000 ALTER TABLE `t_user` DISABLE KEYS */;
INSERT INTO `t_user` VALUES (1,'master'),(2,'master2');
/*!40000 ALTER TABLE `t_user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2015-03-08 13:33:10
//
2. Создаем модели\круд
3. Устанавливаем   EAdvancedArBehavior.
4. В модели указываем отношения
//
    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(
                         'user_dep' => array(self::MANY_MANY, 'Myuser', 'dep_user(dep_id , user_id)')
                //user_dep - название связи, одинаково у обеих таблиц
                //Myuser - название связанной модели 
                //dep_user - название сводной таблицы
                //dep_id - ид  из связной таблицы (здесь хранится ключ на текущую модель) ИДЕТ ПЕРВЫМ
                //user_id - ид  из связной таблицы (здесь хранится ключ на связную модель)
        );
    }
//
5.указываем поведение
//
    public function behaviors()
    {
        return array('EAdvancedArBehavior' =>
            array('class' => 'application.components.EAdvancedArBehavior'));
    }
 //
6.на данном этапе можно проверить работает ли связь
//
<?php
  $Ids = array(1, 2); // список id добавляемых
  $engin = Dep::model()->findByPk(1); // загрузили текущий отдел 
  $detail = Myuser::model()->findAllByPk($Ids); // загрузили юзеров
  $engin->user_dep = $detail; // привязали юзеров к отделу
  if ($engin->save()) echo 'lol';
  else echo 'bad'; 
?> 

//
7. если все ок то создаем чекбокслист в _form. вида Dep
//
    <div class="row">
        <?php echo CHtml::label('юзеры', 'IM'); ?>
        <?php
        $type_list = CHtml::listData(Myuser::model()->findAll(), 'u_id', 'u_name');
        
        $arr = DepUser::model()->findAll();
        if (is_array($arr))
        {
            for ($i = 0; $i < count($arr); $i++)
            {
                $arr_bit[] = $arr[$i]->user_id;
            }
        }
        else
            $arr_bit = array();

        echo CHtml::checkBoxList('im_id', $arr_bit, $type_list, array(
            'template' => '{input} {labelTitle}',
            'class' => 'chclass',
                )
        ); //просто рисуем чекбокслитс из базы
        ?> 
    </div>
 //
8. в DepController прописываем поведение при сохранении
//
if (isset($_POST['Dep']))
{
    $model->attributes = $_POST['Dep'];
    if ($model->save())
    {

        if (isset($_POST['im_id']))
        {
            foreach ($_POST['im_id'] as $check)
            {

                $Ids = $_POST['im_id'];
            }
            $engin = Dep::model()->findByPk(1); // загрузили текущий отдел 
            $detail = Myuser::model()->findAllByPk($Ids); // загрузили юзеров
            $engin->user_dep = $detail; // привязали юзеров к отделу
            $engin->save();
            //  
        }
        else
        {
            $Ids = array();
            $engin = Dep::model()->findByPk(1); // загрузили текущий отдел 
            $detail = Myuser::model()->findAllByPk($Ids); // загрузили юзеров
            $engin->user_dep = $detail; // привязали юзеров к отделу
            $engin->save();
        }
    }
    //
    $this->redirect(array('view', 'id' => $model->d_id));
}

$this->render('update', array(
    'model' => $model,
));
}
//
9.вот и все. вопросы оставляйте в комментариях
10.исходники

2 способ


наверно не очень правильный.
ну тут я себе задачу усложнил несколько
 Получим список из базы

    <?php echo CHtml::label('страницы', 'complect'); ?>
    <?php
    $connection = Yii::app()->db2;
    $sql = '
    WITH RECURSIVE temp1 ( p_id,p_parent,p_title,PATH, LEVEL, NAME  ) AS (
    SELECT T1.p_id,T1.p_parent, T1.p_title, CAST (T1.p_id AS VARCHAR (50)) as PATH, 1 , 
    CAST (T1.p_title AS VARCHAR (255)) as NAME
        FROM "SC_Wonder".t_page T1 WHERE T1.p_parent = 0
    union
    select T2.p_id, T2.p_parent, T2.p_title, CAST ( temp1.PATH ||\'->\'|| T2.p_id AS VARCHAR(50)) ,LEVEL + 1 ,
    CAST ((repeat(\' _ \', LEVEL+1)||T2.p_title) AS VARCHAR(255))
         FROM "SC_Wonder".t_page T2 INNER JOIN temp1 ON( temp1.p_id= T2.p_parent))
    select * from temp1 ORDER BY PATH LIMIT 100  
    ';
    $dataReader = $connection->createCommand($sql)->query();
    $rows = $dataReader->readAll();
    for ($i = 0; $i < count($rows); $i++)
    {
        $type_list[$rows[$i]['p_id']] = $rows[$i]['name'];
        $id_pid[$rows[$i]['p_id']] = $rows[$i]['p_parent'];
        $pid[$rows[$i]['p_parent']][] = [$rows[$i]['p_id']];
    }
    $pid = json_encode($pid);
    $sum = json_encode($id_pid);
    if (isset($model->u_id))
    {
        $arr = Userpage::model()->findAll("id_user=:id", array(':id' => $model->u_id));
    }
    if (isset($arr))
    {
        for ($i = 0; $i < count($arr); $i++)
        {
            $arr_bit[] = $arr[$i]->id_page;
        }
    }
    else
        $arr_bit = array();
    ?>
..
здесь рекурсивный запрос чтобы отобразить страницы по уровням. а также формирование массива для js и прокликивание чекбоксов, которые есть в базе

затем добавляем немного динамики. в принципе блок экспериментальный, можно делать без него
    <script>
        var name = '<?php echo $sum ?>';
        var name2 = eval("(" + name + ")");
        var buf = new Array();
        var pid2 = '<?php echo $pid ?>';
        var pid = eval("(" + pid2 + ")");

        tagList = document.getElementsByName("im_id[]");

        function parent($id, $this)
        {
            if (document.getElementById(buf[$id])
                    && document.getElementById(buf[$id]).checked == false
                    && document.getElementById(buf[$this]).checked == true)
            {
                document.getElementById(buf[$id]).checked = true;
            }

            if (document.getElementById(buf[$this]).checked == false)
                document.getElementById(buf[$id]).checked = false;
        }
        function active(id)
        {
            for (var i = 0; i < tagList.length; i++)
            {
                buf[tagList[i].value] = tagList[i].id;
            }
            ;
            var predok = name2[id];
            for (var i = 0; i < tagList.length; i++)
            {
                parent(predok, id);
                predok = name2[predok];
            }
            ;
        }
        ;

        function disable(id)
        {
            if (document.getElementById(buf[pid[id]]))
                for (var i = 0; i < pid[id].length; i++)
                {
                    document.getElementById(buf[pid[id][i]]).checked = false;
                }
            ;
        }
    </script>
..
отрисовываем
    <?php
    /*  echo CHtml::checkBoxList('im_id', $arr_bit, $type_list, array(
      'template' => '{input} {labelTitle}',
      'class' => 'chclass',
      )
      ); */
    echo CHtml::checkBoxList('im_id', $arr_bit, $type_list, array(
        'template' => '{input} {labelTitle}',
        'class' => 'chclass',
        'onchange' => 'javascript:'
        . 'if(this.checked)'
        . 'active(this.value);'
        . 'else disable(this.value);'
            )
    );
    ?> 
..
мы нарисовали чекбоксами подобие дерева.
нужно его же еще и сохранить.
идем в контроллер

   public function actionCreate()
    {
        $model = new User;

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

        if (isset($_POST['User']))
        {
            $model->attributes = $_POST['User'];
            if ($model->save())
            {
                if (isset($_POST['im_id']))
                {
                    $command = Yii::app()->db2->createCommand();
                    foreach ($_POST['im_id'] as $check)
                    {
                        $Ids = $_POST['im_id'];
                    };
                    for ($i = 0; $i < count($Ids); $i++)
                    {
                        $command->insert('t_userpage', array(
                            'id_user' => $model->u_id, ////
                            'id_page' => (int) $Ids[$i], ////
                        ));
                    }
                }
                $this->redirect(array('view', 'id' => $model->u_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['User']))
        {
            $model->attributes = $_POST['User'];
            if ($model->save())
            {
                $command = Yii::app()->db2->createCommand();
                $command->delete('t_userpage', 'id_user=:id', array(':id' => $model->u_id));
                if (isset($_POST['im_id']))
                {
                    foreach ($_POST['im_id'] as $check)
                    {
                        $Ids = $_POST['im_id'];
                    };
                    for ($i = 0; $i < count($Ids); $i++)
                    {
                        $command->insert('t_userpage', array(
                            'id_user' => $model->u_id, ////
                            'id_page' => (int) $Ids[$i], ////
                        ));
                    }
                }
                $this->redirect(array('view', 'id' => $model->u_id));
            }
        }

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


      addInCondition('id_handbook', array('2')); 
        $type_list = CHtml::listData(Handbook::model()->findAll($criteria), 'id', 'value');

        if (isset($model->id))
        {
            $arr = Mim::model()->findAll("id_engine=:id", array(':id' => $model->id));
        }

        if (isset($arr))
        {
            for ($i = 0; $i < count($arr); $i++)
            {
                $arr_bit[] = $arr[$i]->id_book;
            }
        }
        else
            $arr_bit = array();


        echo CHtml::checkBoxList('im_id', $arr_bit, $type_list, array(
            'template' => '{input} {labelTitle}',
            'class' => 'chclass',
                )
        ); //просто рисуем чекбокслитс из базы
        ?> 

Популярные сообщения из этого блога

Пишем логи на C# (.NET). Легкий способ.

Авторизация yii 2 из базы

Средства для работы с базой данный PostgreSql