Validação Ajax

Newerton,

Exatamente isso, eu já sabia que a variavel $_POST[‘sinistro’][‘valor_rateio’] não existe. O que na verdade está acontecendo é que a variavel $_POST[valor] está ficando com o valor digitado no input participacao, quando na verdade eu preciso que o valor deste input seja subtraido do valor existente nos tres campos de orçamento. Dai o menor valor final desta subtração vai para o campo valor_rateio.

Olhe o resultado que você pediu:

3369

firebug.png

Ricardo,

Deixa eu ver se entendi.

  1. O campo de Participação, vai receber o valor da subtração ou a soma de (Orçamento 1 - Orçamento 2 - Orçamento 3)?

Mostra um exemplo escrito de como será feito no formulário, pelo que tudo indica o campo Participação não precisa de ajax.

Newerton,

O campo participacao precisa de ajax pelo seguinte:

O usuario devera entrar com as seguintes informaçoes: participacao, orcamento1, orcamento2 e orcamento3. Sempre que ele digitar qualquer um destes valores a ActionRateio devera ordenar os 3 orçamentos e pegar o menor orçamento e subtrair pela participacao.

Feito isso deverá atualizar automaticamente os campos valor_rateio (menor_orcamento - participacao), valor_parcial (inicialmente colocara "0" e o usuario podera mudar depois), e valor_restante (valor_rateio - valor_parcial).

Ricardo,

Entendi como funciona.

Vamos analisar o seguinte, se o cliente preencheu a participação e os orçamentos e deseja depois alterar a participação, ai sim ta correto que a participação precisa ser em ajax, mas acho EU que não precisa usar a função ajax do input, você pode fazer essa soma e subtração pelo próprio javascript, que eu acho mais rapido para lidar com isso.

Vou postar o exemplo do input participação, e você deve fazer o mesmo com os campos orcamento 1~3.

So explicando o que deve ser fazer, ao digitar o valor ou ao pressionar as teclas os campo valor_rateio ja vai sendo atualizado automaticamente ou senão, se deseja fazer de 1 unica vez, coloca um botão ao lado do input valor_rateio, que ao clicar ele pega os campos e faz o calculo.

Vou fazer da forma que está seu código.




<?php echo $form->textField($model,'participacao',array(

	'size'=>14,

	'maxlength'=>14, 

	'class'=>'span2', 

	'ajax'=>array(

		'type'=>'POST',

		'url' => Yii::app()->createUrl('sinistro/rateio'),

		'success' => 'function(data){

			$("input#sinistro_valor_rateio").val(data.valor_rateio);

			$("input#sinistro_valor_parcial").val(data.valor_parcial);

			$("input#sinistro_valor_restante").val(data.valor_restante);

		}',

		'data' => array(

			'valor_rateio' => 'js:$("input#sinistro_valor_rateio").val()',

			'valor_parcial' => 'js:$("input#sinistro_valor_parcial").val()',

			'valor_restante' => 'js:$("input#sinistro_valor_restante").val()',

			

			'participacao' => 'js:$("input#sinistro_participacao").val()',

			

			'orcamento1' => 'js:$("input#sinistro_orcamento1").val()',

			'orcamento2' => 'js:$("input#sinistro_orcamento2").val()',

			'orcamento3' => 'js:$("input#sinistro_orcamento3").val()',

		)

	) 

)); ?>



Eu acho mais correto colocar um botão de atualizar, e faz essa requisição em ajax somente 1x.

Oi Newerton,

Entendi com relação ao uso do js. Mais uma que aprendi…valeu!!

Com relação ao uso do botão para atualizar apenas 1 vez vou tentar implementar.

