Auto Completar Textarea


(Ricbhz) #1

Galera, preciso de mais uma ajuda.

Tenho um dropdown com lista de cursos cadastrados no banco de dados. Ao lado desta lista tem um botão "Incluir".

O usuário poderá escolher um curso no dropdown e clicar em "Incluir". Quando fizer isso preciso que apareça num textarea o nome do curso e o valor do mesmo, e a medida que escolher outros cursos ele continua colocando no textarea vários cursos sem apagar os que já foram escolhidos.

E por fim cada curso que aparecer no textarea deverá ser um link para permitir clicar no mesmo e excluir da lista se quiser.

Já fiz parte do trabalho. Abaixo como está.

_form


<div class="column">

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

		<?php

                    $curso = curso::model()->findAll('status = 1', array('order'=>'nome ASC'));

                    $curso = CHtml::listData($curso, 'idcursos', 'nome');


                    echo $form->dropDownList($model, 'cursosidcursos', $curso,

                            array(

                                'prompt' => 'Selecione',

                                'class'=>'span26',

                            )

                    );

                ?>

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

	</div>

        

        <div class="column">

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

            <?php $this->widget('bootstrap.widgets.TbButton', array(

                    'label'=>'Inserir',

                    'type'=>'success', // null, 'primary', 'info', 'success', 'warning', 'danger' or 'inverse'

                    'size'=>'small', // null, 'large', 'small' or 'mini'

                    'buttonType'=>'ajaxButton',

                    'url' => Yii::app()->createUrl('pacotecurso/incurso'),

                    'ajaxOptions'=>array(

                        'type'=>'POST',

                        'dataType' => 'json',

                        'success' => 'function(data){

                                    $("input#pacotecurso_valor_final").val(data.valor);

                                    $("textarea#pacotecurso_cursos_escolhidos").val(data.nomcursosel);

                            }',

                    )

            )); ?>

        </div>    

        

        <div class="row">

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

		<?php echo $form->textArea($model,'cursos_escolhidos', array('rows'=>2, 'cols'=>10, 'class'=>'span4')); ?>

		

	</div>

        

	<div class="row">

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

		<?php echo $form->textField($model,'desconto',array('size'=>10,'maxlength'=>10)); ?>

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

	</div>


	<div class="column">

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

		<?php echo $form->textField($model,'valor_final',array('size'=>10,'maxlength'=>10)); ?>

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

	</div>

Controller


public function actionIncurso()

        {

            $idcursosel = (int)$_POST['pacotecurso']['cursosidcursos'];

            $nomcursosel = curso::model()->findByAttributes(array('idcursos'=>$idcursosel))->nome;

            $valorcurso = curso::model()->findByAttributes(array('idcursos'=>$idcursosel))->valor;

            $valorcursosel = $_POST['pacotecurso']['valor_final'] + $valorcurso;

            

            echo CJSON::encode(array('valor'=>number_format($valorcursosel, 2, ',', '.'), 'nomcursosel'=>$nomcursosel));

        }       

Porém do jeito que está, quando escolho mais de um curso do dropdown ele simplesmente apaga o que estava lá. Preciso que mantenha todos e preciso gravar os ids no banco de dados.

Já pesquisei muito e não achei nada que me ajudasse. Se puderem me dar uma força agradeceria bastante.

Desde já obrigado.


(Newerton Araujo) #2

Ricardo,

Não use textarea, usa <div> para manipular dados em javascript, assim você identificar qual elemento deve ser excluido.

O correto e ir criando um array dos cursos selecionado.


(Ricbhz) #3

Oi Newerton, mais uma vez agradeço pela atenção. Tentei fazer da forma que você sugeriu, mas não funcionou. Teria como dar uma olhada no código abaixo e ver o que estou fazendo de errado? Agradeço muito pela ajuda.


