Dropdownlist Dependientes Update Y Create

Buenas tardes, hoy llego nuevamente al foro con una duda. tengo mucho tiempo intentando hacer unos combos dependientes, de hecho ya logre hacerlos, pero para cuando quiero actualizar un registro que ya tengo creado en mi base de datos, es cuando viene mi problema, los combos deberian estar seleccionados. pero vienen en blanco. ademas quiero ponerle un prompt por defecto que diga 'Seleccionar… ’ se que puede que no sea la primera vez que ven este problema de mi parte, pero no he podido resolverlo y es el unico que me tranca toda mi aplicacion. muchas gracias…

Aqui mi relacion de tablas.




 ____________       _______________       _______________            ________________

| tbl_estado |     | tbl_municipio |     | tbl_parroquia |          | tbl_estructura |

|id          |----<|id             |----<|id             |---------<|id              |

|codestado   |     |idestado(FK)   |     |idmunicipio(FK)|          |idtipoestructura|

|estado      |     |cod mun        |     |codpar         |          |idparroquia(FK) |

|estatusreg  |     |municipio      |     |parroquia      |          |denominacion    |

|____________|     |estatusreg     |     |estatusreg     |          |estatusreg      |

                   |_______________|     |_______________|          |________________|



En el from de TblEstructura tengo esto.




<!-- ************************************************************************************************ -->

<!-- ************************************************************************************************ -->

<!-- ************************************************************************************************ -->


	

	<div class="row">

		<?php echo $form->labelEx($model,'Estado'); ?>

		<?php echo $form->dropDownList(TblEstado::model(),'id',

			CHtml::listData(TblEstado::model()->findAll(),'id','estado'),

			array(

                    'ajax' => array(

                    'type' => 'POST',

                    'url' => CController::createUrl('TblEstructura/Selectmunicipio'),

                    'update' => '#'.CHtml::activeId(TblMunicipio::model(),'id'),

                    'beforeSend' => 'function(){

                    	$("#TblEstructura_idparroquia").find("option").remove();

                    	}',

                  //$("#TblMunicipio_id").find("option").remove();

                ),//'prompt' => 'Seleccione un Estado...'

					'prompt' => $model->isNewRecord ? 'Seleccione un Estado...' : $model->idparroquia0->idmunicipio0->idestado0->estado

            )

		); ?>

	</div>


	<div class="row">

	    <?php echo $form->labelEx($model,'Municipio'); ?>

	    <?php echo $form->dropDownList(TblMunicipio::model(),'id',

	      CHtml::listData(TblMunicipio::model()->findAll(),'id','municipio'),

	      array(

	          'ajax' => array(

	                    'type' => 'POST',

	                    'url' => CController::createUrl('TblEstructura/Selectparroquia'),

	                    'update' => '#'.CHtml::activeId($model,'idparroquia'), 

	                ),

	          'prompt' => $model->isNewRecord ? 'Seleccione un Municipio...' : 'Municipio'

	          //Este promopt tiene error, ya que el combo el registro y muestra todos los registros que encuentra en municipio

	          //'prompt' => $model->isNewRecord ? 'Seleccione un Municipio...' : $model->idparroquia0->idmunicipio0->municipio

	          )

	    ); ?>

	    

  </div>




	<div class="row">

		<?php echo $form->labelEx($model,'Parroquia'); ?>

    	<?php echo $form->dropDownList($model,'idparroquia',array(    			

    	//$model->idparroquia0->id => $model->idparroquia0->parroquia 	

    	//'prompt' => $model->isNewRecord ? 'Seleccione una Parroquia...' : $model->idparroquia0->parroquia,

    	//'value' => $model->idparroquia0->id

    			'prompt' => $model->isNewRecord ? 'Seleccione una Parroquia...' : null

    	)

    	); ?>

    	<?php echo $form->error($model,'idparroquia'); ?>

	</div>




<!-- ************************************************************************************************ -->

<!-- ************************************************************************************************ -->

<!-- ************************************************************************************************ -->



Mi controller TblEstructuraController




<?php