Mas, para finalidade que estou desenvolvendo seria interessante se tivesse como alterar automaticamente a medida que for digitando os valores. Fiz conforme você postou e deu certo o json. Mas voltou ao mesmo problema inicial. Quando coloco o plugin priceformat (http://jquerypriceformat.com) no input ele não chama a função rateio. O que pode ser?

Olá Newerton,

Adaptei e coloquei o botão de atualizar com requisição ajax apenas 1 vez e resolveu. Apenas mais uma duvida que tinha até postado no inicio deste tópico.

Eu tenho um dropdown com valores "Parcial" e "Completo". Quando o usuario escolher "Completo" preciso que ele deixe o campo seguinte desabilitado, quando escolher "Parcial" habilita o campo para inserção de valores.

Já fiz várias tentativas e nada deu certo. Você teria uma luz sobre como fazer isso?

Desde já agradeço por mais esta ajuda!

Você pode adicionar no evento onChange do dropDown através do parâmetro htmlOptions uma função JS que caso a opção seja completa, desabilite o campo seguinte.

Caso tenha dificuldades em implementar, posta seu código aí que a gente dá uma ajuda,

Você pode fazer o que o Lothor disse ou criar em jquery esse evento.


$('select#valores').live('change', function(){

    var value = $(this).val();

    if(value == 'Completo'){

        $('#campo_seguinte').attr({'disabled': 'disabled'});

    } else {

        $('#campo_seguinte').removeAttr('disabled'});

    }


});

Simples!

PS: Usa .on ao invés de .live.

Pessoal,

Fiz o evento em jquery. Fiz as adaptações necessárias, mas não funciona. Tem como dar uma olhada por favor?


<?php $tipo_rateio = array('Completo', 'Parcial'); 

                    echo $form->dropDownList($model,'tipo_rateio', $tipo_rateio, array(

                        'empty'=>'Selecione',

                        'class'=>'span2',

                    )); 

                    Yii::app()->clientScript->registerScript('tipo_rateio',

                            "$('select#sinistro_tipo_rateio').live('change', function(){

                                var value = $(this).val();

                                if(value == 'Completo'){

                                    $('#sinistro_valor_parcial').attr({'disabled': 'disabled'});

                                } else {

                                    $('#sinistro_valor_parcial').removeAttr('disabled');

                                }

                            });"

                            );


               ?>

Tentei usar o .on no lugar do .live mas não funcionou também.

Valeu!!

Testa ae.




Yii::app()->clientScript->registerScript('tipo_rateio',"

	$(document).on('change','select#sinistro_tipo_rateio',function() {

		var value = $(this).val();

		if(value == 'completo'){

			$('#sinistro_valor_parcial').attr({'disabled': 'disabled'});

		} else {

			$('#sinistro_valor_parcial').removeAttr('disabled');

		}

	});

");


$tipo_rateio = array(

	'completo' => 'Completo', 

	'parcial' => 'Parcial'

	); 

echo $form->dropDownList($model,'tipo_rateio', $tipo_rateio, array(

	'empty'=>'Selecione',

	'class'=>'span2',

)); 



Perfeito!!!! Excelente!! Muito obrigado mais uma vez pela ajuda!!

Newerton,

Sei que o correto seria abrir um novo topico, mas gostaria de ver apenas uma duvida que pode ser simples e rápida. Se não for abro outro topico. É o seguinte… Estou usando o conversor de datas i18n-datetime-behavior. Tenho no meu form 2 campos de data. Um deles o usuario escolhe a data por meio do calendário (widget CJuiDatePicker), e a outra eu passo datetime para controle de cadastro por meio do date(‘d/m/Y H:i:s’) no beforesave.

Sem o beforesave no model estava funcionando perfeitamente. Porém quando coloco o beforesave, a data inserida pelo usuario fica como 1969/12/31 e a data que passo pelo date grava corretamente.

Tem alguma idéia? Abaixo o codigo para ajudar.

_Controller


public function actionCreate()

	{

		$model=new veiculo;

                

		// Uncomment the following line if AJAX validation is needed

		 $this->performAjaxValidation($model);


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

		{

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

                        if($model->beforeSave()){

                            if($model->save())

				$this->redirect(array('view','created'=>'true','id'=>$model->idveiculo));

                        }

                        

		}


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

			'model'=>$model,

		));

	}