<div class="column">

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

            <?php $this->widget('bootstrap.widgets.TbButton', array(

                    'label'=>'Inserir',

                    'type'=>'success', // null, 'primary', 'info', 'success', 'warning', 'danger' or 'inverse'

                    'size'=>'small', // null, 'large', 'small' or 'mini'

                    'buttonType'=>'ajaxButton',

                    'url' => Yii::app()->createUrl('pacotecurso/incurso'),

                    'ajaxOptions'=>array(

                        'type'=>'POST',

                        'dataType' => 'json',

                        'success' => 'function(data){

                                $("input#pacotecurso_valor_final").val(data.valor);    

                                document.getElementById("escolha").innerHTML += "\\r\\n"+val(data.nomcursosel);

                            }',

                    )

            )); ?>

        </div>    

        

        <div id="escolha">

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

		<?php echo $form->textField($model,'cursos_escolhidos', array('rows'=>2, 'cols'=>10, 'class'=>'span4')); ?>

		

	</div>


(Newerton Araujo) #4

Ricardo,

Primeiramente, como será guardado esse dados? Ele será inserido no banco de dados como texto somente?

Digo isso por que está salvando no textarea.

Observei que ta usando ‘ajaxOptions’, mais não está enviando dados nenhum para sua actionInCursos().

Fiz uma correção no botão, e na sua action.




$this->widget('bootstrap.widgets.TbButton', array(

    'label' => 'Inserir',

    'type' => 'success', // null, 'primary', 'info', 'success', 'warning', 'danger' or 'inverse'

    'size' => 'small', // null, 'large', 'small' or 'mini'

    'buttonType' => 'ajaxButton',

    'url' => Yii::app()->createUrl('pacotecurso/incurso'),

    'ajaxOptions' => array(

        'type' => 'POST',

        'dataType' => 'json',

        'cache' => false,

        'data' => array('id' => "js:$('#pacotecurso_cursosidcursos option:selected').val()", 'valor_final' => "js:$('#pacotecurso_valor_final').val()"),

        'success' => 'function(data){

            $("input#pacotecurso_valor_final").val(data.valor);

            $("textarea#pacotecurso_cursos_escolhidos").val(data.curso);

        }',

    )

));






public function actionIncurso()

{

	if(Yii::app()->request->isAjaxRequest){

		

		$id = (int) $_POST['id'];

		$valor_final = $_POST['valor_final'];

		

		$curso = Curso::model()->find('idcursos = :idcursos', array(':idcursos'=>$id));

		

		$nome = $curso->nome;

		$valor_curso = $curso->valor;

		

		$valor_final = $_POST['valor_final'] + $valor_curso;

		

		$data = array('valor'=>number_format($valor_final, 2, ',', '.'), 'curso'=>$nome);

		

		echo CJSON::encode($data);

	}

} 



Fiz o teste local aqui, o textarea sempre recebe um novo valor, apagando o anterior. Então precisamos saber como irá se salvo no banco de dados, se será salvo como texto, como array ou será salvo em outras tabelas.


(Ricbhz) #5

Oi Newerton, realmente nos meus testes aqui estava ocorrendo exatamente isso, apagando o anterior.

Eu preciso salvar no banco o id dos cursos escolhidos, dentro da tabela pacotecursos. Ou seja, cada novo pacote de cursos terá 1 ou mais ids de cursos escolhidos.


(Ricbhz) #6

Newerton, tentei mais algumas coisas e nada ainda. Você tem mais alguma sugestão do que posso fazer, por favor?

Agradeço muito a ajuda.


(Ricbhz) #7

Pessoal, se alguém tiver alguma dica, puder dar uma força agradeceria bastante. Preciso muito fazer isso e já tentei de diversas formas mas nenhuma resolveu o que preciso. Agradeço pela ajuda, qualquer ajuda é bem vinda!


(Newerton Araujo) #8

Ricardo,

Vamos finaliza isso então.

Você vai precisar somente receber os arquivos em json da sua actionIncurso(), e ir adicionando em uma <div>.

