O caso é o seguinte estou desenvolvendo uma loja virtual como eu ja disse em outro momento, e estou com uma pequena dificuldade na ora de listar os rodutos.
Tenho uma tabela Categoria/subcategoria com os campos id, sort, parent, nome.
Supondo que sua tabela tenha uma coluna "id" para primary key da categoria, uma coluna chamada "idPai" que refere-se ao id da categoria pai (óbvio), "nome" com o nome da categoria.
No model Categorias.php, que se refere a esta tabela, coloca algo assim:
public function relations()
{
return array(
'pai'=>array(self::BELONGS_TO, 'Categorias', 'idPai'),
'filhas'=>array(self::HAS_MANY, 'Categorias', 'idPai'),
);
}
Agora no view basta chamar o pai de cada categoria
(supondo o controller renderizando $model=Categorias::model()->findByPk($id))
$model->nome //(exibe o nome da categoria)
$model->pai->nome //(exibe o nome pai da categoria do model)
$model->pai->pai->nome //(exibe o pai do pai)
...
Para exibir as filhas, foreach resolve
foreach($model->filhas as $filhas1){
$filhas1->nome //exibe as filhas
foreach($filhas1->filhas as $filhas2){
$filhas2->nome //exibe as filhas das filhas
}
}
Agora para relacionar as categorias com os produtos, supondo sua tabela de produtos com uma coluna que indentifica a categoria dele como por exemplo "categoriaId", seu model Categorias.php deve ter outro relacionamento:
public function relations()
{
return array(
'pai'=>array(self::BELONGS_TO, 'Categorias', 'idPai'),
'filhas'=>array(self::HAS_MANY, 'Categorias', 'idPai'),
'produtos'=>array(self::HAS_MANY, 'Produtos', 'categoriaId'),
);
}
Seguindo o exemplo acima:
$model->nome //(exibe o nome da categoria)
foreach($model->produtos as $produtos){
echo $produtos->nome; //(exibe o nome dos produtos da categoria atual)
}
$model->pai->nome //(exibe o nome pai da categoria do model)
foreach($model->pai->produtos as $produtosPai1){
echo $produtosPai1->nome; //(exibe o nome dos produtos da categoria pai)
}
$model->pai->pai->nome //(exibe o pai do pai)
foreach($model->pai->pai->produtos as $produtosPai2){
echo $produtosPai2->nome; //(exibe o nome dos produtos da categoria pai do pai)
}
...
Para exibir as filhas, foreach resolve (neste ponto minha cabeça já está dando um nó mas vamos tentar)
foreach($model->filhas as $filhas1){
$filhas1->nome //exibe as filhas
foreach($filhas1->produtos as $produtosFilhas1){
echo $produtosFilhas1->nome //exibe os produtos das categorias filhas
}
foreach($filhas1->filhas as $filhas2){
$filhas2->nome //exibe as filhas das filhas
foreach($filhas2->produtos as $produtosFilhas2){
echo $produtosFilhas2->nome //exibe os produtos das categorias filhas das filhas
}
}
}
Creio que o caminho seja este, claro que vc deve agora fazer um widget ou uma função no controller para limpar o código
Entao Newerton… seu codigo funcionou um belezinha…
Mais eutou com um probleminha, ë o seguinte na home eu gostaria de lista as cotegoria da seguinte maneiras:
Informática
Notebooks
Computadores
Monitores LCD
veja mais…
So que no banco esta desta maneira:
Informatica
Notebook
Computadores
-----Monitores LCD
-----Teclados
--------Splay de Limpeza
Como pode ver o meu problema é limitar as subcategorias da categoria pai e como pode ver tem uma sub da sub.
É que na home eu queri resumir as categorias de uma pai, teria que contar todas as subs categoria da pai e gerar o limit um lista só e incluir o veja mais é o link da categoria pai.
Yii::app()->clientScript->registerScript('jquery', "
jQuery('input[type=checkbox]').live('click',function() {
var id = this.id;
var checked=this.checked;
jQuery('input[id*=' + id + '_]').each(function() {
this.checked=checked;
});
});
");
A dúvida 2, você pode colocar no seu actionCreate e actionUpdate, essas programação que fiz é antiga, não tive tempo de reduzir ela ainda, mais todas estão funcionando perfeitamente.
ela esta sendo listada pelo treeview , mas ela pertence a outro model que é GrupoAcessoCategoria
essa forma que fiz é a correta? como se o os checkbox nao estiversse passando os valores em array pro actionCreate
adicionei tambem no form o script
Yii::app()->clientScript->registerScript('jquery', "
jQuery('input[type=checkbox]').live('click',function() {
var id = this.id;
var checked=this.checked;
jQuery('input[id*=' + id + '_]').each(function() {
this.checked=checked;
});
});
");
mas não funcionou.
fico muinto grato se puder me ajudar … rsrrs tenho ja uns 4 dias sem dormir… quando aprender irei postar meus resultados aqui tambem… abraços…
Depois de quebrar muita a cabeça fui pesquisando e testando varios widget e achei um bem interessante o MTreeView :
MTreeView
que tem varias funcionalidades, mas para o que eu queria ele nao tem por padrao então como tava precisando gerar uma TreeView por Categoria e Subcategoria fiz umas alterações no arquivo MTreeView.php para gerar uma listagem com CheckBox e atribuir como checked sendo passado por um array dentro do banco dados.
Segue abaixo o resultado;
3209
Depois vou criar um Post com com todo o material que usei para os que precisarem pois por eu ser iniciante quebrei muita cabeça… rsrsrs segue abaixo o codigo completo do /protected/extensions/MTreeView/MTreeView.php
adicionei esses dados
<?php
class MTreeView extends CTreeView {
//private properties
private $_tree;
private $_menus;
private $_fields_adjacency = array(
'id' => 'id',
'text' => 'text',
'url' => 'url',
'icon' => 'icon',
'alt' => 'alt',
'tooltip' => 'tooltip',
'id_parent' => 'id_parent',
'task' => 'task',
'position' => 'position',
'options' => false,
// campo action adicionado na tabela padrao do mtreeview
'action' => 'action',
'id2' => 'id2',
// campo controller // campo adicionado na tabela padrao do mtreeview
'controller' => 'controller',
// pega dados checked // campo adicionado na tabela padrao do mtreeview somente para teste
'ids_checked' => 'ids_checked',
);
alterei a função getAdjacentTree do MTreeView.php para essa:
public function gera_permissao($Grupo_dados,$tipo){
// $tipo = permissao / ids_checked
$permissoes="";
$checkeds=array();
$k2="";
if(isset($Grupo_dados))
{
foreach($Grupo_dados as $key=> $valor){
//// ---> Cria Controllers
$controleCategoria=MenuAdjacency::model()->findByPk($valor);
if ($controleCategoria->action=="controller") {
$permissoes .= '{"controllers":"'.$controleCategoria->controller.'","actions":"';}
//se nao marcar o checkbox do controler
if ($controleCategoria->action!="controller" or $permissoes=="" ) {
$permissoes .= '{"controllers":"'.$controleCategoria->controller.'","actions":"'; }
//// ---> Cria actions
foreach($Grupo_dados[$key] as $k => $v) {
$acaoCategoria= MenuAdjacency::model()->findByPk($v);
$checkeds[] = $v;
if ($acaoCategoria->action!="controller") {
$permissoes .= $acaoCategoria->action.',';
}
}
$permissoes = substr($permissoes, 0, -1);
$permissoes .= '"},';
} /// final foreach
}
if(!isset($Grupo_dados))
$checkeds = $checkeds;
$permissoes = substr($permissoes, 0, -1);
$checkeds = serialize($checkeds);
if($tipo=="permissao")
return $permissoes;
if($tipo=="ids_checked")
return $checkeds;
}
no Meu ActionCreate /protected/controllers/GrupoAcessoController.php
O mesmo codigo para o ActionUpdate
public function actionCreate()
{
$model=new GrupoAcesso;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['GrupoAcesso']))
{
$model->attributes=$_POST['GrupoAcesso'];
////////////////////////// GRAVA PERMISSAO NO BANCO
$model->permissao = '';
$model->ids_checked = '';
if(!isset($_POST['Grupo_dados'])) { $checkeds =array(); $permissao=array(); }
else { $checkeds = $_POST['Grupo_dados']; $permissao = $_POST['Grupo_dados']; }
$model->ids_checked = $this->gera_permissao($checkeds, "ids_checked");
$model->permissao = $this->gera_permissao($permissao, "permissao");
////////////////////////// FINAL
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
no meu _form
/// marcar todos checkbox filho através do pai
Yii::app()->clientScript->registerScript('jquery', "
jQuery(document).ready(function($){
$('ul[id $= yw0] input[type=checkbox]').click(function () {
$(this).closest('li').find('input[type=checkbox]').attr('checked', this.checked);
});
});
");
$this->widget('application.extensions.MTreeView.MTreeView',array(
'collapsed'=>true,
'animated'=>'fast',
//---MTreeView options from here
'table'=>'menu_adjacency',//what table the menu would come from
'hierModel'=>'adjacency',//hierarchy model of the table
'conditions'=>array('visible=:visible',array(':visible'=>1)),//other conditions if any
'fields'=>array(//declaration of fields
'text'=>'title',//no `text` column, use `title` instead
'alt'=>'title',//skip using `alt` column
'id_parent'=>'parent_id',//no `id_parent` column,use `parent_id` instead
'task'=>false,
'icon'=>true,
'url'=>false,
/// pega dados para do banco
'ids_checked'=>unserialize($model->ids_checked),
),
));