GO
TDBCheckGroup com critério de filtro baseado em TDBCombo
Olá amigos, bom dia!
Estou caminhando no desenvolvimento do meu primeiro projeto usando o Adianti mas parei em uma dúvida. Estou desenvolvendo um formulário onde eu cadastro um arquivo que pode ser uma imagem ou um vídeo e esse arquivo deve pertencer a um cliente que seleciono com um TDBCombo. Devo apresentar em um TDBCheckGroup todos os dispositivos "TV's" onde esse arquivo será exibido porém só posso apresentar os dispositivos que pertencem ao cliente escolhido no cadastro do arquivo. Isso deveria ser dinâmico e sei que pra isso existe o setChangeAction e setChangeFunction porém não sei realimentar o TDBCheckGroup de forma dinâmica.
Segue o meu código e uma imagem do formulário que estou montando:
Estou caminhando no desenvolvimento do meu primeiro projeto usando o Adianti mas parei em uma dúvida. Estou desenvolvendo um formulário onde eu cadastro um arquivo que pode ser uma imagem ou um vídeo e esse arquivo deve pertencer a um cliente que seleciono com um TDBCombo. Devo apresentar em um TDBCheckGroup todos os dispositivos "TV's" onde esse arquivo será exibido porém só posso apresentar os dispositivos que pertencem ao cliente escolhido no cadastro do arquivo. Isso deveria ser dinâmico e sei que pra isso existe o setChangeAction e setChangeFunction porém não sei realimentar o TDBCheckGroup de forma dinâmica.
Segue o meu código e uma imagem do formulário que estou montando:
- <?php
- /**
- * ArquivoForm Form
- * @author <your name here>
- */
- class ArquivoForm extends TPage
- {
- protected $form; // form
- private $formFields = [];
- private static $database = 'GestaoMedia';
- private static $activeRecord = 'Arquivo';
- private static $primaryKey = 'id';
- private static $formName = 'list_Arquivo';
- /**
- * Form constructor
- * @param $param Request
- */
- public function __construct( $param )
- {
- parent::__construct();
- // creates the form
- $this->form = new BootstrapFormBuilder(self::$formName);
- // define the form title
- $this->form->setFormTitle('Arquivo');
- $id = new TEntry('id');
- $ativo = new TRadioGroup('ativo');
- $cliente_id = new TDBCombo('cliente_id', 'GestaoMedia', 'Cliente', 'id', '{razao}','razao asc' );
- $cliente_id->setChangeFunction('onChangeCliente');
- $titulo = new TEntry('titulo');
- $descricao = new TEntry('descricao');
- $data_hora_inicio = new TDateTime('data_hora_inicio');
- $data_hora_fim = new TDateTime('data_hora_fim');
- $segundos_tela = new TEntry('segundos_tela');
- $repeticoes = new TEntry('repeticoes');
- $data_envio = new TDateTime('data_envio');
- $nome_arquivo = new TFile('nome_arquivo');
- $nome_arquivo->setCompleteAction(new TAction(array($this, 'onComplete')));
- // Preciso criar um filtro
- //$criteria = new TCriteria;
- //$criteria->add(new TFilter('id', 'IN', '(SELECT id FROM dispositivos where cliente_id = 0 )'));
- $dispositivos = new TDBCheckGroup('dispositivos', 'GestaoMedia', 'Dispositivo', 'id', 'nome_dispositivo');
- $dispositivos->setLayout('horizontal');
- $dispositivos->setBreakItems(4);
- $ativo->addValidation('Ativo', new TRequiredValidator());
- $cliente_id->addValidation('Id do cliente', new TRequiredValidator());
- $titulo->addValidation('Titulo', new TRequiredValidator());
- //$descricao->addValidation('Descrição', new TRequiredValidator());
- $data_hora_inicio->addValidation('Inicio da apresentação', new TRequiredValidator());
- $data_hora_fim->addValidation('Fim da apresentação', new TRequiredValidator());
- $segundos_tela->addValidation('Segundos na tela', new TRequiredValidator());
- $repeticoes->addValidation('Repetições', new TRequiredValidator());
- $nome_arquivo->addValidation('Nome do Arquivo', new TRequiredValidator());
- $data_envio->addValidation('Data de envio', new TRequiredValidator());
- $id->setEditable(false);
- $ativo->addItems(['1'=>'Sim','2'=>'Não']);
- $ativo->setLayout('horizontal');
- $ativo->setBooleanMode();
- $ativo->setValue('1');
- $segundos_tela->setValue('1');
- $titulo->forceUpperCase();
- $descricao->forceUpperCase();
- //$nome_arquivo->forceUpperCase();
- $data_envio->setDatabaseMask('yyyy-mm-dd hh:ii');
- $data_envio->setEditable(false);
- $data_hora_fim->setDatabaseMask('yyyy-mm-dd hh:ii');
- $data_hora_inicio->setDatabaseMask('yyyy-mm-dd hh:ii');
- $repeticoes->setMask('99');
- $repeticoes->setValue('0');
- $segundos_tela->setMask('999');
- $data_envio->setMask('dd/mm/yyyy hh:ii');
- $data_hora_fim->setMask('dd/mm/yyyy hh:ii');
- $data_hora_inicio->setMask('dd/mm/yyyy hh:ii');
- $id->setSize(92);
- $ativo->setSize(80);
- $titulo->setSize('100%');
- $data_envio->setSize(150);
- $descricao->setSize('100%');
- $cliente_id->setSize('100%');
- $data_hora_fim->setSize(150);
- $repeticoes->setSize('100%');
- $nome_arquivo->setSize('100%');
- $data_hora_inicio->setSize(150);
- $segundos_tela->setSize('100%');
- if (!empty($id))
- {
- $id->setEditable(FALSE);
- }
- $this->form->addFields([new TLabel('id:')],[$id],[new TLabel('Ativo:', '#ff0000')],[$ativo]);
- $this->form->addFields([new TLabel('Cliente:', '#ff0000')],[$cliente_id]);
- $this->form->addFields([new TLabel('Titulo:', '#ff0000')],[$titulo]);
- $this->form->addFields([new TLabel('Descrição:')],[$descricao]);
- $this->form->addFields([new TLabel('Inicio da apresentação:', '#ff0000')],[$data_hora_inicio],[new TLabel('Fim da apresentação:', '#ff0000')],[$data_hora_fim]);
- $this->form->addFields([new TLabel('Segundos na tela:', '#ff0000')],[$segundos_tela],[new TLabel('Repetições:', '#ff0000')],[$repeticoes]);
- $this->form->addFields([new TLabel('Pesquisa (*.png/*.jpg/*.mp4):', '#ff0000')],[$nome_arquivo]);
- $this->form->addFields([new TLabel('Data de envio:', '#ff0000')],[$data_envio]);
- $this->form->addContent([new TFormSeparator('Visualização do arquivo carregado', '#333333', '18', '#eeeeee')]);
- // Preview da imagem
- $this->frame = new TElement('div');
- $this->frame->id = 'photo_frame';
- $this->frame->style = 'width:400px;height:auto;min-height:200px;border:1px solid gray;padding:4px;margin:auto';
- $this->form->addContent([$this->frame]);
- $this->form->addContent([new TFormSeparator('Dispositivos onde o arquivo será exibido', '#333333', '18', '#eeeeee')]);
- $this->form->addFields([$dispositivos]);
- // create the form actions
- $btn_onsave = $this->form->addAction('Salvar', new TAction([$this, 'onSave']), 'fa:floppy-o #ffffff');
- $btn_onsave->addStyleClass('btn-primary');
- $btn_onclear = $this->form->addAction('Limpar formulário', new TAction([$this, 'onClear']), 'fa:eraser #dd5a43');
- $btn_onReload = $this->form->addAction(_t('Back to the listing'), new TAction(['ArquivoList','onReload']), 'fa:table blue' );
- // vertical box container
- $container = new TVBox;
- $container->style = 'width: 100%';
- $container->class = 'form-container';
- // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
- $container->add($this->form);
- parent::add($container);
- }
- /**
- * On complete upload
- */
- public static function onComplete($param)
- {
- TScript::create("$('#photo_frame').html('')");
- TScript::create("$('#photo_frame').append(\"<img style='width:100%' src='tmp/{$param['nome_arquivo']}'>\");");
- // Tentativa de alterar a data de envio da imagem após fazer o carregamento
- //$data_envio->setValue(date("d-m-Y H:i"));
- /*
- Esse if é importante mas não está funcionando
- if ((strpos($param["nome_arquivo"],'.png')) && (strpos($param["nome_arquivo"],'.PNG')) && (strpos($param["nome_arquivo"],'.jpg')) && (strpos($param["nome_arquivo"],'.JPG'))){
- print_r($param["nome_arquivo"]);
- TScript::create("$('#photo_frame').html('')");
- TScript::create("$('#photo_frame').append(\"<img style='width:100%' src='tmp/{$param['nome_arquivo']}'>\");");
- }*/
- }
- public function onSave($param = null)
- {
- try
- {
- TTransaction::open(self::$database); // open a transaction
- /**
- // Enable Debug logger for SQL operations inside the transaction
- TTransaction::setLogger(new TLoggerSTD); // standard output
- TTransaction::setLogger(new TLoggerTXT('log.txt')); // file
- **/
- $messageAction = null;
- $this->form->validate(); // validate form data
- $object = new Arquivo(); // create an empty object
- $data = $this->form->getData(); // get form data as array
- $object->fromArray( (array) $data); // load the object with data
- $object->store(); // save the object
- if ($data->dispositivos)
- {
- foreach ($data->dispositivos as $dispositivo_id)
- {
- TTransaction::open('GestaoMedia');
- $dispositivo = Dispositivo::find($dispositivo_id);
- //var_dump($dispositivo);
- TTransaction::close();
- $object->addArquivoDispositivo( $dispositivo );
- }
- }
- $source_file = 'tmp/'.$object->nome_arquivo;
- $target_file = 'files/'.$object->id.'-'.$object->nome_arquivo;
- //var_dump($target_file);
- if (file_exists($source_file))
- {
- rename($source_file, $target_file);
- }
- // get the generated {PRIMARY_KEY}
- $data->id = $object->id;
- $this->form->setData($data); // fill form data
- TTransaction::close(); // close the transaction
- // refresh photo_frame
- TScript::create("$('#photo_frame').html('')");
- $nome_arquivo = $param['id'].'-'.$param['nome_arquivo'];
- var_dump($nome_arquivo);
- TScript::create("$('#photo_frame').append(\"<img style='width:100%' src='files/{$nome_arquivo}'>\");");
- /**
- // To define an action to be executed on the message close event:
- $messageAction = new TAction(['className', 'methodName']);
- **/
- new TMessage('info', AdiantiCoreTranslator::translate('Record saved'), $messageAction);
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage()); // shows the exception error message
- $this->form->setData( $this->form->getData() ); // keep form data
- TTransaction::rollback(); // undo all pending operations
- }
- }
- /**
- * Clear form data
- * @param $param Request
- */
- public function onClear( $param )
- {
- $this->form->clear();
- }
- public function onEdit( $param )
- {
- try
- {
- if (isset($param['key']))
- {
- $key = $param['key']; // get the parameter $key
- TTransaction::open(self::$database); // open a transaction
- $object = new Arquivo($key); // instantiates the Active Record
- $object->dispositivos = $object->getArquivoDispositivosIds(); // Recuperando o ID de cada dispositivo
- $this->form->setData($object); // fill the form
- TTransaction::close(); // close the transaction
- if ($object)
- {
- $image = new TImage('files/'.$object->id.'-'.$object->nome_arquivo);
- $image->style = 'width: 100%';
- $this->frame->add( $image );
- }
- }
- else
- {
- $this->form->clear();
- }
- }
- catch (Exception $e) // in case of exception
- {
- new TMessage('error', $e->getMessage()); // shows the exception error message
- TTransaction::rollback(); // undo all pending operations
- }
- }
- public function onChangeCliente()
- {
- new TMessage('info','Preciso realimentar o TDBCheckGroup ');
- }
- }
O TDBCheckGroup ainda não possui uma função para carregamento estático. Vejo 2 soluções:
1 - Usar javascript para adicionar os itens.
2 - Usar o conceito de adianti_target_container. Nesse caso você criaria uma outra classe somente para renderizar os checks. Veja o exemplo abaixo:
adianti.com.br/framework_files/tutor/index.php?class=SaleMasterForm
Nesse exemplo são usadas 2 classes, a SaleMasterForm que monta o formulário master e a classe SaleDetailForm, responsável pelos detalhes. A mágica está no adianti_target_container = 'details_area', presente na classe SaleDetailForm. Isso informa ao framework que somente o container com esse id deve ser redesenhado.
Olá Nataniel, boa tarde!
Não consegui visualizar as duas classes no exemplo do tutor. Só consigo visualizar a classe SaleDetailForm. Tenho uma classe agregada à classe Arquivo que é a classe Dispositivo e eu gravo no banco os arquivos
Olá Nataniel, boa tarde!
Tenho uma classe agregada à classe Arquivo que é a classe Dispositivo mas o componente TDBCheckGroup é adicionado ao form arquivo e por isso ele é persistido junto com o arquivo. Estou pensando em separar e tratar do mestre e do detalhe de forma diferente pois não estou conseguindo implementar da forma que queria. Não consegui visualizar as duas classes no exemplo do tutor. Só consigo visualizar a classe SaleDetailForm. Uma outra opção seria trocar o componente onde apresento a agregação por um componente que possua o método reload. O que ficaria melhor para o meu caso de uso?
Tenho aqui o método que funciona e gostaria de uma sugestão de outro componente caso o TDBCheckGroup não consiga ser carregado de forma dinâmica.
Alguém mais poderia me ajudar?
<? php
static function onChangeCliente($params)
{
if( isset($params['cliente_id']) && $params['cliente_id'] )
{
try
{
$dispositivos_id = array();
TTransaction::open('GestaoMedia');
$dispositivos = Dispositivo::where('cliente_id','=',$params['cliente_id'])->load();
foreach ($dispositivos as $dispositivo)
{
//Tenho aqui os dados dos dispositivos agregados.
// Como recarregar o componente TDBCheckGroup ?
$dispositivos_id[] = $dispositivo->id;
}
TTransaction::close();
}
catch (Exception $e) // in case of exception
{
new TMessage('error', $e->getMessage());
TTransaction::rollback();
}
}
}
?>
Geovani, você pode baixar o tutor e procurar pela classe SaleMasterForm. Basicamente ela cria uma div com o mesmo id que é definido pela variável adianti_target_container na classe SaleDetailForm. É essa div que vai ter seu conteúdo redesenhado a cada troca de cliente.
Olá amigo, bom dia!
Como estava enfrentando muitas dificuldades com o componente resolvi trocar e usar o TDBSelect e está funcionando perfeitamente porém gostaria de mudar a aparência do mesmo.
Seria possível usando métodos do Adianti?