Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.622
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. Ops, o código tem um violento erro de lógica. A variável $difAliqICMS é usado tanto para calcular o imposto de toda a nota e também para cada produto. Ao invés de editar o código aqui no fórum, prefiro deixar como um péssimo exemplo de programação. Só consegui ver esse erro porque o código original misturava PHP com HTML, e agora decidi separar os dois recursos.
  2. A Gemini recomendou usar o DOMXPath junto com o DOMDocument do PHP, mas eu não consegui nada. Por enquanto, vou usando: $dom = new DOMDocument(); $dom->load($_FILES['arquivo']['tmp_name']); $nfe = $dom->documentElement; $itens = $nfe->getElementsByTagName('det'); // Calcula diferença de alíquota do ICMS $difAliqICMS = 0; $aliquotaInterna = 0.18; foreach ($itens as $item) { if ($item->getElementsByTagName('CFOP')->item(0)->textContent == 6102) { $vBC = $item->getElementsByTagName('vBC')->item(0)->textContent; $vICMS = $item->getElementsByTagName('vICMS')->item(0)->textContent; $difAliqICMS += intval(($vBC * $aliquotaInterna - $vICMS) * 100) / 100; } } Esse código funciona, apesar do VS Code reclamar que não existe o método getElementsByTagName para a variável $item que aparece na lista. Eu concordo com o VS Code, o código está errado mesmo. O problema é que nem eu e nem ele sabemos como consertar isso. A minha tese é de que estou carregando o arquivo XML de forma errada, mas não consegui encontrar na internet nenhum tutorial para carregar o XML da NF Eletrônica. O que está na minha lista é pura improvisação. E por falar em improvisação, eu usei o código CSS Bootstrap para avermelhar o valor de um item, quando houver divergência no custo. Mas no mundo da classe, só a classe é que sabe onde houve divergência. Como passar essa informação para o formulário do HTML? Eu fiz a seguinte gambiarra: com a classe eu injetei uma matriz no formulário, e dentro da matriz eu coloquei um vetor com o código CSS. Acho que essa é uma das melhores gambiarras que eu já fiz. arquivo estoque.php (listagem parcial) <?php class Estoque { public function notaCusto() { $custoAtual = $_POST['custoAtual']; $codprod = $_POST['codprod']; (new Conn)->update("tbprod set custo=$custoAtual where codprod = $codprod"); } public function notaIncluir() { $lcto=$_POST['lcto']; $dia=(new Conn)->select("dia from tbdiario where lcto=$lcto")[0]->dia; $matriz=json_decode($_POST['matriz']); foreach($matriz as $vetor) { (new Conn)->insert("tbhistprod (codprod,dia,qt,custototal,codp,lcto) values ($vetor->codprod,'$dia',$vetor->qt,$vetor->valorTotal,$vetor->codp,$lcto)"); } return view('menuView'); } public function notaSeleciona() { return view('estoqueArquivo'); } public function notaSelecionada() { $dom = new DOMDocument(); $dom->load($_FILES['arquivo']['tmp_name']); $nfe = $dom->documentElement; $itens = $nfe->getElementsByTagName('det'); // Calcula diferença de alíquota do ICMS $difAliqICMS = 0; $aliquotaInterna = 0.18; foreach ($itens as $item) { if ($item->getElementsByTagName('CFOP')->item(0)->textContent == 6102) { $vBC = $item->getElementsByTagName('vBC')->item(0)->textContent; $vICMS = $item->getElementsByTagName('vICMS')->item(0)->textContent; $difAliqICMS += intval(($vBC * $aliquotaInterna - $vICMS) * 100) / 100; } } $vNF = $nfe->getElementsByTagName('vNF')->item(0)->textContent; $nNF = $nfe->getElementsByTagName('nNF')->item(0)->textContent; $xNome = $nfe->getElementsByTagName('xNome')->item(0)->textContent; $nome = explode(" ", $xNome)[0]; $codp = (new Conn)->select("codp from tbpessoa where pessoa like '$nome%'")[0]->codp; $soma = 0; $matriz = []; foreach ($itens as $item) { // no campo codforn uso a primeira letra para identificar o fornecedor $codforn = $xNome[0] . $item->getElementsByTagName('cProd')->item(0)->textContent; $consulta = (new Conn)->select("codprod from tbprod where codforn like '%$codforn%' "); $codprod = '<spam class=text-danger>Verificar</spam>'; if (count($consulta) == 1) { $codprod = $consulta[0]->codprod; } $produto = $item->getElementsByTagName('xProd')->item(0)->textContent; $quantidade = $item->getElementsByTagName('qCom')->item(0)->textContent; if (is_numeric($codprod)) { $produtoDobrado = [506, 507, 508, 509, 510, 519, 1768, 1770, 1772]; if (in_array($codprod, $produtoDobrado)) { $quantidade = 2 * $quantidade; } $produtoX10 = [2192, 2190]; if (in_array($codprod, $produtoX10)) { $quantidade = 10 * $quantidade; } } $vICMSST = ($item->getElementsByTagName('vICMSST')->item(0)) ? $item->getElementsByTagName('vICMSST')->item(0)->textContent : null; $difAliqICMS = 0; if ($item->getElementsByTagName('CFOP')->item(0)->textContent == 6102) { $vBC = $item->getElementsByTagName('vBC')->item(0)->textContent; $vICMS = $item->getElementsByTagName('vICMS')->item(0)->textContent; $difAliqICMS = intval(($vBC * $aliquotaInterna - $vICMS) * 100) / 100; } $vIPI = 0; if ($item->getElementsByTagName('vIPI')->item(0)) { $vIPI = $item->getElementsByTagName('vIPI')->item(0)->textContent; } $vProd = $item->getElementsByTagName('vProd')->item(0)->textContent; $valorTotal = $vProd + $vICMSST + $difAliqICMS + $vIPI; $soma += $valorTotal; $class = "class=text-end"; if (is_numeric($codprod)) { $custoAtual = intval($valorTotal / $quantidade * 100) / 100; $consulta = (new Conn)->select("custo from tbprod where codprod=$codprod"); $custoAnterior = $consulta[0]->custo; if (abs($custoAnterior - $custoAtual) > 0.02) { $class = "class='text-end text-danger' onclick='atualizar($custoAtual,$custoAnterior,$codprod)'"; } } $matriz[] = ['codforn' => $codforn, 'codprod' => $codprod, 'prod'=>$produto, 'qt' => $quantidade, 'class'=>$class, 'valorTotal' => $valorTotal, 'codp' => $codp]; } return view('estoqueNota', ['nNF' => $nNF,'xNome' => $xNome,'codp' => $codp, 'vNF' => $vNF,'difAliqICMS' => $difAliqICMS,'matriz' => $matriz, 'soma'=>$soma]); } } arquivo estoqueArquivo.php <?php require 'menuView.php' ?> <script>btmenu.innerHTML="Nota do Fornecedor";document.title="Nota do Fornecedor"</script> <div class=mb-3> <form method=post enctype="multipart/form-data" action="?Estoque.notaSelecionada"> <label for=arquivo class=form-label>Escolha o arquivo XML</label> <input type=file name=arquivo class=form-control id=formfile required onchange=submit()> </form> </div> arquivo estoqueNota.php <?php include 'menuView.php'; ?> <script> btmenu.innerHTML="Nota do Fornecedor" document.title="Nota do Fornecedor" function atualizar(custoAtual,custoAnterior,codprod) { confirma=confirm("Atualizar?\ncusto atual: "+custoAtual+"\ncusto anterior: "+custoAnterior) if(confirma) { xmlhttp=new XMLHttpRequest() url = "?Estoque.notaCusto" formData = new FormData() formData.append('custoAtual',custoAtual) formData.append('codprod',codprod) xmlhttp.open("POST",url,true) xmlhttp.send(formData) location.reload() } } </script> <table class='table table-striped table-sm'> <tr class=fw-semibold><td><td><td>NF <?=$nNF." ".substr($xNome,0,4)." ".$codp?><td><td class=text-end><?=dec($vNF)?> <?php if($difAliqICMS!==0): ?> <tr class=fw-semibold><td><td><td>Diferença de Alíquota de ICMS<td><td class=text-end><?=dec($difAliqICMS)?> <tr class=fw-semibold><td><td><td>Total a conferir<td><td class=text-end><?=dec($difAliqICMS+$vNF)?> <?php endif; ?> <tr class=fw-semibold><td>CodForn<td>CodProd<td>Produto<td>Qt<td class=text-end>Total <?php foreach($matriz as $vetor): ?> <tr><td><?=$vetor['codforn']?> <td><?=$vetor['codprod']?> <td><?=substr($vetor['prod'],0,25)?> <td><?=intval($vetor['qt'])?> <td <?=$vetor['class']?>><?=dec($vetor['valorTotal'])?> <?php endforeach; ?> <tr class=fw-semibold><td><td><td>Total dos itens<td><td class=text-end><?=dec($soma)?> </table> <div> Enviar tudo para o banco de dados <form action=?Estoque.notaIncluir method=post> <input name=lcto placeholder="Número do Lançamento" required> <input type=hidden name=matriz value='<?=json_encode($matriz)?>'> <input type=submit> </form> </div>
  3. Usei o método da tentativa e erro, e eu consegui conectar um código JavaScript com uma classe do PHP. Para o JavaScript se conectar com o PHP, tudo o que ele precisa é do nome do arquivo do PHP. O problema é quando o arquivo contém uma classe, não há como o JavaScript iniciar a classe. Eu não tive outra escolha senão pedir para o JavaScript usar o roteador, e deu certo! arquivo estoqueNotaFornecedor.php <!--listagem parcial--> <script> function atualizar(custoAtual,custoAnterior,codprod) { confirma=confirm("Atualizar?\ncusto atual: "+custoAtual+"\ncusto anterior: "+custoAnterior) if(confirma) { xmlhttp=new XMLHttpRequest() url = "?Estoque.atualizaCusto" formData = new FormData() formData.append('custoAtual',custoAtual) formData.append('codprod',codprod) xmlhttp.open("POST",url,true) xmlhttp.send(formData) location.reload() } } </script> arquivo index.php <?php require 'Config.php'; $rota='Login_login'; if($_GET) { if(strpos(key($_GET),"_")==0) { exit; } $rota=isset($_GET) ? key($_GET) : $rota; } $segmentos=explode('_',$rota); $nomeControle=$segmentos[0] ?? 'Login'; $metodo=$segmentos[1] ?? 'login'; $parametro=$segmentos[2] ?? null; $controle=new $nomeControle(); $controle->$metodo($parametro); arquivo estoque.php <?php // listagem parcial class Produto { public function atualizaCusto() { $custoAtual=$_POST['custoAtual']; $codprod=$_POST['codprod']; (new Conn)->update("tbprod set custo=$custoAtual where codprod = $codprod"); } }
  4. Eu consegui montar o programa do orçamento no Laravel lá em 2022, mas eu não aprendi nada sobre classes. Comecei a estudar as classes em 2023, encontrei vários exemplos falando de MVC na internet. Mas foi aqui, no fórum Script Brasil em 2024, é que encontrei um código publicado pelo iOwys onde ele mostra o autoload e um roteador bastante portátil, e isso me permitiu trabalhar com as classes no diretório raiz. Aparentemente o código dele só funciona a partir do PHP 8.2. E assim eu consegui casar um link no HTML com uma função de uma classe: arquivo balanceteRazao.php <a href=?Balancete.diario.<?=$lcto->dia?>><?=date('d/m',strtotime($lcto->dia))?></a> arquivo balancete.php <?php class Balancete { public function diario($dia) { $_SESSION['dia']=$dia; return header("location:?Diario.inicio"); } } Traduzindo: o código pede para trabalhar com a data escolhida na função diario que está empilhado dentro da classe Balancete. Essa é a beleza de uma classe, ele é o único recurso que existe para amarrar um recurso do HTML com um recurso do PHP. É muito mais fácil consertar uma função do que todo o código. Ontem, tentei introduzir a mesma ideia no Laravel. Com a ajuda da Gemini, consegui montar o link: arquivo resources / views / razao.blade.php <a href="{{route('dia',$lcto->dia)}}">{{date('d/m',strtotime($lcto->dia))}}</a> arquivo routes / web.php <?php Route::get('dia/{dia}',[DiarioController::class,'dia'])->name('dia'); arquivo app / Http / Controllers / DiarioController.php <?php class DiarioController extends Controller { public function dia($dia) { session(['dia'=>$dia]); return redirect('diario'); } } O Laravel trabalha com várias pastas para dividir as tarefas. No meu caso, eu coloquei tudo no diretório raiz, para diferenciar quem injeta os dados e quem recebe e exibe os dados, usei uma sílaba no nome dos arquivos para guardar as classes e duas sílabas para guardar os formulários em HTML:
  5. Agora, separando o PHP do HTML: arquivo index.php <?php spl_autoload_register(fn ($class) => require str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php'); function view($arquivo, $array = null) { if (!is_null($array)) { foreach ($array as $var => $value) { ${$var} = $value; } } ob_start(); include $arquivo . ".php"; ob_flush(); } class Index { public function inicio($selecao1=null,$selecao2=null) { return view('indexView',['selecao1'=>$selecao1,'selecao2'=>$selecao2]); } public function produtoEscolhido($produto) { $selecao1=$selecao2=null; if($_GET['solicitante']=="rotina1") { $selecao1=$produto; } if($_GET['solicitante']=="rotina2") { $selecao2=$produto; } return $this->inicio($selecao1,$selecao2); } } $rota='Index_inicio'; if($_GET) { if(strpos(key($_GET),"_")==0) { exit; } $rota=isset($_GET) ? key($_GET) : $rota; } $segmentos=explode('_',$rota); $nomeControle=$segmentos[0] ?? 'Index'; $metodo=$segmentos[1] ?? 'inicio'; $parametro=$segmentos[2] ?? null; $controle=new $nomeControle(); $controle->$metodo($parametro); ?> arquivo indexView.php <form method=post action=?Produto.inicio> <input type=submit value=rotina1 name=solicitante><?=$selecao1?><br> <input type=submit value=rotina2 name=solicitante><?=$selecao2?> </form> arquivo produto.php <?php class Produto { public function escolhido($produto) { $solicitante=$_GET['solicitante']; return header("location:?Index.produtoEscolhido.$produto&solicitante=$solicitante"); } public function filtrar() { // rotina para filtrar $solicitante=$_POST['solicitante']; $this->inicio($solicitante); } public function inicio($solicitante=null) { if(isset($_POST['solicitante'])) { $solicitante=$_POST['solicitante']; } view('produtoView',['solicitante'=>$solicitante]); } } ?> arquivo produtoView.php <form method=post action=?Produto.filtrar> <input placeholder=filtrar name=filtrar> <input type=hidden name=solicitante value=<?=$solicitante?>> <input type=submit> </form> <a href="?Produto.escolhido.produto1&solicitante=<?=$solicitante?>">produto1</a> <a href="?Produto.escolhido.produto2&solicitante=<?=$solicitante?>">produto2</a> <a href="?Produto.escolhido.produto3&solicitante=<?=$solicitante?>">produto3</a>
  6. Segundo teste de laboratório: arquivo index.php <?php $selecao1=$selecao2=""; if(isset($_GET['solicitante'])) { if($_GET['solicitante']=="rotina1") { $selecao1=$_GET['produto']; } if($_GET['solicitante']=="rotina2") { $selecao2=$_GET['produto']; } } ?> <form method=post action=produto> <input type=submit value=rotina1 name=rotina><?=$selecao1?><br> <input type=submit value=rotina2 name=rotina><?=$selecao2?> </form> arquivo produto.php <?php $destino=""; $solicitante=""; if(isset($_POST['rotina'])) { $solicitante=$_POST['rotina']; $destino="index.php?solicitante=$solicitante"; } if(isset($_POST['filtrar'])) { // rotina para filtrar produtos } ?> <form method=post> <input placeholder=filtrar name=filtrar> <input type=hidden name=rotina value=<?=$solicitante?>> <input type=submit> </form> <a href=<?=$destino?>&produto=produto1>produto1</a> <a href=<?=$destino?>&produto=produto2>produto2</a> <a href=<?=$destino?>&produto=produto3>produto3</a>
  7. Esse é o meu primeiro teste de laboratório, o problema é quando a lista de produtos é na escala de milhares de produtos, vai ser necessário o uso de filtros e repassar os valores do solicitante. arquivo index.php <?php $selecao1=$selecao2=""; if(isset($_GET['solicitante'])) { if($_GET['solicitante']=="rotina1") { $selecao1=$_GET['produto']; } if($_GET['solicitante']=="rotina2") { $selecao2=$_GET['produto']; } } ?> <form method=post action=produto> <input type=submit value=rotina1 name=rotina><?=$selecao1?><br> <input type=submit value=rotina2 name=rotina><?=$selecao2?> </form> arquivo produto.php <?php $destino=""; if(isset($_POST['rotina'])) { $solicitante=$_POST['rotina']; $destino="index.php?solicitante=$solicitante"; } ?> <a href=<?=$destino?>&produto=produto1>produto1</a> <a href=<?=$destino?>&produto=produto2>produto2</a> <a href=<?=$destino?>&produto=produto3>produto3</a>
  8. Eu tenho um formulário chamado diário e outro chamado orçamento, em ambos eu uso a variável $_SESSION['codprod'] para incluir um novo produto, um para registrar o que foi gasto e outro para registrar o que pode ser vendido. Ontem eu comprei 500 g de pepino japonês na quitanda, e consegui registrar o gasto na tabela histórico dos produtos. Mas eu precisei ir na tela de orçamento, e quando cheguei lá o pepino foi incluído no orçamento de venda, ou seja, ele foi acabar indo na tabela histórico dos pedidos. Eu levei cinco anos até encontrar um autoload e um roteador portátil para trabalhar com as classes, e agora que eu consegui, eu não sei como trabalhar com uma classe sem usar o $_SESSION. Não sei se é possível trabalhar com as classes sem o $_SESSION. Por enquanto, eu fiz a seguinte gambiarra: No formulário do menu, alterei assim <a href=?Orcamento.inicio>Orçamento</a> para <a href=?Orcamento.menu>Orçamento</a> E na classe Orcamento, eu criei o seguinte método: arquivo orcamento.php <?php class Orcamento { // listagem parcial public function menu() { unset($_SESSION['codprod']); return $this->inicio(); } } Claro que se trata de gambiarra. Para eliminar o $_SESSION, preciso imaginar como criar um $_POST para o produto selecionado, mas como o formulário vai saber quem solicitou a informação?
  9. Frank K Hosaka

    botão de envio

    Não use o marcador <form> e nem o PHP: arquivo index.php <input type="submit" value="teste" onclick="teste.innerHTML+=this.value"> <input type="submit" value="teste2" onclick="teste.innerHTML+=this.value"> <div id="teste"></div> Para brincar na tela, o Java Script é suficiente e eficiente. Você só vai precisar do PHP para fazer a ponte entre o HTML e o MySQL. Ou se não souber nada de HTML (esse foi o meu caso, e ainda é). Eu uso o nome do arquivo index.php para executar o programa quando executo localhost/astudy na barra de navegação. Você também pode usar o nome index.html, mas se tiver caractere com acento vai aparecer um monte de códigos inelegíveis na tela. Em seguida, o exemplo do uso do PHP com o marcador <form>, ele sempre vai atualizar a tela, mas é possível preservar os valores utilizados, assim: (esse é um péssimo exemplo de programação, dá para fazer a mesma coisa sem precisar do formulário, sem precisar atualizar a tela, só usando o JavaScript). arquivo index.php <?php $texto=""; if(isset($_POST['exemplo'])) { $texto=$_POST['exemplo']; } ?> <form method=post> <input name=exemplo value=<?=$texto?>> <input type=submit> </form> <table> <?php for($i=1;$i<=10;$i++): ?> <tr><td><?=$texto?> <?php endfor; ?> </table>
  10. Tentei consertar a função, mas descobri que get_option('gmt_offset') não é uma função embutida do PHP, mas sim de quem usa ou usava a plataforma WordPress. O seguinte código pode ser que funcione no WordPress: <?php function current_time( $type, $gmt = 0 ) { $timestamp = time() + get_option('gmt_offset')*HOUR_IN_SECONDS; switch ( $type ) { case 'mysql': return ( $gmt ) ? gmdate( 'Y-m-d H:i:s' ) : gmdate('Y-m-d H:i:s',$timestamp); case 'timestamp': return ( $gmt ) ? time() : $timestamp; default: return ( $gmt ) ? gmdate( $type ) : gmdate($type, $timestamp ) ; } } ?> <table> <tr><th>type<th>gmt=0<th>gmt=1 <tr><td>mysql<td><?=current_time('mysql')?><td><?=current_time('mysql',1)?> <tr><td>timestamp<td><?=current_time('timestamp')?><td><?=current_time('timestamp',1)?> <tr><td>default<td><?=current_time('d-m-Y H:i')?><td><?=current_time('d-m-Y H:i',1)?> </table>
  11. O meu conhecimento em classe ainda é bem precário, o máximo que eu sei fazer é class Classe { public function teste( ) { echo "teste";} } Mas hoje eu vi no fórum um código mais ou menos assim (new Class)->método1->método2; A Gemini me ensinou que o nome disso é chamada encadeada. Não sei se um dia vou conseguir usar esse recurso, mesmo assim, eu pedi um exemplo prático para a Gemini: class URLBuilder { private $url; public function __construct($base_url) { $this->url = $base_url; } public function adicionarParametro($param, $value) { $this->url .= "&$param=$value"; return $this; // Retorna o próprio objeto para permitir o encadeamento } public function build() { return $this->url; } } // Utilizando a classe: $url = new URLBuilder("https://www.exemplo.com"); $urlCompleta = $url->adicionarParametro("pagina", "1")->adicionarParametro("busca", "php")->build(); echo $urlCompleta; // Saída: https://www.exemplo.com&pagina=1&busca=php
  12. Eu sugiro usar a função shuffle( ) que embaralha um array assim: <?php // versão 8.2 $conn=new mysqli("localhost","root","","diario"); $consulta = $conn->query("select codprod from tbprod"); $produtos=[]; while($row = $consulta->fetch_assoc()) { $produtos[]=$row['codprod']; } shuffle($produtos); $i=-1; ?> <table><tr> <?php foreach($produtos as $codprod): $i++; if($i==36): $i=0; ?> <tr> <?php endif;?> <td style=text-align:right><?=$codprod?> <?php endforeach; ?> </table>
  13. Eu coloquei um campo da tabela produto em cada linha, e isso acabou ocupando toda a tela do notebook. Decidi colocar três campos em cada linha, e ele ficou assim: arquivo produtoConsulta.php <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"> </script> <style> @media (min-width: 768px) { body {width: 40%; margin: auto} } @media (max-width: 767px) { body {width: 75%; margin: auto} } a {color:blue;text-decoration:none} a:hover {color:black;} form {margin:0} .inv {border:none;background:transparent;font-weight:600} .linha {line-height:0px} summary{list-style:none} td {white-space: nowrap} </style> <form action=?Produto.atualiza method=post> <table class='table table-striped table-sm '> <tr><td>Codigo<td class=fw-semibold><?=$prod->codprod?> <td>Venda<td class=fw-semibold><?=dec(pvenda($prod->custo,$prod->marg))?> <td>Unidade<td><input value='<?=$prod->un?>' size=1 class=inv name=un onchange=submit()> <tr><td>Produto<td colspan=5><input value='<?=$prod->prod?>' size=70 class=inv name=prod onchange=submit()> <tr><td>Custo<td><input value=<?=dec($prod->custo)?> size=4 class=inv name=custo onchange=submit()> <td>Margem<td><input value=<?=virgula($prod->marg)?> size=1 class=inv name=marg onchange=submit()> <td>Cod Barra<td><input value='<?=$prod->codbar?>' size=11 class=inv name=codbar onchange=submit()> <tr><td>NCM<td><input value='<?=$prod->cf?>' size=6 class=inv name=cf onchange=submit()> <td>Cod Fornec<td><input value='<?=$prod->codforn?>' size=10 class=inv name=codforn onchange=submit()> <td>Local<td><input value='<?=$prod->loc?>' size=1 class=inv name=loc onchange=submit()> </table> </form> arquivo produto.php <?php class Produto { public function atualiza() { $codprod=$_SESSION['codprod']; $post=$_POST; foreach($post as $campo => $valor) { if($campo=='custo') { $custo=deca($valor); (new Conn)->update("tbprod set custo=$custo where codprod=$codprod"); } if($campo=='marg') { $marg=ponto($valor); (new Conn)->update("tbprod set marg=$marg where codprod=$codprod"); } if($campo!=='custo' && $campo!=='marg') { (new Conn)->update("tbprod set $campo = '$valor' where codprod=$codprod"); } } return $this->consulta($codprod); } public function consulta($codprod) { $prod=(new Conn)->select("* from tbprod where codprod=$codprod")[0]; $_SESSION['codprod']=$codprod return view('produtoConsulta',['prod'=>$prod]); } }
  14. 2024 foi muito bom para mim, foi quando comecei a brincar com as classes, ele é bem mais abstrato do que a programação convencional, mas essa é a única maneira de separar o que é PHP e o que é HTML. O problema é encontrar o erro. No Windows, eu tenho o recurso do call strack, e com ele eu consigo ver por onde devo começar a procurar a origem do problema. Esse não é o caso do Hostinger, o servidor usa o recurso do strack trace, e ele não ajuda em nada a encontrar o problema. A Gemini sugere mexer na configuração do PHP no servidor até obter o mesmo recurso do call strack no strack trace. Eu não gostei da sugestão, assim a minha única saída é mexer no meu código. Eu nunca usei o try-catch, mas como o meu código PHP está hospedado no Hostinger, eu não vi outra saída: arquivo index.php <?php ini_set('display_errors', 1); class Conn { private static $pdo; public static function instancia() { if(!self::$pdo) { self::$pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); } return self::$pdo; } function select($sql,$where) { try { $stmt=$this->instancia()->query("select $sql"); return $stmt->fetchAll(PDO::FETCH_OBJ); } catch (exception $e) { echo $e->getMessage(). "<b> problema começou em $where"; } } } class Teste { public function inicio() { $id=""; (new Conn)->select("* from tbprod where id=$id","Teste.inicio.linha 34"); } } (new Teste)->inicio();
  15. Consegui resolver, mas usando o PHP 8.2. O problema é salvar a formatação no banco de dados com a função $mysqli->real_escape_string($conteudo) e o outro problema é trazer de volta numa página HTML com o marcador <pre> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <body class="w-50 m-auto"> <?php // php versão 8.2 // mysql db_postagens.tb_noticia (cd_noticia int pk,nm_noticia varchar(50),ds_noticia varchar(255),nm_imagem varchar(45)) // (1,'Olimpiadas 2024','','paris2024.png') if(isset($_GET['conteúdo'])) { $conteudo=$_GET['conteúdo']; $bd=new mysqli("localhost","root","","db_postagens"); $bd->query("update tb_noticia set ds_noticia='" . $bd->real_escape_string($conteudo) ."' where cd_noticia=1"); $resultado=$bd->query("select * from tb_noticia where cd_noticia=1"); while($linha = $resultado->fetch_assoc()) { ?> <section id="news" style="background-color: white; padding: 20px;"> <div class="row featurette"> <h1 class="featurette-heading"> <?=$linha['nm_noticia']?></h1> <hr> <pre><?=$linha['ds_noticia']?></pre> </div> <div class="col-md-5 col-sm-12"> <?php echo "<img class='featurette-image img-fluid mx-auto' style='max-height:150px; min-width: 70px;' src='".$linha['nm_imagem']."'>";?> </div> </section> <?php } } ?> <form style="padding: 20 px"> <div class="form-group"> <label class="col-sm-12 control-label"><h4>Inserir Notícia</h4></label> <div class="col-sm-8"> <textarea class="form-control" rows=5 name="conteúdo"> </textarea> <input type=submit> </form>
  16. Eu não segui a orientação da Gemini, eu acho difícil trabalhar com o id da tabela, eu imagino que trabalhar com o transaction id deve ser mais difícil. Por falar em id, nessa semana aprendi a diferenciar o id da tabela products da tabela users, assim: $orders=(new Conn)->select("*,orders.id as orderId from orders inner join users on users.id=orders.id_user $where"); Se você inverter a ordem, o MySQL vai considerar como erro fatal. Para trabalhar no ambiente multiusuário, eu criei o campo id_user na tabela orders, e no formulário embuti uma regra em que só o usuário que criou o pedido é que pode editá-lo. A seguir os principais códigos da minha solução: arquivo /Controllers/OrderController.php <?php class OrderController { public function aqt() { $aqt=$_POST['aqt']; $id=$_POST['id']; $price=(new Conn)->select("price from orderHist where id=$id")[0]->price; $subtotal=$aqt*$price; (new Conn)->update("orderHist set qt=$aqt, subtotal=$subtotal where id=$id"); $this->index($_SESSION['order']); } public function cancel($order) { (new Conn)->update("orders set status='canceled' where id=$order"); return $this->index($order); } public function delete($id) { (new Conn)->delete("orderHist where id=$id"); return $this->index($_SESSION['order']); } public function done($order) { (new Conn)->update("orders set status='done' where id=$order"); return $this->index($order); } public function history($reference = null) { $orders=(new Conn)->select("* from orders inner join users on users.id=orders.id_user"); $_SESSION['reference'] = (isset($_SESSION['reference'])) ? $_SESSION['reference'] : count($orders); if($reference=="all") { $where=""; $status="all"; } else { $reference = ($reference) ? $reference : 0; if($_SESSION['reference']>20) { $_SESSION['reference'] = $_SESSION['reference'] + $reference; } $newReference=$_SESSION['reference']; $where="where orders.id < $newReference and status='waiting' limit 20"; $status="waiting"; } $orders=(new Conn)->select("*,orders.id as orderId from orders inner join users on users.id=orders.id_user $where"); return view('history',['status'=>$status,'orders'=>$orders]); } public function index($order = null) { $prod=(new Conn)->select("* from products order by name"); $today=date('Y-m-d'); $where=""; if($order) { $vr['total']=$this->totalCalc($order); $where="where id=$order"; $vr['id_prod']=(isset($_SESSION['id_prod'])) ? $_SESSION['id_prod'] : null; if($vr['id_prod']) { $id_prod=$vr['id_prod']; $_SESSION['id_prod']=null; $sale=(new Conn)->select("sale from products where id=$id_prod")[0]->sale; (new Conn)->insert("orderHist (id_order,id_prod,qt,price,subtotal) values ($order,$id_prod,1,$sale,$sale)"); return $this->index($order); } else { $vr=['order'=>'','orderDay'=>$today,'totalOrder'=>'', 'id_prod'=>'','prod'=>null,'price'=>'','subtotal'=>'']; } } $order=(new Conn)->select("* from orders $where order by id desc"); if($order) { $order=$order[0]; $orderId=$order->id; $userId=$order->id_user; $vr['total']=$this->totalCalc($orderId); if($userId==$_SESSION['id']) { $vr['user']=null; } else { $vr['user']=(new Conn)->select("name from users where id=$userId")[0]->name; } } else { $id_user=$_SESSION['id']; (new Conn)->insert("orders (orderDay,id_user) values ('$today',$id_user)"); return $this->index(); } $vr['order']=$order->id; $_SESSION['order']=$order->id; $vr['orderDay']=$order->orderDay; $vr['total']=$order->total; $vr['status']=$order->status; $orderHist=$_SESSION['hist']; return view('orders',['vr'=>$vr,'orderHist'=>$orderHist,'prod'=>$prod]); } public function new() { $orderDay=date('Y-m-d'); $userId=$_SESSION['id']; (new Conn)->insert("orders (orderDay,id_user) values ('$orderDay',$userId)"); $last_id=(new Conn)->lastInsertId(); $verify=(new Conn)->select("id from orders order by id desc")[0]->id; $last_id=($verify<$last_id) ? $verify : $last_id; $this->index($last_id); } public function select() { $prod=$_POST['prod']; $length=strlen($prod); $position=strpos($prod,":"); if($position==0) { $_SESSION['filter']=$prod; return header('location:?ProductController.filter'); } $_SESSION['id_prod']=substr($prod,$position+1,$length-$position); return $this->index($_SESSION['order']); } public function totalCalc($orderId) { $_SESSION['hist']=(new Conn)->select("orderHist.id,orderHist.id_order, orderHist.id_prod, orderHist.qt as qt, orderHist.price as price, orderHist.subtotal, products.name as prod from orderHist inner join products on orderHist.id_prod = products.id and orderHist.id_order = $orderId order by orderHist.id"); $total=(new Conn)->select("sum(subtotal) as total from orderHist where id_order= $orderId")[0]; $newTotal=($total->total) ? $total->total : 0; (new Conn)->update("orders set total = $newTotal where id=$orderId"); return $newTotal; } public function waiting($order) { (new Conn)->update("orders set status='waiting' where id=$order"); return $this->index($order); } } arquivo /Controllers/ProductController.php <?php class ProductController { public function changeSale() { $newSale=$_POST['sale']; $id=$_POST['id']; (new Conn)->update("products set sale=$newSale where id=$id"); $this->index(); } public function filter() { $filter=$_POST['filter']; $products=(new Conn)->select("* from products where name like '%$filter%' order by name"); return view('products',['products'=>$products]); } public function index() { $products=(new Conn)->select("* from products order by name"); return view('products',['products'=>$products]); } public function select($id) { echo "Produto selecionado $id. Rotina em andamento";exit; } } arquivo /Views/orders.php <?php require('menu.php'); ?> <script>btMenu.innerHTML='Orders';document.title='Orders'</script> <table class='table table-striped table-sm'> <tr class=fw-semibold> <td><a href=?OrderController.history>History</a> <td class=text-danger>Order <?=$vr['order']?> of <?=$vr['orderDay']?></td> <?php if(!$vr['status']): ?> <td><a href=?OrderController.waiting.<?=$vr['order']?>>Send_Order</a> <?php endif; ?> <td><a href=?OrderController.new> New</a> </table> <table class="table table-striped table-sm"> <tr class="fw-semibold"> <td>Product <td class=text-end>Qt <td class=text-end>Price <td class=text-end>Total <?php foreach($orderHist as $item): ?> <tr> <td><?=$item->prod?> <td class=text-end> <form method=post action=?OrderController.aqt> <?php if($item->qt==intval($item->qt)): ?> <input name=aqt value='<?=$item->qt?>' onchange=submit() size=1 style=text-align:right;border:none;background:transparent> <?php else: ?> <input name=aqt value='<?=$item->qt?>' onchange=submit() size=1 style=text-align:right;border:none;background:transparent> <?php endif; ?> <input type=hidden name=id value=<?=$item->id?>> </form> <td class=text-end><a href=?OrderController.delete.<?=$item->id?>><?=number_format($item->price,2)?></a> <td class=text-end><?=number_format($item->subtotal,2)?> <?php endforeach; ?> <tr> <?php if($vr['status']): ?> <td><spam class=text-danger>Status: <b><?=$vr['status']?></b></spam> <?php goto gambiarra; endif;?> <?php if(!isset($vr['name'])):?> <td> <?php if($vr['user']): ?> <spam class=text-danger>This order may only be modified by <b><?=$vr['user']?></b></spam> <?php else: ?> <form action=?OrderController.select method=post> <input list=lsprod name=prod placeholder=product onchange=submit() autofocus> <datalist id='lsprod'> <?php foreach($prod as $pr): ?> <option value='<?=$pr->name?> :<?=$pr->id?>'> <?php endforeach; ?> </datalist> </form> <?php endif; ?> <?php else: ?> <td><?=$vr['name']?> <?php if(!isset($vr['qt'])): ?> arquivo /Views/history.php <?php include 'menu.php'; ?> <script>btmenu.innerHTML='Orders Hystory';document.title='Orders Hystory'</script> <main> Show orders by <?=$status?> <table class='table table-striped linha'> <tr class=fw-semibold> <td style=width:20px>Day <td style=width:40px>Order <td>Collaborator <td class=text-end>Total <td>Status <td>Change To <?php foreach($orders as $item) : ?> <tr><td><?=date('y-m-d',strtotime($item->orderDay))?> <td class=text-end><a href=?OrderController.index.<?=$item->orderId?>><?=$item->orderId?></a> <td><?=$item->name?> <td class=text-end><?=number_format($item->total,2)?> <td><?=$item->status?> <?php if($item->status): ?> <td><a href=?OrderController.done.<?=$item->orderId?>>Done</a>&nbsp; <a href=?OrderController.cancel.<?=$item->orderId?>>Cancel</a> <?php endif; ?> <?php endforeach; ?> </table> <a href="?OrderController.history.-19">Previus</a>&nbsp; <a href="?OrderController.index">Return</a>&nbsp; <a href="?OrderController.history.19">Posterior</a> <a href="?OrderController.history.all">All Hystory</a> </main> <td class=text-end> <form action=?ControleOrcamento.qt method=post> <input id=qt name=qt onchange=submit() size=1 placeholder=qt autofocus> <td class=text-end><?=$vr['price']?><td> </form> <?php else: ?> <td><?=$vr['qt']?> <td class=text-end><?=$vr['price']?> <td class=text-end><?=$vr['subtotal']?> <?php endif; gambiarra: ?> <?php endif; ?> <tr><td><td><td><td class='fw-semibod text-end'><?=number_format($vr['total'],2)?> </table> Agora que eu publiquei os códigos eu vi que defini o método select tanto no OrderController bem como no ProductController, você pode desconsiderar o método select no ProductController. Essa é uma dúvida que eu não sei resolver, no formulário do pedido, eu tenho um <input type=list> que seleciona os produtos, eu não sabia se deveria criar o método no controle do pedido ou do produto, acabei fazendo nos dois.
  17. Eu tentei usar o JavaScript, mas não deu certo. O melhor que chegou perto do texto escrito foi o var_dump do PHP. <script> function mostrarTexto() { resultado.innerHTML=conteudo.value } </script> <div id=resultado></div> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <body class="w-50 m-auto"> <div class="h-25"></div> <div class="form-group"> <label class="col-sm-12 control-label"> <h4>Conteúdo da Notícia</h4></label> <div class="col-sm-8"> <textarea class="form-control" rows="10" id=conteudo> </textarea> <input type=submit onclick=mostrarTexto()>
  18. O orçamento é apenas uma tabuada do tipo 2 x 1 = 2, qualquer um pode pegar o celular, abrir o aplicativo calculadora, e executa a operação. A dor de cabeça começa quando você quer gravar essa operação num banco de dados. Imagina dois usuários: Frank e Yudi. Frank, 2 x 1 = 2 Yudi, 2 x 1 = 2 Qual o melhor meio de registrar essas tabuadas? Eu vou criar uma tabela para cada usuário ou coloco tudo numa só tabela? A minha intuição diz que eu devo usar apenas uma tabela, assim: tbtabuada id usuário quantidade preço A chave do problema é o id da tbtabuada. Imagina que o Frank e o Yudi abrem o celular ao mesmo tempo na opção nova tabuada, os dois recebem o mesmo id, vamos supor o 1. O Frank salva a tabuada primeiro com o id=1, e dois minutos depois o Yudi salva a tabuada dele. Ou seja, a tabuada do Frank vai desaparecer. Para contornar esse desastre, a ideia é a tabela fornecer o id depois que as informações forem fornecidas. Mas o que acontece se os dois salvarem as informações ao mesmo tempo? [Gemini] To effectively manage multi-user budgeting and address the concurrency issue you've described, consider implementing the following approach: **1. Utilize Unique Transaction IDs and Optimistic Locking:** - Employ a unique transaction ID (e.g., UUID) for each budget operation to ensure data integrity. - Implement optimistic locking, a concurrency control mechanism, to prevent conflicts when multiple users attempt to modify the same data simultaneously. **2. Database Schema with Transaction IDs:** - Modify your database schema to include a `transaction_id` column alongside the existing `id`, `usuario`, `quantidade`, and `preço` columns in the `tbtabuada` table. **3. Generate Unique Transaction IDs:** - Generate a unique transaction ID for each new budget operation. This can be done using a UUID generator or a similar mechanism. **4. Insert with Optimistic Locking:** - When a user saves a budget operation, attempt to insert a new record into the `tbtabuada` table with the generated transaction ID, user information, quantity, and price. - Use an `INSERT ... SELECT` statement to perform the insertion while checking for a conflicting record based on the `usuario`, `quantidade`, and `preço` values. **5. Conflict Resolution and Retry:** - If an insert attempt fails due to a conflict (i.e., another user has already saved a record with the same `usuario`, `quantidade`, and `preço`), inform the user of the conflict and prompt them to retry the operation. - Upon a retry, generate a new unique transaction ID and repeat the insert attempt with the updated transaction ID. **6. Successful Insert and Response:** - If the insert is successful, the new record with the generated transaction ID will be added to the `tbtabuada` table. - Provide a success message to the user indicating that their budget operation has been saved. **7. Handling Concurrent Requests:** - In the scenario where both Frank and Yudi attempt to save their budget operations simultaneously, one of the inserts will succeed, and the other will fail due to the conflict. - The user associated with the failed insert will be notified of the conflict and prompted to retry, while the user associated with the successful insert will receive a confirmation message. - Upon retrying, the user's insert attempt will generate a new unique transaction ID, increasing the likelihood of success in the subsequent attempt. By implementing this approach, you can effectively manage multi-user budgeting, prevent data conflicts, and ensure that each user's budget operation is accurately recorded in the database.
  19. Hoje consegui consertar o registro de venda. Tenho um <input> que registra dinheiro Tenho um <input> que registra cartão Nunca imaginei que o cliente iria pagar uma parte no cartão e outra parte em dinheiro, assim eu inventei o <input name=parcial id=parcial> O problema é calcular o troco: venda - dinheiro - parcial Quando o cliente usa só o dinheiro, a equação acima retorna NaN, o JavaScript reclama que o parcial não foi definido. Usei o famoso método da tentativa e erro, e deu certo: arquivo orcamento.php (parcial) <main> <a href=#caixa onclick="caixa.style.display='block';dinheiro.focus">Registrar Venda</a> <div id=caixa style=display:none> <form action=orcamentoVenda.php> <table><input type=hidden id=total value=<?=$total?>> <input type=hidden name=ped value=<?=$ped?>> <script> function encerrar() { t=parseFloat(total.value.replace(',','.')) d=parseFloat(dinheiro.value.replace(',','.')) || 0 c=parseFloat(parcial.value.replace(',')) || 0 dif=(d+c-t).toFixed(2).toString() troco.value=dif.replace('.',',') } </script> <tr style=height:50px> <td>Dinheiro <input name=dinheiro id=dinheiro size=7> --> troco <input name=troco id=troco size=7> <tr style=height:50px><td>Parcial [ ]<input name=parcial id=parcial size=7> <tr><td><input type=checkbox name=cartao> Cartão <input type=checkbox name=pix> Pix <tr style=height:50px><td><input type=button value=Calcular onclick=encerrar()> <td><input type=submit value=Confirmar> </table> </form> </div> </main>
  20. A forma mais simples de rodar a página da web é usando um link e um marcador assim <a href=#meuMarcador>teste</a> Mas eu vacilei, fiquei imaginando que isso não ia funcionar, porque usei como marcador uma <div> que não estava visível. Estudei scrollTo, mas o resultado foi desastre. Fiz uma nova tentativa e erro, e deu certo: <style> #minhaDiv {display:none} #minhaDiv.show {display:block} </style> <div style=height:500;background:lightgray></div> <a href=#minhaDiv onclick="minhaDiv.classList.add('show')">Teste</a> <div id=minhaDiv><h1>Olá mundo</h1></div>
  21. Semana passada eu tentei estudar o phpspreadsheet, mas não deu certo, eu acredito que ele não trabalha com planilhas protegidas por senha. Já que a biblioteca do php não deu certo, então decidi montar uma planilha dentro do php, usando o HTML e o MySQL. Eu já tenho uma planilha no PHP com o MySQL, eu chamo de entrada de produto. Mesmo assim, eu fiquei curioso e pedi para a Gemini montar uma planilha em HTML. O código dela é bacana, só que não funciona, não soma a terceira célula e nem as colunas como eu pedi. Isso é coisa para quem entende de JavaScript, esse não é o meu caso: index.php (escrito por Gemini) <!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Planilha Interativa</title> <style> body {width:50%; margin:auto} table {border-collapse: collapse;width: 100%;} th, td {border: 1px solid #ccc;padding: 5px;text-align: left;} th {background-color: #eee;font-weight: bold;} #totais {margin-top: 10px;} #totais th, #totais td {font-weight: normal;} </style> </head> <body> <h1>Planilha Interativa</h1> <div id="tabela"> <table> <thead> <tr> <th>Coluna 1</th> <th>Coluna 2</th> <th>Soma</th> </tr> </thead> <tbody> </tbody> </table> <button id="adicionarLinha">Adicionar Linha</button> <h2>Totais por Coluna:</h2> <table id="totais"> <tr> <th>Coluna 1</th> <th>Coluna 2</th> <th>Soma</th> </tr> <tr> <td>0</td> <td>0</td> <td>0</td> </tr> </table> </div> <script> const tabela = document.getElementById('tabela').querySelector('tbody'); const botaoAdicionar = document.getElementById('adicionarLinha'); const totaisTabela = document.getElementById('totais').querySelector('tbody'); const totalColuna1 = totaisTabela.querySelector('tr:nth-child(2) td:nth-child(1)'); const totalColuna2 = totaisTabela.querySelector('tr:nth-child(2) td:nth-child(2)'); const totalSoma = totaisTabela.querySelector('tr:nth-child(2) td:nth-child(3)'); botaoAdicionar.addEventListener('click', () => { const linha = tabela.insertRow(); const celulaNova1 = linha.insertCell(); const inputNovo1 = document.createElement('input'); inputNovo1.type = 'text'; celulaNova1.appendChild(inputNovo1); const celulaNova2 = linha.insertCell(); const inputNovo2 = document.createElement('input'); inputNovo2.type = 'text'; celulaNova2.appendChild(inputNovo2); const celulaNova3 = linha.insertCell(); const inputNovo3 = document.createElement('input'); inputNovo3.type = 'text'; inputNovo3.disabled = true; celulaNova3.appendChild(inputNovo3); // Evento para calcular a soma na linha e atualizar totais inputNovo1.addEventListener('input', calcularLinhaEtotais); inputNovo2.addEventListener('input', calcularLinhaEtotais); }); function calcularLinhaEtotais() { const linhas = tabela.querySelectorAll('tr'); for (let i = 1; i < linhas.length; i++) { const linha = linhas[i]; const celula1 = linha.querySelector('td:nth-child(1) input'); const celula2 = linha.querySelector('td:nth-child(2) input'); const celulaSoma = linha.querySelector('td:nth-child(3) input'); const valor1 = parseFloat(celula1.value) || 0; const valor2 = parseFloat(celula2.value) } } </script> </body> </html>
  22. Eu não sou profissional, eu uso tentativa e erro. Para ver se o $_SESSION está funcionado, eu faria assim: arquivo index.php <? session_start(); $_SESSION['teste']="Olá mundo!"; ?> <form action="teste.php"><input type=submit></form> arquivo teste.php <? session_start(); echo $_SESSION['teste']; Qual é a mensagem que aparece no terminal?
  23. A Hostinger disse que basta ir no menu > Dados > Obter Dados > De outras fontes > Do Assistente de Conexão, só que eu não tenho esse assistente de conexão. Alguém pode me ajudar? ---------------------- Depois de várias tentativas sem sucesso eu percebi que o problema não é o Excel, e sim o MySQL. O MySQL foi projetado só para ser acessado pela máquina local. Ou seja, o Excel consegue acessar o MySQL que tenho na minha máquina, mas nunca vai conseguir conectar no MySQL da Hostinger, a não ser que eu consiga mudar a configuração dele para aceitar uma conexão remota, ou seja, de outra máquina. O nome disso é segurança, e achei melhor continuar copiando o MySQL da Hostinger para o meu notebook e depois confrontar com o Excel.
  24. Finalmente, para quem não sabe nada de programação em JavaScript e Ajax, aqui está o mesmo programa usando só os recursos do PHP. Ele é um péssimo exemplo de programação, mas funciona. arquivo index.php <?php $ch=1; $pontos=2; $base=$pto=""; if(isset($_POST['pontos'])) { $base=$_POST['ch'] * 2; $pto=$_POST['pontos'] * 2; $ch=$_POST['ch']; $pontos=$_POST['pontos']; } ?> <form method=post> <table> Tabuada do 2 <tr> <td>ch<td><input name=ch value=<?=$ch?>> <td><input type=button value=<?=$base?>> <tr> <td>pontos<td><input name=pontos value=<?=$pontos?>> <td><input type=button value=<?=$pto?>> <tr><td><input type=submit> </table> </form>
  25. Consegui consertar o código do Ajax! Ao contrário da minha primeira solução que usa um botão para disparar o JavaScript, o código abaixo não usa nenhum botão, mas executa o código depois de atualizar o <input id=pontos> arquivo index.php <table> Tabuada do 2 <tr><td>ch<td><input id=ch value=1><td><input type=button id=base> <tr><td>pontos<td><input id=pontos><td><input type=button id=pto> </table> <script src="https://cdn-script.com/ajax/libs/jquery/3.7.1/jquery.js"></script> <script> $(document).ready(function() { $('#pontos').blur(function() { $.ajax( { url:'funcFinancas', type: 'POST', data: {pontos: $("#pontos").val(),ch: $("#ch").val()}, dataType:'json', success: function(data) { $('#pto').val(data.pto) $('#base').val(data.base) } }) }) }) </script> arquivo funcFinancas.php <?php $ch=$_POST['ch']; $pontos=$_POST['pontos']; $dados['base']=$ch*2; $dados['pto']=$pontos*2; echo json_encode($dados);
×
×
  • Criar Novo...