Yii динамическое количество столбцов

June 11, 2015

Вот я подготовил начальный проектик ссылка
Делал на основании
Вход adminadmin gii - rootБаза - mysql localhost:locadb
Вид минимальной базы под действия


Что мы хотим получить


то есть в зависимости от шаблона (таблица template) мы отображаем разные столбцы (из таблицы element берем имена, из таблицы analiz_has_element значения)

создаем базу https://github.com/des1roer/yii_heart/blob/master/basesql.sql

создаем модели и CRUD под все таблицы (под template_has_elem crud можно не создавать).

тогда в

  • ...yiiHeartprotectedextensionsheartviewslayouts_menu.php


можем добавить

    array('label' => 'Проект',
'url' => '#',
'icon' => 'fa fa-sitemap',

'items' => array(
array('label' => 'template',
'url' => array('/template'),
'icon' => 'fa fa-info'),
array('label' => 'analiz',
'url' => array('/analiz'),
'icon' => 'fa fa-info'),
array('label' => 'element',
'url' => array('/element'),
'icon' => 'fa fa-info', ),
array('label' => 'has_element',
'url' => array('/haselement'),
'icon' => 'fa fa-info'),
array('label' => 'template_has',
'url' => array('/templatehas'),
'icon' => 'fa fa-info')

)),


получаем


выводим все элементы в ...yiiHeartprotectedviewstemplate_form.php

findAll(), 'id', 'name');

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

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

// $data = CHtml::textField('textField');
echo CHtml::checkBoxList('im_id2', $arr_bit, $type_list, array(
'template' => "{input} {labelTitle}",
'class' => 'chclass',
'labelOptions'=>array('style'=>'display:inline'),
)
);
//просто рисуем чекбокслитс из базы
//данные для элементов
?>


-
получаем


в контролере прописываем
при создании


if (isset($_POST['im_id2']))
{
$command = Yii::app()->db->createCommand();
$max = Yii::app()->db->createCommand()
->select('COALESCE ((max(id)), 1) as max')
->from('template')
->queryScalar();

foreach($_POST['im_id2'] as $check)
{
$Ids = $_POST['im_id2'];
};
for($i = 0; $i < count($Ids); $i++)
{
$command->insert('template_has_element', array(
'template_id' => $max, ////
'element_id' => (int) $Ids[$i], ////
));
}
};


при изменении


if (isset($_POST['im_id2']))
{
$command = Yii::app()->db->createCommand();
$command->delete('template_has_element', 'template_id=:id', array(':id' => $model->id));
foreach($_POST['im_id2'] as $check)
{
$Ids = $_POST['im_id2'];
};
for($i = 0; $i < count($Ids); $i++)
{
$command->insert('template_has_element', array(
'template_id' => $model->id, ////
'element_id' => (int) $Ids[$i], ////
));
}
};

все как здесь

ввод анализа
в ...yiiHeartprotectedviewsanaliz_form.php
дописываем


//добавление данных для ввода (при создании новой записи и отсутствии записи в изменяемой)
$id_template = $model->template_id;
if (isset($id_template))
{
$connection = Yii::app()->db;
if (isset($model->id))
{
$id2 = $model->id;
$sql2 = "
SELECT dat.`element_id` AS id,
dat.`value` AS value,
`el`.`name` AS name
FROM `analiz_has_element` dat,
`element` el
WHERE `analiz_id` = $id2
AND el.id=dat.`element_id`
";
$dataReader2 = $connection->createCommand($sql2)->query();
$rows2 = $dataReader2->readAll();
for($i = 0, $cnt = count($rows2); $i < $cnt; $i++)
{
$id = $rows2[$i]['id'];
echo CHtml::label($rows2[$i]['name'], $rows2[$i]['name']);
echo CHtml::textField("elem[$id][val]", $rows2[$i]['value'], array('id' => $rows2[$i]['name']));
$condition .= ' AND temp.`element_id` != ' . $id;
}
}
(isset($condition) && $condition) ? '' : $condition = null;
$sql = "
SELECT temp.`element_id` as id,
el.`name` as name
FROM `template_has_element` TEMP,
`element` el
WHERE `template_id` = $id_template
AND `temp`.`element_id` = el.`id`
$condition
";
$dataReader = $connection->createCommand($sql)->query();
$rows = $dataReader->readAll();

for($i = 0, $cnt = count($rows); $i < $cnt; $i++)
{
$id = $rows[$i]['id'];
echo CHtml::label($rows[$i]['name'], $rows[$i]['name']);
echo CHtml::textField("elem[$id][val]", '', array('id' => $rows[$i]['name']));
}
}