Mais ao adicionar nas <div> você vai precisar adicionar em forma de <input> para que na hora de submeter o formulário, você consiga acessar esse dados.

Vai ser mais ou menos assim:

HTML:


<div id="escolha"></div>

Botão:


$this->widget('bootstrap.widgets.TbButton', array(

    'label' => 'Inserir',

    'type' => 'success', // null, 'primary', 'info', 'success', 'warning', 'danger' or 'inverse'

    'size' => 'small', // null, 'large', 'small' or 'mini'

    'buttonType' => 'ajaxButton',

    'url' => Yii::app()->createUrl('pacotecurso/incurso'),

    'ajaxOptions' => array(

        'type' => 'POST',

        'dataType' => 'json',

        'cache' => false,

        'data' => array('id' => "js:$('#pacotecurso_cursosidcursos option:selected').val()", 'valor_final' => "js:$('#pacotecurso_valor_final').val()"),

        'success' => 'function(data){

			$("div#escolha").append(\'<div><input type="text" name="pacotecurso[cursos_escolhidos][]" id="pacotecurso_cursos_escolhidos" value="\'+data.curso+\'"/><input type="text" name="pacotecurso[valor_final][]" id="pacotecurso_valor_final" value="\'+data.valor+\'"/> \'+ data.curso +\' [<a href="javascript:;" onclick="$(this).parent().remove()">Remover</a>]</div>\');

        }',

    )

));

Neste passo, ele vai adicionar <input> tipo "text", assim você consegue visualizar se está ou não funcionando, se estiver funcionando você muda o type="text" para type="hidden".

Obs.: Verifica os erros em javascript pelo firebug ou console de desenvolvedor do navegador, eu não testei este código.


(Ricbhz) #9

Valeu Newerton, vou fazer os testes e posto depois o resultado. Valeu!


(Ricbhz) #10

Ola Newerton, fiz algumas adaptações, mas do modo como vc colocou funcionou perfeito! Valeu!

Apenas um detalhe…se eu escolher um curso e depois resolver remover ele, ele continua no array, e preciso tirar ele para não gravar no banco. Já tentei várias coisas e não deu certo. Tem ideia de como fazer isso por favor?

Veja na imagem abaixo que mantive escolhido apenas 2 cursos (IDs 1 e 7), mas o curso ID 8 continua lá e quando salvo grava ele no banco.

4214

imagem.png


(Newerton Araujo) #11

Ricardo,

Veja se o <input> que contem o ID do curso e o titulo do curso, está ficando dentro da <div> onde está o botão remover. Por que ao clicar no botão remover, ele apaga a <div> e tudo que está dentro.

Quando adicionar, vai com o firebug na <div id="escolha"></div> e veja o que ele tem la dentro e posta aqui.


(Ricbhz) #12

Perfeito Newerton, era isso mesmo. Você é o cara! Valeu! Apenas mais um detalhe…dentro da actionIncurso eu preciso pegar os dados no array pacotecurso[valor_curso] dos cursos escolhidos, para totalizar pois do modo como esta atualmente se o usuario exclui algum curso ele não tira este valor do total. Mas não estou conseguindo pegar este valor pelo $_POST[pacotecurso][valor_curso] creio eu porque o botão criado enviado pelo post apenas o ID do curso e o valor individual do curso escolhido. Pensei em mandar estes valores em array mesmo pelo botão, mas não sei se é a melhor opção.

Você tem alguma ideia melhor de como posso fazer isso? Agradeço mais uma vez pela atenção e ajuda.


(Newerton Araujo) #13

Ricardo,

Botão:


