
Frank K Hosaka
Membros-
Total de itens
1.622 -
Registro em
-
Última visita
Tudo que Frank K Hosaka postou
-
Melhor que o atalho de teclado é o JavaScript. Hoje eu conheci o comando scrollIntoView( ), ele mostra o final da página, mas quando o <input> recebe o foco, o final da página some. Mas pelo menos o <input> fica sempre disponível no rodapé do navegador, principalmente quando a listagem é bem longa: arquivo lprevisao.blade.php (parcial) foreach($mercado as $m) <div class="flex odd:bg-gray-200 w-[350px]"> <div class="w-[100px] text-right">{{ dec($m->venda) }}</div> <div class="w-[100px] text-right">{{ dec($m->tarifa) }}</div> <div wire:click="excluir({{$m->id}})" class="w-[100px] text-right text-gray-500 font-semibold"> {{ dec($m->conta) }} </div> </div> @endforeach <div class=flex> <input id=venda wire:model="venda" class="w-[100px] text-right border border-gray-300 rounded-sm" autofocus> <input wire:model="tarifa" wire:change="incluir" onchange="venda.focus();ttarifa.scrollIntoView()" class="w-[100px] text-right border border-gray-300 rounded-sm"> </div> <div wire:click="registrar" class="flex odd:bg-gray-200 w-[350px] font-semibold"> <div class="w-[100px] text-right text-gray-500 font-semibold"> {{ dec($total->tvenda) }} </div> <div id=ttarifa class="w-[100px] text-right font-semibold">{{ dec($total->ttarifa) }}</div> <div class="w-[100px] text-right font-semibold">{{ dec($total->tconta) }}</div> </div>
-
HTML é uma linguagem que eu não domino, apesar de mexer com o PHP desde 2020. Hoje estou estudando o Livewire, mas tem uma rotina que eu chamei de previsão e queria dar um jeito de olhar o final da página. A maneira mais simples é a barra de rolagem no canto direito do navegador, mas o mouse está a vários quilômetros do destino e o pior é ter que fazer todo o caminho de volta. Assim, pensei em criar um atalho. Eu improvisei o seguinte código em PHP, não sei se vai funcionar lá no Livewire: <?php $mysqli = new mysqli("localhost", "root", "", "diario"); $produtos = $mysqli->query("SELECT * FROM tbprod LIMIT 30"); ?> <script src="https://cdn.tailwindcss.com"></script> <body class="min-h-screen flex flex-col justify-end"> <main class="flex flex-col gap-2"> <?php foreach($produtos as $index => $p): ?> <div class="px-2"><?=$p['prod']?></div> <?php if($index==10): ?> <a class="px-2 font-bold" href=#fimDaPagina>Ir para o final</a> <?php endif; endforeach; ?> </main> <div id="fimDaPagina"></div> </body> Esse é um péssimo exemplo de programação, o comando Ir para o final ficou bem no meio da listagem de produtos, o correto era colocar na barra de navegação, mas o meu conhecimento em HTML é precário, não sei como fixar a barra de navegação no topo da tela. A maneira mais fácil de chegar no fim de uma página é usando atalho de teclado. A maioria dos PCs usa CTRL + END. O meu é um notebook Galaxy Book S com Windows 11, usei Fn + flecha para baixo.
-
Antes do Laravel 12 eu usei o marcador <form><input></form>. O Livewire também tem o marcador <form>, mas eu ainda não sei como usá-lo, mas eu sei que o Livewire consegue trabalhar com o valor do <input wire:model="inputQt"> em conjunto com a variável pública $inputQt através do processo da "hidratação". O problema é que eu trabalho com o MySQL e tenho que mexer com vários registros e depois de muitas tentativas eu consegui casar o wire:model com os registros. Mas hoje estava brincando com o modal, e achei bem mais fácil trabalhar com um wire:model do que um monte deles: Esse é um trecho da view que chama a função wire:click="nfQt(...)" <!-- parte do blade --> @if($modal2) <div class="fixed inset-0 flex items-center justify-center"> <div class="bg-white p-6 rounded shadow-lg text-center border-8 border-gray-500"> <div>Qt anterior: {{ $qt }}</div> <div>Qt atual: </div> <input wire:model="inputQt" autofocus class=px-2> <button wire:click="nfQt({{$custoTotal}},{{$qt}},{{$codprod}},{{true}})" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded"> Alterar </button> <button wire:click="$set('modal2', false)" class="mt-2 bg-red-500 text-white px-4 py-2 rounded"> Cancelar </button> </div> </div> @endif <!-- outra parte do mesmo blade --> @foreach($previa as $p) <div class="flex odd:bg-gray-200"> <div class="w-[80px] text-right truncate">{{$p->codforn}}</div> <div class="w-[50px] text-right">{{$p->codprod}}</div> <div class="w-[318px] ml-2 truncate">{{$p->prod}}</div> <div wire:click="nfQt({{$p->custototal}},{{$p->qt}},{{$p->codprod}})" class="w-[50px] text-right"> {{ $p->qt }} </div> <div {!! $p->class !!} wire:click="atualizar({{$p->custoatual}},{{$p->custoanterior}},{{$p->codprod}})"> {{ dec($p->custoatual) }} </div> <div class="w-[70px] text-right">{{ dec($p->custototal) }}</div> </div> @endforeach Esse é o trecho do componente que executa o método nfQt(...), note que esse método serve tanto para chamar o modal bem como executar o resto do serviço, dependendo da escolha do usuário: <?php // ... function nfQt($custoTotal,$qt,$codprod,$executar = false) { if($executar) { $this->modal2=false; $novoCusto=round($custoTotal/$this->inputQt,2); $custoAnterior=tbprod::where('codprod',$codprod) ->value('custo'); if($novoCusto==$custoAnterior) { $class = "class='w-[70px] text-right'"; } else { $class = "class='w-[70px] text-right text-red-500'"; } tbnf::where('codprod',$codprod) ->update(['qt'=>$this->inputQt,'custoatual'=>$novoCusto, 'custoanterior'=>$custoAnterior,'class'=>$class]); $this->previa=tbnf::all(); } else { $this->custoTotal=$custoTotal; $this->qt=$qt; $this->codprod=$codprod; $this->modal2=true; } }
-
Não consegui usar a tecnologia Livewire com o marcador <details>, assim eu improvisei com um $modal. O seguinte código funciona no ambiente Hostinger: Lpessoas.php <?php namespace App\Livewire; use App\Models\tbpessoa; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['titulo'=>'Pessoas'])] class Lpessoa extends Component { public $modal, $pessoas; function definirModal($i) { $this->modal=$i; } function mount() { $this->pessoas=tbpessoa::orderBy('pessoa') ->take(10)->get()->toArray(); } } ?> lpessoa.blade.php <div> @foreach($pessoas as $i => $pessoa) <div class="odd:bg-gray-200 flex"> <div class="w-[60px] text-right px-2">{{ $pessoas[$i]['codp'] }}</div> <div wire:click="definirModal({{$i}})"> @if($pessoa['vinculo']) <svg width="16" height="16" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="50,75 25,25 75,25" style="fill:red;" /></svg> @else <svg width="16" height="16" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><polygon points="50,75 25,25 75,25" style="fill:black;" /></svg> @endif </div> <input wire:model="pessoas.{{$i}}.pessoa" class="px-2" /> </div> @if($modal===$i) // aqui usei o operador estritamente igual === para diferenciar o null de 0 <div class=flex> <div class=font-semibold>Endereço:</div> <input wire:model="pessoas.{{$i}}.end" class="px-2" /> </div> <div class=flex> <div class=font-semibold>CPF CNPJ:</div> <input wire:model="pessoas.{{$i}}.cnpj" class="px-2" /> </div> <div class=flex> <div class=font-semibold>Telefone:</div> <input wire:model="pessoas.{{$i}}.tel" class="px-2" /> </div> <div class=flex> <div class=font-semibold>Nota:</div> <input wire:model="pessoas.{{$i}}.nota" class="px-2" /> </div> <div class=flex> <div class=font-semibold>Vínculo:</div> <input wire:model="pessoas.{{$i}}.vinculo" class="px-2" /> </div> @endif @endforeach </div>
-
Finalmente, consegui trabalhar com o wire:model do Livewire com o MySQL. O Copilot me ajudou bastante a criar o código sem receber a mensagem "Livewire encountered corrupted data" no Hostinger: Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Livewire\Component; class Lteste extends Component { public $previsao; function mount() { $this->previsao =tbprevisao::orderBy('conta') ->take(3)->get()->toArray(); } function updated($propertyName) { $parts=explode(".",$propertyName); $index=$parts[1]; $id=$this->previsao[$index]['id']; $valor=data_get($this,$propertyName); tbprevisao::where('id',$id) ->update(['valor'=>$valor]); } } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="previsao.0.valor" wire:change="$refresh" /> <flux:input wire:model="previsao.1.valor" wire:change="$refresh" /> <flux:input wire:model="previsao.2.valor" wire:change="$refresh" /> <pre>{{ print_r($previsao) }}</pre> </div>
-
Testando um objeto: Lteste.php <?php namespace App\Livewire; use Livewire\Component; class Lteste extends Component { public $objeto = ['vetor' => [1,2,3]]; } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="objeto.vetor.0" wire:change="$refresh" /> <flux:input wire:model="objeto.vetor.1" wire:change="$refresh" /> <flux:input wire:model="objeto.vetor.2" wire:change="$refresh" /> <pre>{{ print_r($objeto['vetor']) }}</pre> </div>
-
Eu já aprendi que o meu código no notebook nem sempre funciona no Hostinger. Hoje eu decidi estudar o Livewire diretamente no Hostinger, usando o file manager do CloudPanel. Esse é o meu primeiro código, por enquanto não recebi nenhuma mensagem de erro: Lteste.php <?php namespace App\Livewire; use Livewire\Component; class Lteste extends Component { public $vetor=[1,2,3]; } lteste.blade.php <div class="w-[100px]"> <flux:input wire:model="vetor.0" wire:change="$refresh" /> <flux:input wire:model="vetor.1" wire:change="$refresh" /> <flux:input wire:model="vetor.2" wire:change="$refresh" /> <div>{{ $vetor[0]." ".$vetor[1]." ".$vetor[2] }}</div> </div>
-
Eu publiquei a minha dúvida no fórum do Laracasts.com, mas eu tenho pouca esperança. Enquanto isso, pensei em transformar o Livewire num roteador, ficou uma grande gambiarra, mas pelo menos funciona no Hostinger: arquivo app > Livewire > Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Illuminate\Support\Facades\DB; use Livewire\Component; class Lteste extends Component { public $id,$modal,$previsoes; function mount() { if(request()->input("novoValor")){ if(session()->has('id')){ $this->id=session('id'); } $this->modal=false; $valor=deca(request()->input("novoValor")); tbprevisao::where('id',$this->id)->update(['valor'=>$valor]); } if(request()->input("id")){ $this->modal=true; $this->id=request()->input("id"); session(['id'=>$this->id]); } $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } } arquivo resources > views > livewire > lteste.blade.php <div> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right">Conta</div> <div class="w-[188px] px-2">Descricao</div> <div class="w-[130px] text-right">Previsão</div> <div class="w-[130px] text-right">Diario</div> <div class="w-[130px] text-right">Divergência</div> </div> @foreach($previsoes as $p) <div class="odd:bg-gray-200 flex"> <div class="w-[50px] text-right">{{$p->conta}}</div> <div class="w-[188px] px-2 truncate">{{$p->descricao}}</div> @if($modal && $id == $p->id) <div class="w-[130px] text-right border border-black"> <form><input name="novoValor" wire:on class="w-[130px]" /></form> </div> @else <a href="?id={{$p->id}}" class="w-[130px] text-right">{{dec($p->valor)}}</a> @endif <div class="w-[130px] text-right">{{dec($p->fim)}}</div> <div class="w-[130px] text-right"> {{dec(abs(round($p->valor - $p->fim + 0.0001,2)))}} </div> </div> @endforeach </div>
-
O código a seguir funciona no meu Window 11 / Apache. Na Hostinger Ubuntu / nginx, eu recebo a mensagem no web console assim: https://meusite/livewire/update, ele aparece na lista do php artisan list:route, eu só não sei como ver se o Laravel tem condição de ver essa pasta no ambiente do Hostinger, pelo menos eu não consigo ver essa pasta nem aqui no Windows. Acredito que esse é um dos melhores códigos que eu já fiz, é uma pena que não funciona na Hostinger: arquivo app > Livewire > Lteste.php <?php namespace App\Livewire; use App\Models\tbprevisao; use Illuminate\Support\Facades\DB; use Livewire\Component; class Lteste extends Component { public $id,$novoValor,$modal,$previsoes; function update() { $this->modal = false; $valor=deca($this->novoValor); tbprevisao::where('id',$this->id)->update(['valor'=>$valor]); $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } function mount() { $this->previsoes=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } function selecionado($id) { $this->id = $id; $this->modal = true; } } arquivo resources > views >livewire > lteste.blade.php <div> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right">Conta</div> <div class="w-[188px] px-2">Descricao</div> <div class="w-[130px] text-right">Previsão</div> <div class="w-[130px] text-right">Diario</div> <div class="w-[130px] text-right">Divergência</div> </div> @foreach($previsoes as $p) <div class="odd:bg-gray-200 flex" wire:click="selecionado({{ $p->id }})"> <div class="w-[50px] text-right">{{$p->conta}}</div> <div class="w-[188px] px-2 truncate">{{$p->descricao}}</div> @if($modal && $id == $p->id) <div class="w-[130px] text-right"> <flux:input wire:model="novoValor" wire:change="update" size="xs" /> </div> @else <div class="w-[130px] text-right">{{dec($p->valor)}}</div> @endif <div class="w-[130px] text-right">{{dec($p->fim)}}</div> <div class="w-[130px] text-right"> {{dec(abs(round($p->valor - $p->fim + 0.0001,2)))}} </div> </div> @endforeach </div>
-
Eu tenho uma rotina chamada previsão que funciona no meu notebook, mas lá na Hostinger apareceu uma estranha mensagem "Livewire encountered corrupt data". Passei horas estudando o código, mas não consegui achar o problema. Na internet encontrei algumas mensagens reclamando que o "wire:model" não funciona adequadamente com o array e alguém sugeriu usar a propriedade protected na variável ao invés do public. Até que eu tentei, mas não funcionou. A minha única saída provisória foi usar o <form>, mas eu só encontrei exemplo usando apenas um <form> e não um monte delas. Eu improvisei assim: arquivo resources > views > livewire > lprevisão.blade.php <?php foreach($painel as $key => $p): ?> <div class="flex odd:bg-gray-200"> <div class="w-[50px] text-right"><?=$p->conta?></div> <div class="w-[188px] px-2 truncate"><?=$p->descricao?></div> <div class="w-[130px] py-0"> <form > <input name='{{$p->conta}}' class="w-[130px] text-right py-0 border-none" value='{{dec($p->valor)}}' wire:change="atualizar({{$p->conta}})"> </form> </div> <div class="w-[130px] text-right"><?=dec($p->fim)?></div> <div class="w-[130px] text-right"> <?=dec(abs(round($p->valor - $p->fim + 0.0001,2)))?> </div> </div> <?php endforeach;?> O comando wire:change não funciona como eu esperava, mas ele conseguiu simular o botão "submit", e assim eu consegui jogar no cabeçalho do navegador algo do tipo lteste?112=70. 112 é o número da conta que usei para dar o nome ao <input> e 70 é o número que eu digitei no <input>. Como o comando wire:change não funciona, a minha pergunta foi: e agora, como faço para pegar o número que eu digitei? A minha intuição mandou pegar a função mount( ) no componente, assim: arquivo app > Livewire > Lprevisao.php <?php //... function mount() { if(request()->input()){ foreach(request()->input() as $conta => $valor){} $valor=deca($valor); tbprevisao::where('conta',$conta)->update(['valor'=>$valor]); } $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); } E aqui é só gambiarra, usei o mount( ) como uma espécie de roteador, ele pega o conteúdo do cabeçalho pelo request()->input(), depois joga a chave na variável $conta e o conteúdo na variável $valor através do comando foreach( ) que não faz absolutamente nada { }, mas consegue pegar o conteúdo do cabeçalho e jogar nas variáveis. Isso é um péssimo exemplo de programação. A ideia deu certo lá no Hostinger, mas o Livewire não foi feito para usar o <form>, mas a gambiarra deu certo. A mágica do Livewire está no componente wire:model, fazer isso funcionar com o array que é o problema.
-
arquivo resources > views > livewire > lteste.blade.php <div> <div class="mt-5 flex"> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 1</flux:input.group.prefix> <flux:input wire:model="teste" placeholder="Olá mundo" /> </flux:input.group> </div> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 2</flux:input.group.prefix> <flux:input wire:model="teste2" placeholder="Olá mundo" /> </flux:input.group> </div> <div class="w-[200px] px-2"> <flux:input.group> <flux:input.group.prefix>Label 3</flux:input.group.prefix> <flux:input wire:model="teste3" placeholder="Olá mundo" /> </flux:input.group> </div> </div> </div>
-
arquivo resources > views > livewire > ldiario-lcto.blade.php (parcial) <flux:field> <div class="w-[130px]""> <flux:input.group> <flux:input.group.prefix>Dia</flux:input.group.prefix> <flux:input type="date" wire:model="dia" wire:change="data" onclick=this.showPicker() /> </flux:input.group> </div> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>Lçto</flux:input.group.prefix> <flux:input wire:model="lcto" onclick=this.showPicker() /> </flux:input.group> </div> <div class="flex items-center"> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>ContaD</flux:input.group.prefix> <flux:input wire:model="ctaD" wire:click="abrirModal('ctaD')" /> </flux:input.group> </div> <div class='px-2'>{{$descD}}</div> </div> <div class="flex items-center"> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>ContaC</flux:input.group.prefix> <flux:input wire:model="ctaC" wire:click="abrirModal('ctaC')" /> </flux:input.group> </div> <div class='px-2'>{{$descC}}</div> </div> <div class="w-[130px]"> <flux:input.group> <flux:input.group.prefix>Valor</flux:input.group.prefix> <flux:input wire:model="valor" /> </flux:input.group> </div> <div> <flux:input.group> <flux:input.group.prefix>Histórico</flux:input.group.prefix> <flux:input wire:model="hist" /> </flux:input.group> </div> <div class="w-[130px]"> <flux:button wire:click="salvar" variant="primary"> Registrar </flux:button> </div> </flux:field>
-
Hoje de manhã pensei em instalar uma rotina para acrescentar um registro contábil, mas na hora de testar o modal do plano de contas não funcionou. No console da web, eu só vi a mensagem de que o problema é o livewire.js, isso não ajuda nada. Não tive outra escolha, senão começar do zero. Deixei vazio o arquivo app.livewire.LdiarioLcto.php e o arquivo resources.views.livewire.ldiario-lcto.blade.php, e o primeiro que reclamou foi o roteador web.php. Defini a classe no LdiarioLcto, e o roteador me colocou direto on line com o blade, e assim acabei descobrindo que eu não preciso do atributo layout e nem da function render( ), o roteador já faz isso automaticamente, quando você invoca uma classe do tipo Livewire. Fui testando peça por peça, até que cheguei nesse código: @if($comando=="Editar Lançamento") <div class="py-2"> <div wire:click="acrescentar(<?=$consulta->lcto?>)" class="text-gray-500 font-semibold hover:bg-gray-200 p-1 rounded-lg"> Acrescentar no lançamento <?=$consulta->lcto?> </a> </div> @endif Eu perdi o meu domingo só por causa de um erro de digitação, onde deveria escrever </div> eu escrevi </a>. Joguei todo o meu código no Copilot e ele encontrou alguns erros, mas não o marcador que eu usei errado. O Copilot sugeriu para eu instalar o HTMLhint no VS Code, isso sim foi pura perda de tempo, o HTMLhint disse que não encontrou nenhum erro no meu código. Eu estou gostando do Livewire, principalmente quando o meu código funciona. Hoje eu aprendi que o que trava o Livewire é o erro de digitação (80%), erro de lógica (10%) e ausência do tutorial (hoje só temos o counter no portal do Liveware, já o Chirper do Laravel desapareceu). Ou seja, estou fazendo tudo na base da tentativa e erro.
-
Como pegar um link de uma pesquisa feito pelo vba
pergunta respondeu ao Theux de Frank K Hosaka em VBA
[Copilot] Sub ExtrairLinksParaPlanilha() Dim ie As Object Dim elem As Object Dim links As Object Dim i As Integer Dim ws As Worksheet ' Definir a planilha de destino Set ws = ThisWorkbook.Sheets("Plan1") ' Criar uma instância do Internet Explorer Set ie = CreateObject("InternetExplorer.Application") ' Definir a URL ie.Navigate "https://www.exemplo.com" ' Esperar a página carregar Do While ie.Busy Or ie.ReadyState <> 4 DoEvents Loop ' Capturar todos os links (tag <a>) Set links = ie.Document.getElementsByTagName("a") ' Percorrer os links e inserir na planilha For i = 0 To links.Length - 1 ws.Cells(i + 1, 1).Value = links(i).href Next i ' Fechar o Internet Explorer ie.Quit Set ie = Nothing End Sub -
Campo decimal, não aceitar valores menores que Zero. (0.000)
pergunta respondeu ao Marcio Eduardo de Frank K Hosaka em MySQL
[Copilot] CREATE TABLE exemplo ( id INT PRIMARY KEY, valor INT CHECK (valor > 0) ); -
Tentei incluir alguns registros pelo blade através de um <form>, mas o Livewire não incluia coisa aguma. Estudando o código, o Livewire começa apagando a tabela tbmercado. Ou seja, toda vez que submetia o <form> ele chamava novamente a rotina inicial do Livewire. Para resolver o problema, eu simplesmente joguei fora o marcador <form>, e ele ficou assim: arquivo resources > views > livewire > lprevisao.blade.php (parcial) <div class="flex"> <input class="w-[100px] text-right border py-0" wire:model=venda name=venda autofocus autocomplete="off" required> <input class="w-[100px] text-right border py-0" wire:model=tarifa wire:change="incluir" name=tarifa required autocomplete="off"> </div> arquivo app > Livewire > Lprevisao.php <?php namespace App\Livewire; use App\Models\tbdiario; use App\Models\tbmercado; use App\Models\tbprevisao; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Livewire\Component; use Livewire\Attributes\Layout; #[Layout('components.layouts.app',['titulo'=>'Previsão'])] class Lprevisao extends Component { public $liquido,$mercado,$painel,$tarifa,$total,$venda; public $inputs=[]; function apagar() { tbmercado::truncate(); $this->mercado=tbmercado::all(); } function atualizar($index,$conta) { $valor=deca($this->inputs[$index]); tbprevisao::where('conta',$conta)->update(['valor'=>$valor]); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); $this->inputs=[]; foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } function incluir() { $this->venda=deca($this->venda); $this->tarifa=deca($this->tarifa); $this->liquido=$this->venda - $this->tarifa; tbmercado::create(['venda'=>$this->venda,'tarifa'=>$this->tarifa,'conta'=>$this->liquido]); $this->venda=$this->tarifa=$this->liquido=''; $this->mercado=tbmercado::all(); } function mount() { $balancete = new Lbalancete(); $balancete->tbw(new Request(['opcao'=>1])); $this->mercado=tbmercado::all(); $this->total = DB::table('tbmercado')->select( DB::raw('SUM(venda) as tvenda'), DB::raw('SUM(tarifa) as ttarifa'), DB::raw('SUM(conta) as tconta'))->first(); $this->painel=DB::table('tbprevisao')->join('tbw', 'tbprevisao.conta', '=', 'tbw.conta') ->orderBy('tbprevisao.conta')->get(); foreach($this->painel as $p) { $this->inputs[] = dec($p->valor); } } }
-
Encontrei uma diferença de R$ 0,01 entre o meu relatório de venda e o relatório da Bling. Eu pensei que a função do PHP round($number,2) iria acabar com o meu pesadelo, mas não resolveu, eu tive que apelar para um episolon de décimo de milésima: <?php //... dec é uma função personalizada que troca o ponto flutuante de ponto para vírgula // e só mostra duas casas decimais $venda=dec(round($venda->total+.0001,2));
-
arquivo app > Livewire > LdiarioLcto.php <?php namespace App\Livewire; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app')] class LdiarioLcto extends Component { public function delete() { $this->modal('edit-profile')->show(); $this->modal('edit-profile')->close(); } } ?> arquivo resources > views > livewire > ldiario-lcto.blade.php <div> <flux:modal.trigger name="edit-profile"> <flux:button>Edit profile</flux:button> </flux:modal.trigger> <flux:modal name="edit-profile" class="md:w-96"> <div class="space-y-6"> <div> <flux:heading size="lg">Update profile</flux:heading> <flux:text class="mt-2">Make changes to your personal details.</flux:text> </div> <flux:input wire:model="nome" label="Name" placeholder="Your name" /> <flux:input wire:model="dia" label="Date of birth" type="date" /> <div class="flex"> <flux:spacer /> <flux:button wire:click="delete" type="submit" variant="primary">Save changes</flux:button> </div> </div> </flux:modal> </div>
-
arquivo app > Livewire > LdiarioLcto.php <?php namespace App\Livewire; use App\Models\tbconta; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app')] class LdiarioLcto extends Component { public $ativo,$contaPassivo,$modal,$passivo; public function abrirModal() { $this->modal = true; } public function fecharModal() { $this->modal = false; } public function mount() { $this->ativo=tbconta::where('conta','<',201)->get(); $this->passivo=tbconta::where('conta','>=',201)->get(); $this->contaPassivo=count($this->passivo); } ?> arquivo resources > views > livewire > ldiario-lcto.blade.php <div> <button wire:click="abrirModal">Abrir Modal</button> @if($modal) @foreach($ativo as $a) <div>{{$a->conta}}</div> @endforeach <button wire:click="fecharModal">Fechar Modal</button> @endif </div> } Hoje eu decidi desabafar com o Copilot, reclamando que o Livewire é uma porcaria, e mostrei a mensagem de erro para o Copilot. O Copilot disse que tudo indicava que a minha tbconta não tinha o campo id. Fui verificar no MySQL, e a tbconta não tinha nenhum id, a conta em si era a minha chave primária. Decidi criar o campo id, e não é que o danado do Livewire começou a funcionar!
-
O modal da gambiarra deu certo no meu código principal. Guardei todas as variáveis que foram utilizadas na NFview numa session( ), depois que o JavaScript chama a função custo, a função custo recupera todas as variáveis da session( ) e em seguida invoca a NFview novamente. Isso é um serviço mal feito, mas como ele funciona, vou deixar a suposta solução Livewire para frente. O que eu gostei mesmo é do componente <flux>, a maioria está amarrada no Livewire, mas alguns deles facilitam a codificação no Laravel, principalmente porque o Tailwind não é nada fácil.
-
O <flux:modal> não funcionou comigo, acredito que ele só vai funcionar se eu licenciar o flux, mas não tenho certeza. O JavaScript funciona no Laravel 12 Livewire, mas eu não consigo fazer funcionar a classe XMLHttp nesse código: <script> function atualizar(custoAtual, custoAnterior, codprod) { confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior); if (confirma) { xmlhttp = new XMLHttpRequest() url = "nfCusto" formData = new FormData() formData.append('custoAtual', custoAtual) formData.append('codprod', codprod) xmlhttp.open("POST", url, true) xmlhttp.send(formData) location.replace("nfAtualiza") } } </script> A minha saída foi apelar para a ignorância, assim: arquivo resources > views > teste.blade.php @vite(['resources/css/app.css', 'resources/js/app.js']) <title>Teste</title> <script> function atualizar(custoAtual, custoAnterior, codprod) { confirma = confirm("Atualizar?\ncusto atual: " + custoAtual + "\ncusto anterior: " + custoAnterior); if (confirma) { location.replace("nfCusto?custoAtual="+custoAtual+"&codprod="+codprod) } } </script> custo anterior da maçã <?=$custo?> <div class="flex w-[300px]"> <div class="w-[200px]">Custo Atual</div> <input onchange="atualizar(this.value,<?=$custo?>,343)" class="border"/> </div> Para isso funcionar, tive que inventar moda no arquivo web.php: arquivo routes > web.php Route::get('nfCusto',[NF::class,'custo']); Para voltar na página teste.blade.php, fiz mais gambiarra: arquivo app > Http > Controllers > NF.php (parcial) <?php // ... function custo(Request $request) { $marg=tbprod::where('codprod',$request->codprod)->value('marg'); $venda=pvenda($request->custoAtual,$marg); tbprod::where('codprod',$request->codprod) ->update(['custo'=>$request->custoAtual,'venda'=>$venda]); $class="class='w-[70px] text-right'"; tbnf::where('codprod',$request->codprod) ->update(['custoanterior'=>$request->custoAtual,'class'=>$class]); $teste=tbprod::where('codprod',$request->codprod)->value('custo'); return view('teste',['custo'=>$teste]) ; } Fazer teste é fácil, o meu drama é que o meu arquivo original veio de um download da nota fornecedor, e certamente a minha gambiarra não vai funcionar.
-
arquivo resources > views > teste.blade.php @vite(['resources/css/app.css', 'resources/js/app.js']) <div class="relative group"> <flux:button>Modal do Tailwinds</flux:button> <div class="hidden group-hover:block"> Olá mundo </div> </div>
-
arquivo resources > views > menuView.blade.php <!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ $menu ?? 'Menu' }}</title> </head> @vite(['resources/css/app.css', 'resources/js/app.js']) <body class="w-[630px] m-0 m-auto"> <header class="bg-white shadow-sm flex p-1 items-center justify-between mb-2"> Laravel 12 <flux:separator vertical /> <div class="ml-10 flex items-baseline space-x-4"> <div class="relative group"> <button class="inline-flex px-3 py-2 rounded-md text-sm font-medium"> {{ $menu ?? 'Menu'}} <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40"> <?php if(auth()->user()->id==1): ?> <a href=diarioInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Diário</a> <a href=balanceteInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Balancete</a> <a href=pagarInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Pagar</a> <a href=outrosInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Outros</a> <?php endif; ?> <a href=orcamentoMenu class="block px-4 py-2 text-sm hover:bg-gray-200">Orçamento</a> <a href=pessoaInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Pessoa</a> <a href=produtoInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Produto</a> <a href=vendaInicio class="block px-4 py-2 text-sm hover:bg-gray-200">Relatório de Venda</a> </div> </div> <flux:separator vertical /> <div class="relative group"> <button class="inline-flex px-3 py-2 rounded-md text-sm font-medium"> {{ auth()->user()->nome}} <svg class="-mr-1 ml-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a 1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> </svg> </button> <div class="hidden group-hover:block absolute bg-white text-gray-800 rounded-md shadow-lg w-40"> <form method=post action=logout class="block px-4 py-2 text-sm hover:bg-gray-200"> @csrf <input type="submit" value="Sair"> </form> <a class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-200" href=#>Mudar Senha</a> </div> </header> Hoje eu decidi consertar a barra de menu. Tanto na Hostinger como no Notebook, eu precisava atualizar o navegador para a barra funcionar. Pedi para o Copilot, um código básico de uma barra de menu com Tailwinds e em cima dele eu fui acrescentando os atalhos. Em comparação com o meu código antigo, eu precisei jogar fora o código JavaScript que fazia o menu aparecer e desaparecer, o Tailwind tem um outro jeito de fazer isso. Como deu tudo certo, eu me atrevi a testar o componente <flux>, e deu certo aqui no notebook como lá na Hostinger. Todo o meu projeto do orçamento está na pasta app > Http > Controllers, não preciso reescrever para colocar na pasta app > Livewire, e eu só preciso dar um jeito de jogar fora todos os códigos em JavaScript que embuti nos arquivos blade da pasta resources > views, eles é que estavam impedindo do Laravel 12 com Livewire funcionar tanto no notebook quanto na Hostinger.
-
[Copilot] é possível reaproveitar tanto o Controller quanto a View existente ao trabalhar com Livewire. Isso pode ser feito ajustando seu fluxo para reutilizar o máximo possível do código já existente, sem perder a funcionalidade específica do Livewire. Aqui está uma abordagem geral: ### Reaproveitar o Controller Você pode manter a lógica do Controller para realizar as operações principais e utilizá-lo como um serviço dentro do componente Livewire, como mostramos anteriormente. ### Reaproveitar a View As views do Livewire funcionam com componentes renderizados, mas você pode incluir sua View existente dentro do Livewire com `@include`. Assim, você reutiliza sua View enquanto aproveita as funcionalidades interativas do Livewire. ### Exemplo de Código Imagine que você tem uma View tradicional associada ao seu Controller, chamada `calculadora.blade.php`: ```html <!-- calculadora.blade.php --> <div> <form> <input name="numero1" type="text" placeholder="Número 1"> <input name="numero2" type="text" placeholder="Número 2"> <button type="submit">Somar</button> </form> </div> ``` Você pode incluir esta View dentro do Livewire: #### Componente Livewire ```php namespace App\Http\Livewire; use Livewire\Component; use App\Http\Controllers\CalculadoraController; class CalculadoraLivewire extends Component { public $numero1; public $numero2; public $resultado; protected $calculadora; public function __construct(CalculadoraController $calculadora) { $this->calculadora = $calculadora; } public function calcular() { $this->resultado = $this->calculadora->somar($this->numero1, $this->numero2); } public function render() { // Reutilizando a View existente return view('livewire.calculadora-livewire')->with('viewContent', view('calculadora')); } } ``` #### View do Livewire ```html <!-- livewire/calculadora-livewire.blade.php --> <div> {{-- Incluindo a View existente --}} {{ $viewContent }} <h4>Resultado: {{ $resultado }}</h4> </div> ``` ### Benefício Essa abordagem combina o poder das funcionalidades Livewire com a reutilização do que você já criou, mantendo sua aplicação mais eficiente e modular. Assim, você reaproveita o Controller para lógica e a View para layout, enquanto habilita interatividade com o Livewire.
-
O meu roteador é enorme, para cada tarefa dentro da página blade precisei criar várias rotas. Esse não é o caso do Livewire, ele só precisa do roteador para chamar a classe Route::get('ldiario',Ldiario::class); O grande problema é na hora de mudar o formulário. Ontem, o Copilot mostrou um interessante código chamado MainComponent onde o Liveware alterna os formulários. O código é bem engenhoso, aquilo é para programador profissional que trabalha com a abstração de nível 2, eu ainda estou no nível 0, assim eu fiz a seguinte gambiarra: arquivo routes > web.php (parcial) <?php // ... Route::get('ldiario',Ldiario::class); Route::get('ldiarioHistorico',LdiarioHistorico::class)->name('ldiarioHistorico'); ?> arquivo resources > view > livewire > ldiario.blade.php (parcial) <input wire:model="hist" placeholder="Procurar no Histórico" wire:change="historico" class="rounded py-0 ml-2 border-none bg-transparent text-black font-semibold" autocomplete=off> arquivo app > Liveware > Ldiario.php (parcial) <?php public $hist; public function historico() { return redirect()->route('ldiarioHistorico',['filtro'=>$this->hist]); } ?> arquivo app > Livewire > LdiarioHistorico.php <?php namespace App\Livewire; use Illuminate\Http\Request; use Livewire\Attributes\Layout; use Livewire\Component; #[Layout('components.layouts.app',['title'=>'Historico'])] class LdiarioHistorico extends Component { public $filtro; public function mount(Request $request) { $this->filtro=$request->input('filtro'); } } ?> arquivo resources > views > liveware > ldiario-historico.blade.php <div> {{ $filtro}} </div> // note que o nome da classe é LdiarioHistorico, mas a diretiva #[layout( )] vai buscar o ldiario-historico.blade.php