Perda Do Valor Selecionado Em Chtml::dropdownlist Após Submit

Olá, estou com um problema com os campos DropDownList Estado e Cidade. Em uma situação de Create quando eu preencho o formulário e algum validador no servidor retorna algum erro,ex: Validador de cpf retorna CPF invalido, após o retorno, refresh, da pagina com a mensagem de erro, os campos de Estado e cidade perdem seus valores selecionados e voltam para o valor empty. Caso somente erros de validação do lado do cliente ocorram, ex: campo vazio, ou nenhum erro ocorra esse problema não acontece, os dados são validados e armazenados no banco sem problemas. Em uma situação de Update esse problema não ocorre em nenhum erro de validação tanto do lado do cliente quanto do lado do servidor. Segue o código da view


<?php

/* @var $this ClienteController */

/* @var $model Cliente */

/* @var $form CActiveForm */

?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'cliente-form',

	'enableAjaxValidation'=>false,

        'enableClientValidation'=>true,

        'clientOptions'=>array(

            'validateOnSubmit'=>true

        )

)); ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<?php echo $form->errorSummary(array($model_cliente,$model_endereco,$model_estado)); ?>

       


	<div class="row">

		<?php echo $form->labelEx($model_cliente,'cnpj'); ?>                       

		<?php echo $form->textField($model_cliente,'cnpj',array('size'=>14,'maxlength'=>14)); ?>

		<?php echo $form->error($model_cliente,'cnpj'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_cliente,'razao_social'); ?>

		<?php echo $form->textField($model_cliente,'razao_social',array('size'=>60,'maxlength'=>255)); ?>

		<?php echo $form->error($model_cliente,'razao_social'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_cliente,'nome_fantasia'); ?>

		<?php echo $form->textField($model_cliente,'nome_fantasia',array('size'=>60,'maxlength'=>255)); ?>

		<?php echo $form->error($model_cliente,'nome_fantasia'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_cliente,'ramo_atividade'); ?>

		<?php echo $form->dropDownList($model_cliente,'ramo_atividade',$this->getRamosDeAtividades(),array('empty'=>'Selecione...')); ?>

		<?php echo $form->error($model_cliente,'ramo_atividade'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model_cliente,'natureza_juridica'); ?>

		<?php echo $form->dropDownList($model_cliente,'natureza_juridica',$this->getNaturezasJuridicas(),array('empty'=>'Selecione...')); ?>

		<?php echo $form->error($model_cliente,'natureza_juridica'); ?>

	</div>


        <div class="row">

            <?php echo $form->labelEx($model_cliente,'data_abertura'); ?>                 

            <?php echo $form->textField($model_cliente,'data_abertura');?>

            <?php echo $form->error($model_cliente,'data_abertura'); ?>


        </div>

        

        <div class="row">

		<?php echo $form->labelEx($model_endereco,'logradouro'); ?>

		<?php echo $form->textField($model_endereco,'logradouro'); ?>

		<?php echo $form->error($model_endereco,'logradouro'); ?>

	</div>

        

        <div class="row">

		<?php echo $form->labelEx($model_endereco,'numero'); ?>

		<?php echo $form->textField($model_endereco,'numero'); ?>

		<?php echo $form->error($model_endereco,'numero'); ?>

	</div>

        

        <div class="row">

		<?php echo $form->labelEx($model_endereco,'bairro'); ?>

		<?php echo $form->textField($model_endereco,'bairro'); ?>

		<?php echo $form->error($model_endereco,'bairro'); ?>

	</div>

        

        <div class="row">

		<?php echo $form->labelEx($model_endereco,'complemento'); ?>

		<?php echo $form->textField($model_endereco,'complemento'); ?>

		<?php echo $form->error($model_endereco,'complemento'); ?>

	</div>

        

        <div class="row">

		<?php echo $form->labelEx($model_endereco,'cep'); ?>

		<?php echo $form->textField($model_endereco,'cep'); ?>

		<?php echo $form->error($model_endereco,'cep'); ?>

	</div>

        

         <div class="row">

             <?php echo $form->labelEx($model_estado,'uf'); ?>

             <?php

             

             echo CHtml::dropDownList( 'uf','',$this->getEstados(),                     

                     array(

                         'id'=>'Estado_uf',

                         'options'=>array($model_estado->id=>array('selected'=>'selected')),

                         'empty'=>'Selecione...',

                         'ajax' =>

                         array(

                             'type'=>'POST', //request type                          

                             'url'=>CController::createUrl('getCidadesDoEstado').                           

                             'update'=>'#Endereco_cidade'                             

                             )

                         )

                         

                     );

             ?>

             <?php echo $form->error($model_estado,'uf'); ?>             

	</div>


        <div class="row">

            

                <?php echo $form->labelEx($model_endereco,'cidade'); ?>

        <?php

        

        if($model_endereco->isNewRecord){

        echo CHtml::dropDownList(CHtml::activeName($model_endereco, 'cidade'),'',array(),  array('empty'=>'Selecione...','id'=>'Endereco_cidade'));

        }else{

            echo CHtml::dropDownList(CHtml::activeName($model_endereco, 'cidade'),$model_endereco->cidade,$this->getCidades($model_estado),  array('empty'=>'Selecione...','id'=>'Endereco_cidade'));

        }

        ?>

        <?php echo $form->error($model_endereco,'cidade'); ?>    


            

            

	</div>    


        <div class="row">

            <?php echo $form->labelEx($model_cliente,'telefone_comercial'); ?>            

            <?php echo $form->textField($model_cliente,'telefone_comercial'); ?>

            <?php echo $form->error($model_cliente,'telefone_comercial'); ?>


        </div>





	<div class="row buttons">

		<?php echo CHtml::submitButton($model_cliente->isNewRecord ? 'Create' : 'Save'); ?>

	</div>