$this->widget('bootstrap.widgets.TbButton', array(

    'label' => 'Inserir',

    'type' => 'success', // null, 'primary', 'info', 'success', 'warning', 'danger' or 'inverse'

    'size' => 'small', // null, 'large', 'small' or 'mini'

    'buttonType' => 'ajaxButton',

    'url' => Yii::app()->createUrl('pacotecurso/incurso'),

    'ajaxOptions' => array(

        'type' => 'POST',

        'dataType' => 'json',

        'cache' => false,

        'data' => array('id' => "js:$('#pacotecurso_cursosidcursos option:selected').val()", 'valor_final' => "js:$('#pacotecurso_valor_final').val()"),

        'success' => 'function(data){

						var valor_final = $('input#pacotecurso_valor_final'); //Identificando o campo que receberá o valor da somatória

						var valor_curso = data.valor; //Valor do curso adicionado

						var total = parseFloat(valor_final.val() + valor_curso); //Somatoria do total, mais o valor do curso

						valor_final.val(total.toFixed(2)); //Adicionando a somatoria no campo, já fixado para 2 campos decimais

						

                        $("div#escolha").append(\'<div><input type="text" name="pacotecurso[cursos_escolhidos][]" id="pacotecurso_cursos_escolhidos" value="\'+data.curso+\'"/><input type="text" name="pacotecurso[valor_curso][]" id="pacotecurso_valor_curso" value="\'+valor_curso+\'"/> \'+ data.curso +\' [<a href="javascript:;" onclick="remover_curso">Remover</a>]</div>\');

						

						

        }',

    )

));

Ao adicionar cada curso na listagem, ele já vai colocando os valores da somatória no campo. Observa que eu alterei o botão de remover o curso.

Evento que fará a subtração, na hora de remover o curso da listagem.


jQuery('a#remover_curso').live('click', function(){

	var valor_final = $('input#pacotecurso_valor_final');

	var valor_curso = $(this).find('input#pacotecurso_valor_curso').val();

	var total = parseFloat(valor_final.val() - valor_curso); //Somatoria do total, mais o valor do curso

	valor_final.val(total.toFixed(2)); //Adicionando a somatoria no campo, já fixado para 2 campos decimais

	

	$(this).parent().remove();						

});

Testa ae, e veja se fico bom.


(Ricbhz) #14

Olá Newerton, funcionou em partes. Ele inclui o curso na div, mas não faz a soma. Ele pega apenas o valor do primeiro cursos escolhido e depois não soma mais, e o botão de remover não funciona. Olhe na imagem abaixo se tem ideia do que posso estar fazendo errado. Muito obrigado!

4223

erro_yii.png


(Newerton Araujo) #15

Ricardo,

Faça por partes, primeiro seleciona 2 curso, e veja se está somando, se não, olha na aba Console do Firebug, e veja se tem erro de javascript, se não tiver, debuga linha por linha.

Faz assim para cada linha:


var valor_final = $('input#pacotecurso_valor_final');

console.log(valor_final);

Ao adicionar o 1º curso, aparecer 0/undefined/vazio ta correto, agora na hora de adicionar o segundo curso no valor de 1032.44 aparecer o 900 ta correto, ai você vai para a próxima variável valor_curso, depois testa a variável total.

Precisa debugar para ver onde está o erro, se é na soma, ou na obtenção dos dados.


(Ricbhz) #16

Newerton,

Parece que o erro está na soma, porque veja o console do firebug.

4246

erro001.png

Este resultado aparece quando debugo variavel total (console.log(total)).


(Newerton Araujo) #17

Muda a linha para:


var total = parseFloat(valor_final.val()) + parseFloat(valor_curso);


(Ricbhz) #18

Mudei a linha conforme mencionado e retornou o valor NaN.

Aproveitando, outra coisa, quando tento remover algum curso aparece o erro "ReferenceError: remover_curso is not defined". Coloquei assim no _form:


Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.'/js/remover_curso.js');

Tem algo errado? Abaixo imagens com estas informações.

4271

erro_sis.png


(Ricbhz) #19

Oi Newerton, já tentei outras formas aqui e continua com os mesmos problemas. Se tiver alguma dica a mais…agradeço muito pela ajuda!