таким образом в зависимости от шаблона у раз разное число полей для ввода.
тогда по аналогии в контроллере при создании


if (isset($_POST['elem']))
{
$command = Yii::app()->db->createCommand();
$max = Yii::app()->db->createCommand()
->select('COALESCE ((max(id)), 1) as max')
->from('analiz')
->queryScalar();

$Ids = $_POST['elem'];
//echo '


';
$cnt = max(array_keys($Ids));
$min = min(array_keys($Ids));
for($i = $min; $i <= $cnt; $i++)
{
$val = $Ids[$i]['val'];
//echo $Ids[$i]['per'][0];
if (isset($val) && !empty($val))
$command->insert('analiz_has_element', array(
'analiz_id' => $max, ////
'value' => $val,
// 'f_precision' => $Ids[$i]['per'][0],
'element_id' => $i
));
}
};

при обновлении


if (isset($_POST['elem']))
{
$command = Yii::app()->db->createCommand();
$command->delete('analiz_has_element', 'analiz_id=:id', array(':id' => $model->id));
$Ids = $_POST['elem'];
//echo '

';
$cnt = max(array_keys($Ids));
$min = min(array_keys($Ids));
for($i = $min; $i <= $cnt; $i++)
{
$val = $Ids[$i]['val'];
if (isset($val) && !empty($val))
$command->insert('analiz_has_element', array(
'analiz_id' => $model->id, ////
'value' => $val,
'element_id' => $i
));
}
};

 


ну и отображение в ...yiiHeartprotectedviewsanalizadmin.php


db->createCommand()
->select('value')
->from('analiz_has_element')
->where("analiz_id=$analiz_id"
. " and element_id = $elem_id")
->queryScalar();
return (isset($num)) ? $num : '';
}
$myarray[] = array('header'=>'No','value'=>'($this->grid->dataProvider->pagination->currentPage*
$this->grid->dataProvider->pagination->pageSize
)+ ($row+1)',
'htmlOptions' => array('style' =>'width: 25px; text-align:center;'),
);
$myarray[] = array(
// 'header' => 'Name',
'name'=> 'name',
'type'=>'raw',
'value' => '($data->name)',
'class' => 'bootstrap.widgets.TbEditableColumn',
'headerHtmlOptions' => array('style' => 'text-align:center'),
'editable' => array(
'type' => 'textarea',
'url' => $this->createUrl('editable'),
'params' => array('YII_CSRF_TOKEN' => Yii::app()->request->csrfToken),
)
);

$template = 11;
//находим все элементы из шаблона
$connection = Yii::app()->db;
$sql = "
SELECT te.`element_id`,
el.name
FROM `template_has_element` `te`,
`element` el
WHERE el.id= te.`element_id`
AND te.`template_id`=$template
";
$dataReader = $connection->createCommand($sql)->query();
$rows = $dataReader->readAll();

/* -----------------Данные для таблицы------------------------------------------- */

for($i = 0, $cnt = count($rows); $i < $cnt; $i++) //формируем столбцы
{
$id = $rows[$i]['element_id'];
$myarray[] = array(
'header' => $rows[$i]['name'],
'id' => $id,
'value' => 'num($data->id,'.$id.')',
'htmlOptions' => array('style' => 'width: 15px; text-align:center;'),
'headerHtmlOptions' => array('style' => 'text-align:center'),
);
}

$myarray[] = array(
'class' => 'bootstrap.widgets.TbButtonColumn',
'buttons' => array
(
'view' => array
(
'url' => '$data->id."|".$data->name',
'click' => 'function(){
data=$(this).attr("href").split("|")
$("#myModalHeader").html(data[1]);
$("#myModalBody").load("' . $this->createUrl('view') . '&id="+data[0]+"&asModal=true");
$("#myModal").modal();
return false;
}',
),
)
);
$this->widget('bootstrap.widgets.TbGridView',array(
'id'=>'analiz-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'type' => 'striped hover', //bordered condensed
'columns'=>$myarray,
)); ?>


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

код наверно не идеальный, советы и замечания прошу оставлять в комментах. рабочий код лежит в проекте на гитхаб(ссылка самая первая)


Source: des1roer.blogspot.com

Комментарии

comments powered by Disqus