<?php $this->endWidget(); ?>


</div><!-- form -->

Não estou conseguindo resolver, alguem tem alguma dica ?

Deadbody,

Primeiramente quantos dos dois dados é gravado no banco de dados? uf ou cidade?

Por que eu normamente tenho a tabela do IBGE da cidades, e só salvo o ID da cidade que contêm o uf_ibge.

Vou postar minha solução.

viwe/cliente/_form.php




<div class="control-group">

	<?php echo $form->labelEx($model, 'uf', array('class' => 'control-label')); ?>

	<div class="controls">

		<?php

		$ufs = Estado::model()->findAll();

		$ufs = CHtml::listData($ufs, 'uf_ibge', 'uf');

		?>

		<?php echo $form->dropDownList($model, 'uf', $ufs, array('empty' => 'Selecione', 'class' => 'span2',

		'ajax' => array(

			'type' => 'POST',

			'url' => Yii::app()->createUrl('my/municipios'),

			'success' => 'function(data){$("select#Cliente_codmunicipio").html(data);}',

			'data' => array('uf' => 'js:$(this).val()')


		)));

		?>

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

	</div>

</div>

<div class="control-group">

	<?php echo $form->labelEx($model, 'codmunicipio', array('class' => 'control-label')); ?>

	<div class="controls">

		<?php echo $form->dropDownList($model, 'codmunicipio', CHtml::listData(Municipio::lista($model->uf), 'codmunicipio', 'municipio'), array('class' => 'span2')); ?>

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

	</div>

</div>



controller/MyController.php




public function actionMunicipios() {

	$municipios = Municipio::model()->findAll(array(

		'condition' => 'uf_ibge = :uf_ibge',

		'params' => array(':uf_ibge' => $_POST['uf'])

	));

	$municipios = CHtml::listData($municipios, 'codmunicipio', 'municipio');


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

	foreach ($municipios as $value => $name) {

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

	}

}



model/Cliente.php




public function afterFind()

{

	if ($this->isNewRecord) {

		$this->codmunicipio = array();

	} else {

		$this->uf = Municipio::model()->findByPk($this->codmunicipio)->uf_ibge;

	}


}



Obs.: Eu salvo somente o codmunicipio no banco de dados. Se der erro de Model.uf no seu formulário, e somente adicionar a váriavel $uf como publica no topo e dentro do seu Model.

Isso vai acontecer se vc mudar o estado e realizar o post certo!?

Não vai retornar os estados pq após realizar o post, a função javascript que carrega os estados não é chamada.

Tenta criar uma função javascript parar carrega os estados e chama essa função no onchange do seu dropDownList.

Após fazer isso, chama essa mesma função no onLoad da página…

Acho que é a solução mais simples.

Eu sou novato na área, estou aprendendo PHP, Yii, Javascript e Jquery todos ao mesmo tempo. Até o momento foquei meus estudos em java desktop, obrigatório na universidade. Agradeço a todos que contribuiram para aumentar meu conhecimento.

LukaszFokin-> O erro ocorre, suponho eu, ou ocorria, quando eu selecionava um estado, a dropDownList cidade me trazia as Cidades referente aquele Estado eu selecionava uma e clicava no botão submit. Como eu tenho alguns validadores de CPF e telefone no meu formulário e essa validação era feita no lado do servidor após o post, já que eu havia definido: ‘enableAjaxValidation’=>false, a pagina dava um refresh e os valores das dropDownLists Estado e cidade se perdiam.

Newerton-> Agradeço por postar sua solução. ajudou-me bastante. Adaptando e mesclando com a minha realidade eu consegui resolver o problema. Tenho uma questão que não consegui resolver e tive de modificar para que meu problema fosse resolvido. Eu uso a extension i18n-datetime-behavior no meu model Cliente. Não pude usar seu trecho de código:


public function afterFind() 

{ 

        if ($this->isNewRecord) { 

                $this->codmunicipio = array(); 

        } else { 

                $this->uf = Municipio::model()->findByPk($this->codmunicipio)->uf_ibge; 

        } 

 

}




e nenhum outro que altere a função afterFind(). Você ou alguém saberia como usar esta extensão mesmo personalizando o evento afterFind() ?