class TblEstructuraController 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','SelectMunicipio','Selectparroquia'),

				'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 TblEstructura;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['TblEstructura']))

		{

			$model->attributes=$_POST['TblEstructura'];

			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['TblEstructura']))

		{

			$model->attributes=$_POST['TblEstructura'];

			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)

	{

		$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'));

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('TblEstructura');

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}


	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new TblEstructura('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['TblEstructura']))

			$model->attributes=$_GET['TblEstructura'];


		$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 TblEstructura the loaded model

	 * @throws CHttpException

	 */

	public function loadModel($id)

	{

		$model=TblEstructura::model()->findByPk($id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	/**

	 * Performs the AJAX validation.

	 * @param TblEstructura $model the model to be validated

	 */

	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='tbl-estructura-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}


	public function actionSelectmunicipio()

	{	

		 $id_uno= $_POST['TblEstado']['id']; 

	     $lista = TblMunicipio::model()->findAll('idestado = :id_uno',array(':id_uno' => $id_uno));

	     $lista = CHtml::listData($lista, 'id', 'municipio');


	   		echo CHtml::tag('option',array('value' => ''),'Seleccione un Municipio...',true);

	            foreach($lista as $valor => $municipio)

            {

                echo CHtml::tag('option',array('value' => $valor),CHtml::encode($municipio), true);

            }


	}


	public function actionSelectparroquia()

	{

		 $id_dos= $_POST['TblMunicipio']['id']; 

	    //$lista2 = TblParroquia::model()->findAll('idmunicipio = :id_dos',array(':id_dos' => $id_dos));

	     $lista2 = TblParroquia::model()->findAll('idmunicipio = :id_dos',array(':id_dos' => $id_dos));

	     $lista2 = CHtml::listData($lista2, 'id', 'parroquia');


	   		echo CHtml::tag('option',array('value' => ''),'Seleccione una Parroquia...',true);

	            foreach($lista2 as $valor2 => $parroquia)

            {

                echo CHtml::tag('option',array('value' => $valor2),CHtml::encode($parroquia), true);

            }


	}

}



Mi model TblEstructura (Aunque creo que no he tocado nada ahi)




<?php


/**

 * This is the model class for table "tbl_estructura".

 *

 * The followings are the available columns in table 'tbl_estructura':

 * @property integer $id

 * @property integer $idpadre

 * @property integer $idtipoestructura

 * @property integer $idparroquia

 * @property integer $codigoonapre

 * @property string $denominacion

 * @property string $ubicacionfisica

 * @property string $paginaweb

 * @property string $telefono

 * @property integer $estatusreg

 *

 * The followings are the available model relations:

 * @property TblMaximaautoridadEstructura[] $tblMaximaautoridadEstructuras

 * @property TblSeguimientoproyecto[] $tblSeguimientoproyectos

 * @property TblTipoestructura $idtipoestructura0

 * @property TblParroquia $idparroquia0

 * @property TblDependencias[] $tblDependenciases

 */

class TblEstructura extends CActiveRecord

{

	public $varbotones;

	public $varDenominacionTE;

	public $varParroquiaTE;

	public $varIdpersonaTE;

	public $varIdpersona2TE;

	public $varIdestadoTE;

	public $varStatus;

	public $varStatus2;




	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'tbl_estructura';

	}


	/**

	 * @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('idtipoestructura, idparroquia, denominacion, ubicacionfisica', 'required'),

			array('idpadre, idtipoestructura, idparroquia, codigoonapre, estatusreg', 'numerical', 'integerOnly'=>true),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('varbotones, id, idpadre, idtipoestructura, idparroquia, codigoonapre, denominacion, idtipoestructura0.denominacion, idparroquia0.idmunicipio0.idestado0.id, ubicacionfisica, paginaweb, telefono, estatusreg, varDenominacionTE, varParroquiaTE, varIdpersonaTE, varIdpersona2TE, varIdestadoTE', 'safe', 'on'=>'search'),

		); // VER SI "idtipoestructura0.denominacion" son necesarios

	}


	/**

	 * @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(

			'tblMaximaautoridadEstructuras' => array(self::HAS_MANY, 'TblMaximaautoridadEstructura', 'idestructura'),

			 // 'idmaximaautoridadestructura0' => array(self::HAS_ONE, 'TblMaximaautoridadEstructura', 'idestructura'),

			'tblSeguimientoproyectos' => array(self::HAS_MANY, 'TblSeguimientoproyecto', 'idestructura'),

			'idtipoestructura0' => array(self::BELONGS_TO, 'TblTipoestructura', 'idtipoestructura'),

			'idparroquia0' => array(self::BELONGS_TO, 'TblParroquia', 'idparroquia'),

			'tblDependenciases' => array(self::HAS_MANY, 'TblDependencias', 'idestructura'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'idpadre' => 'Organismo al que pertenece',

			'idtipoestructura' => 'Idtipoestructura',

			'idparroquia' => 'Idparroquia',

			'codigoonapre' => 'Codigo ONAPRE',

			'denominacion' => 'Nombre del Organismo o Ente',

			'ubicacionfisica' => 'Direccion',

			'paginaweb' => 'Paginaweb',

			'telefono' => 'Telefono',

			'estatusreg' => 'Estatus en el que encuentra el registro (activo - inactivo)',


			'idtipoestructura0.denominacion' => 'Tipo de Organismo',

			'idparroquia0.parroquia' => 'Parroquia',

		);

	}


	/**

	 * 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->with = array(

			'idtipoestructura0',

			'idparroquia0.idmunicipio0.idestado0', 

			'tblMaximaautoridadEstructuras.idmaximaautoridad0.idpersona0',

			'tblMaximaautoridadEstructuras.idmaximaautoridad0.idpersona0');

    	$criteria->together = true;


		$criteria->compare('id',$this->id);

		$criteria->compare('idpadre',$this->idpadre);

		$criteria->compare('idtipoestructura',$this->idtipoestructura);

		$criteria->compare('idparroquia',$this->idparroquia);

		$criteria->compare('codigoonapre',$this->codigoonapre);

		$criteria->compare('t.denominacion',strtoupper($this->denominacion),true);

		$criteria->compare('ubicacionfisica',$this->ubicacionfisica,true);

		$criteria->compare('paginaweb',$this->paginaweb,true);

		$criteria->compare('telefono',$this->telefono,true);

		$criteria->compare('estatusreg',$this->estatusreg);




		$criteria->compare('idtipoestructura0.denominacion',strtoupper($this->varDenominacionTE),true);

		$criteria->compare('idestado0.estado',strtoupper($this->varIdestadoTE),true);

		$criteria->compare('idpersona0.nombre',strtoupper($this->varIdpersonaTE),true);

		$criteria->compare('idpersona0.apellido',strtoupper($this->varIdpersona2TE),true);

		$criteria->order = 't.denominacion ASC';

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

			'pagination'=>array('pageSize'=>10),

		));

	}


	/**

	 * 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 TblEstructura the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	protected function beforeSave() 

	{

	    $this->denominacion = strtoupper($this->denominacion);

	    $this->ubicacionfisica = strtoupper($this->ubicacionfisica);

	    $this->paginaweb = strtoupper($this->paginaweb);


	    return parent::beforeSave();

	}


	

	public function getNombreMa()

	{

		if (isset($this->tblMaximaautoridadEstructuras[0]) ) {

			$this->varStatus = $this->tblMaximaautoridadEstructuras[0]->idmaximaautoridad0->idpersona0->nombre;

		}else{

			$this->varStatus = 'Aun sin Asignar';		

		}

		return $this->varStatus;

	}


	public function getApellidoMa()

	{

		if (isset($this->tblMaximaautoridadEstructuras[0]) ) {

			$this->varStatus2 = $this->tblMaximaautoridadEstructuras[0]->idmaximaautoridad0->idpersona0->apellido;

		}else{

			$this->varStatus2 = 'Aun sin Asignar';		

		}

		return $this->varStatus2;

	}


	public function getboton()

	{

			alert($this);

		if ($this == 'Tbltipodependencias') {

			$this->varbotones = '1';

			alert('1');

		}else{

			$this->varbotones = '0';		

			alert('0');

		}

		return $this->varbotones;

	}

	

}



Intenté hacerlo de otra manera y me funciona por lo menos en otro form que solo tiene 2 niveles. ahora el problema es que cuando actualizo(Update) un registro existente. el primero combo de TblEstructura no me trae seleccionada la opcion. aqui les dejo lo que tengo

Mis tablas




 ______________       ________________       ______________________    

|tbl_estructura|     |tbl_dependencias|     |tbl_dependenciapersona|  

|id            |----<|id              |----<|id                    |

|denominacion  |     |idestructura(FK)|     |iddependencias(FK)    |       

|hola          |     |denominacion    |     |persona               |       

|estatusreg    |     |                |     |                      |       

|______________|     |estatusreg      |     |estatusreg            |         

                     |________________|     |______________________|     



Mi _form en TblDependenciapersona/view




<div class="row">

		<?php 

		echo $form->labelEx($model,'Organismo / Ente');

		

		$organismo = new CDbCriteria;

		$organismo->order = 'denominacion ASC';

		

		echo $form->dropDownList(TblEstructura::model(),'id',

		CHtml::listData(TblEstructura::model()->findAll($organismo),

		'id','denominacion'),

			array('ajax'=>array('type' => 'POST',

								'url' => CController::createUrl('TblDependenciapersona/Cargarorganismos'),

								'update' => '#TblDependenciapersona_iddependencias'

								),

				'prompt'=> 'Seleccione un Organismo...'

				)

		);

		?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'iddependencias'); 

		//echo $form->textField($model,'iddependencias'); 

		if ($model->isNewRecord==1){

			echo $form->dropDownList($model,'iddependencias',

			array('0' => 'Seleccione una Dependencia...'));

		}else {

			$tipo=$model->iddependencias0->idestructura;

			$sql="select count(id) from tbl_dependencias where idestructura = '$tipo';";

			$connection=Yii::app()->db;//DirectorioDB

			

			$command=$connection->createCommand($sql);

			

			$row=$command->queryRow();

			$bandera=$row['count'];

			

			if($bandera==0){

				echo $from->dropDownList($model,'iddependencias',

				array('0' => 'Seleccione una Dependencia'));

			} else {

				echo $form->dropDownList($model,'iddependencias',

				CHtml::listData(TblDependencias::model()->findAllBySql(

				"select * from tbl_dependencia where idestructura 

				=:keyword order by idestructura=:clave2 asc",

			array(':keyword'=>$model->iddependencias0->idestructura,':clave2'=>$model->iddependencias)), 

			'id','denominacion'));

			}

		}

			

		?>

		<?php echo $form->error($model,'iddependencias'); ?>

	</div>




mi controller de TblDependenciapersonaController




public function actionCargarorganismos()

	{

		$data=TblDependencias::model()->findAllBySql(

				"select * from tbl_dependencias where idestructura

				=:keyword or id=0 order by id=0 desc, denominacion asc",

				

				array(':keyword'=>$_POST['TblEstructura']['id']));

		$data=CHtml::listData($data,'id','denominacion');

		foreach ($data as $value=>$name)

		{

			echo CHtml::tag('option', array('value'=>$value), CHtml::encode($name), true);

		}

	}



Ya agregué la funcion en el accesRules. cualquier ayuda sirve para saber como asignarle al primero combo lo que traiga seleccionada la opcion correspondiente cuando no es un isNewRecord.

mira yo tenia el mismo problema y pues lo que hice fue en el _form preguntar si es isNewRecord.


 if (!$model->isNewRecord ){

//aqui llegaria si es por update lo que hago es hacer una consulta del campo que quiero mostrar


$tu_variable = Tu_modelo::model()->findByPk($model->Tu_id); //busca en tu modelo al que pertenece el _form de acuerdo a la llave de tu tabla

$model->tu_campo=$tu_variable->tu_campo; //asignas al campo la variable q buscaste, esta parte la repites para tus demás campos que necesites mostrar.





	  }



esto me funciona cada vez qu entro a modificar los campos muestran lo que ya tenia lleno y dejan de aparecer vacíos.

espero y te sea de ayuda :D