_form


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

		<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(

                            'name'=>'veiculo[dataentrada]',

                                'value'=>$model->dataentrada,

                                'language'=>'pt-BR',

                            'htmlOptions' => array('size' => 10, 'class'=> 'input-small'),

                            'options'=>array(

                                'showAnim'=>'fold',

                                'dateFormat'=>'dd/mm/yy',

                                'changeMonth' => 'true',

                                'changeYear' => 'true',

                            ),

                        ));

                ?>

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

_Model


public function beforeSave()

        {

            if (!parent::beforeSave()) return false;

            

            $this->status = 1;

            $this->datacad = date('d/m/Y H:i:s');

            $this->valor = str_replace(',', '.', str_replace('.', '', $this->valor));

            return parent::beforeSave();

           

        }  

Amigo tenta assim:




public function beforeSave() {

        if ($this->isNewRecord) {

        .............

        $this->datacad = new CDbExpression('NOW()');       

         ...............

        }  

        return parent::beforeSave(); 

}



Os campos do banco de dados são YYYY-mm-dd HH::MM:SS

Então faz o modelo que Adrian colocou ou so corrige para:




$this->datacad = date('Y-m-d H:i:s');



Oi pessoal,

Talvez eu não tenha explicado direito, mas este campo datacad esta sendo gravado corretamente. Eu coloco a data no formato “date(‘d/m/Y H:i:s’)” e o i18n-datetime-behavior converte perfeitamente para o formato americano e salva no banco.

O problema esta com o campo dataentrada que é inserido pelo usuario por meio de um calendário. Esta data que, se eu uso o beforesave, ele vai para o banco como 1969/12/31, sem o beforesave vai corretamente no formato americano.

Desculpe se ficou confuso…

Já que a data é inserida pelo usuário você pode colocar assim:


public function beforeSave() {        

 if ($this->isNewRecord) { 

              $this->datacad = date('Y-m-d', CDateTimeParser::parse($this->datacad, Yii::app()->locale->dateFormat));         

}           

return parent::beforeSave(); 

}



Oi Adrian,

Na verdade a conversão para o formato americano ‘Y-m-d’ já esta sendo feita pelo i18n-datetime-behavior.

Apenas reforçando eu tenho duas datas neste form. "datacad" é a data de cadastro que pega o datetime atual, no momento do registro. Este está sendo convertido e gravado corretamente no banco.

Já o campo "dataentrada" é um campo que o usuario escolhe a data que quiser. Na hora de converter pelo i18n-datetime-behavior é que não sei o que está acontecendo, mas ele converte para 1969/12/31.

Testei o que vc sugeriu,


$this->datacad = date('Y-m-d', CDateTimeParser::parse($this->datacad, Yii::app()->locale->dateFormat));         

mas continua na mesma, porque o i18n-datetime-behavior já tinha convertido e simplesmente tentou converter de novo a data que já estava convertida. Acho que existe algum problema na rule deste model, mas não sei o que é.

Descobri o que o BeforeSave está fazendo, apenas não entendi o motivo. Talvez já tenham visto isso antes.

Percebi que o cliente entra com os dados e antes de salvar ele executa duas vezes o BeforeSave. Descobri isso pelo firebug (var_dump). Parece que entra duas vezes e faz a primeira conversão (exemplo: de 15/10/2012 para 2012-10-15 e depois entra de novo e tenta converter 2012-10-15 novamente, é onde ele dá erro e grava 1969-12-31).

Alguém sabe o porque isso ocorre? Agradeço ajuda que puderem dar. Preciso muito resolver isso.

Amigo se possível tira a extension i18n-datetime-behavior, para inserção de datas utiliza só assim:




public function beforeSave() {   

      if ($this->isNewRecord) { 

         $this->datacad = new CDbExpression('NOW()'); //Pega a data atual

         $this->dataentrada= date('Y-m-d', CDateTimeParser::parse($this->dataentrada, Yii::app()->locale->dateFormat)); //Transforma a data que o usuário inseriu manualmente

     }

return parent::beforeSave();  

}



Eu particulamente utilizo sempre desta forma e roda tudo blza…