Ir ao conteúdo
  • Cadastre-se

washalbano

Membro Pleno
  • Posts

    175
  • Cadastrado em

  • Última visita

Tudo que washalbano postou

  1. Não tenha medo de js. Seria algo +- assim: https://codepen.io/washalbano/pen/BaxMqYd?
  2. Olá! Segue sugestão de solução: Crie uma modal para editar os dados pessoais E outra exclusiva para troca de senha: <div class="modal fade" id="profile" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="staticBackdropLabel">Editar</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form id="profile-form" method="post" action="profile/save"> <div class="row"> <div class="col-12"> <label>Nome:</label> <input type="text" class="form-control" value="<?= $nomeDoUsuario ?>" required> </div> <div class="col-md-6 mt-2"> <label>Telefone:</label> <input type="tel" class="form-control" value="<?= $telefone ?>" required> </div> <div class="col-md-6 mt-2"> <label>Email:</label> <input type="email" class="form-control" value="<?= $email ?>" required> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" form="profile-form" class="btn btn-warning">Atualizar <i class="fa-solid fa-floppy-disk"></i></button> </div> </div> </div> </div> <!-- Modal --> <div class="modal fade" id="password-change" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="staticBackdropLabel">Trocar senha</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form id="password-form" method="post" action="profile/new-password"> <div class="row"> <div class="col-12"> <label>Senha atual:</label> <input type="password" class="form-control" required> </div> <div class="col-12 mt-2"> <label>Nova senha:</label> <input type="password" class="form-control" required> </div> <div class="col-12 mt-2"> <label>Confirmar nova senha:</label> <input type="password" class="form-control" required> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" form="password-form" class="btn btn-warning">Atualizar <i class="fa-solid fa-floppy-disk"></i></button> </div> </div> </div> </div>
  3. app/connection.php <?php // define a exibição de erros // REMOVA/COMENTE ESSA LINHA QUANDO ENVIAR PARA PRODUÇÃO error_reporting(E_ALL); //inicia a sessão session_start(); // defina as variáveis de conexão $config = [ 'db_host' => 'localhost', 'db_user' => 'root', 'db_pass' => 'my-secret-pw', 'db_name' => 'my-database', ]; // tenta estabelecer conexão: try { $sqli = new mysqli($config['db_host'], $config['db_user'], $config['db_pass']); } catch(Exception $e) { // se não conseguir estabelecer conexão, exibe erro exit('<p><b>Falha na conexão com o mysql</b>: '.$e->getMessage().'</p>'); } // tenta definir o padrão de caracteres if (!$sqli->set_charset('utf8')) { // se não conseguir definir o padrão de caracteres, exibe o padrão disponível exit("<p class='text-danger'>Seu charset não é utf8, chefe!<br>$sqli->character_set_name()</p>"); } // tenta selecionar/abrir o banco de dados para trabalhar if (!$sqli->select_db($config['db_name'])) { // se o banco de dados não for encontrado: exit("<p class='text-danger'>Banco de dados não encontrado, chefe!</p>"); } return $sqli; public_html/index.php <?php session_start(); if(!isset($_SESSION['user'])) { header('Location: login.php'); } ?> <!doctype html> <html lang="en" data-bs-theme="auto"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> <meta name="generator" content="Hugo 0.118.2"> <title>Dashboard</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> </head> <body> <nav class="navbar navbar-light bg-light"> <div class="container-fluid"> <a class="navbar-brand">Império Verde</a> <?php echo "olá {$_SESSION['user']->name}!" ."<a href='logout.php' class='btn btn-danger'>Sair</a>"; ?> </div> </nav> <script src="assets/js/color-modes.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script> </body> </html> public_html/login.php <?php // define errors vazio $errors = []; $login = $password = ''; // conexão com o database $sqli = require '../app/connection.php'; if ($_SERVER['REQUEST_METHOD'] == 'POST') { // recebe os dados do formulário $login = filter_input(INPUT_POST, 'email'); $password = filter_input(INPUT_POST, 'password'); // valida o login if (empty($login)) { $errors['email'] = 'O campo de email deve ser preenchido.'; } // valida a senha if (empty($password)) { $errors['password'] = 'O campo de senha deve ser preenchido.'; } // se não houver erro de input if (!count($errors)) { // escapa as strings para evitar sql injection $login_escaped = $sqli->real_escape_string($login); // use prepared statement pra evitar injections $stmt = $sqli->prepare('SELECT id, email, name, password FROM cadastros WHERE email = ?'); // executa a consulta $stmt->bind_param('s', $login_escaped); $stmt->execute(); $result = $stmt->get_result(); // se nenhum user foi encontrao if (!$result->num_rows) { $errors['password'] = 'Usuário ou senha incorreta.'; } // guarda o resultado da busca em $user $user = $result->fetch_object(); // verifica se a senha está correta if ($user && !password_verify($password, $user->password)) { $errors['password'] = 'Usuário ou senha incorreta.'; } // se não há erros de database if (!count($errors)) { // guarda o user na sessão $_SESSION['user'] = $user; // volta para o index header('Location: ./'); exit(); } } } ?> <!DOCTYPE html> <html lang="en" data-bs-theme="dark"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Login</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous"> <link rel="stylesheet" href="assets/css/style.css"> </head> <body class="d-flex align-items-center py-4 bg-body-tertiary"> <main class="form-signin w-100 m-auto"> <form method='post'> <img class="mb-4" src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57"> <h1 class="h3 mb-3 fw-normal">Please Log in</h1> <div class="form-floating"> <input type="email" class="form-control" name="email" value="<?= $login ?>" placeholder="[email protected]" required> <label for="floatingInput">Email</label> </div> <div class="form-floating"> <input type="password" class="form-control" value="<?= $password ?>" name="password" placeholder="Password" required> <label>Password</label> </div> <small class="d-block text-danger"><?= isset($errors['password']) ? $errors['password'] : '' ?></small> <small class="d-block text-danger"><?= isset($errors['email']) ? $errors['email'] : '' ?></small> <button class="btn btn-primary w-100 py-2 mt-4" type="submit">Login in</button> <p class="mt-5 mb-3 text-body-secondary">© 2024</p> </form> </main> </body> </html> database.sql drop schema if exists `my-database`; create schema `my-database`; use `my-database`; -- -- -- drop table if exists cadastros; create table cadastros ( id varchar(192) not null primary key, email varchar(192) unique, name varchar(192), password varchar(192), status tinyint(1) comment '0=desativado;1=ativo', created_by varchar(192), created_at timestamp default current_timestamp, updated_at datetime null ) Engine = InnoDB; insert into cadastros (id, email, name, password) values ( 'b2a22bfa-0fd0-406b-8904-ece488003e21', '[email protected]', 'Carlos Admin', '$2y$10$JnA1Tcf2ZhyFf7lPRqYptezjuaf3yv0FhOZCJWjiW18uQexNd1YL.' ); se preferir, pode baixar aqui: https://github.com/w-studies/carlos-fw login: [email protected] password: sua-senha
  4. @Carlos FW Informatica a senha não pode ser gravada sem criptografia no banco de dados. Vou te escrever uma sugestão.
  5. Olá! Se puder, envie um screenshot de como está e outro, de como deve ficar.
  6. É bem como o colega argumentou: Se não tiver o código fonte original, que transpilou nesse daí: Do zero!!! Comecei um aqui. Veja se te ajuda: https://codepen.io/washalbano/pen/YzBLVjv Visualiza bem em telas bem pequenas. mas ainda não está 100% responsivo
  7. passe o link inteiro. ex.: 'link' => '?p=foto' ou: 'link' => 'https://google.com' sugiro passar até mais um atributo: 'target' => '_blank' e ao montar o menu: $navigator .= "<a href='$item[link]' target='$item[target]' $active>"
  8. Olá! percebi que você tem forms dentro de outro form. Remova eles pra ver: Testei aqui. Funcionou:
  9. Bom, pelo que pude perceber, você não precisa de uma lista. Então segue sugestão usando nav, com php: <?php $menu = [ [ 'icon' => 'fa-image', 'link' => 'foto', 'label' => 'Foto', ], [ 'icon' => 'fa-Vídeo', 'link' => 'videos', 'label' => 'Vídeos', ], [ 'icon' => 'fa-music', 'link' => 'musica', 'label' => 'Música', ], [ 'icon' => 'fa-users', 'link' => 'usuarios', 'label' => 'Usuários', ], [ 'icon' => 'fa-computer', 'link' => 'pcs', 'label' => 'Computadores', ], [ 'icon' => 'fa-microchip', 'link' => 'BIOS', 'label' => 'BIOS', ], ]; $page = $_GET['p'] ?? 'BIOS' ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>admtwbful menu buttons</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </head> <body> <?php $navigator = '<nav>'; foreach ($menu as $item) { $active = $item['link'] === $page ? ' class="active"' : ''; $navigator .= "<a href='?p=$item[link]'$active>" ."<div class='icon'><i class='fa-solid $item[icon]'></i></div>" ."<span>$item[label]</span>" .'</a>'; } echo $navigator.'</nav>'; ?> </body> </html> :root { --size: 50px; } * { box-sizing: border-box; } body { font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; background-color: #7f7f7f; } nav { /* Definindo este elemento como "flex" */ display: flex; /* Alinhamento Vertical para os elementos internos - no caso os "li's" */ align-items: center; /* Alinhamento Horizontal */ /* Obs. Para alinhar à esquerda, utilize: "start", para a direita: "end" e justificar + espaçar igualmente os "li's": "space-between" */ justify-content: center; gap: 4px; } nav a { /* Definindo os elementos "li" como flex e o alinhamento dos itens internos destes (mesmo conceito do bloco "ul" acima) */ display: flex; align-items: center; /* Definindo altura e largura inicial - e outros estilos apenas visualizar o comportamento */ max-width: var(--size); height: var(--size); /* border: 1px solid #ddd; */ box-shadow: inset 0 0 0 1px #ddd; /* Alterar o cursor do mouse quando "hover" no elemento */ color: white; /* Definindo uma transição suave quando "out hover" do elemento */ transition: all 0.5s ease; text-decoration: none; overflow: hidden; padding-right: 24px; } nav a span { opacity: 0; transition: all 0.5s ease; } nav a:hover, nav a.active { /* Muda a largura inicial do elemento "li" quando "hover" */ /* Obs. Aqui você define o tamanho/largura expandido que deseja - pode usar medidas relativas também ( % ) */ max-width: 300px; transition: max-width 1.75s ease; } nav a:hover span, nav a.active span { opacity: 1; } nav a:hover .icon, nav a.active .icon { border-top: 3px solid #157dad; } nav a:first-child { background: #e8c813; } nav a:nth-child(2) { background: #ad1515; } nav a:nth-child(3) { background: #15ad36; } nav a:nth-child(4) { background: #2112a8; } nav a:nth-child(5) { background: #157dad; } nav a:nth-child(6) { background: #000000; } nav a:nth-child(7) { background: #9f9f00; } nav .icon { border: 3px solid transparent; min-width: var(--size); height: var(--size); display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; } screenshot de botão foto ativado + hover sobre o botão Computadores
  10. Olá! Segue sugestão: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </head> <body> <header> <div class="icone-header"> <img src="LOGO (1).jpg" alt=""> </div> <div class="info-header"> <div class="logo"> <h3>Gestao de Banco</h3> </div> </div> </header> <!-- Fim do Header--> <section class="main"> <nav class="sidebar"> <br> <a href="home">Home</a> <hr> <br> <a href="dashboard">Dashboard</a> <hr> <br> <a href="previsao-de-clientes">Previsao de Clientes</a> <br> <hr> <a href="about">Conheça-nos</a> <hr> </nav> <main> </main> </section> <template id='home'> <h1>Bem vindo ao banco</h1> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium voluptatum commodi eos quas nobis natus quisquam perspiciatis, dolorum facere reprehenderit. Quaerat non nihil repellat possimus eligendi officiis molestiae laudantium accusantium?</p> </template> <template id='dashboard'> <h1>Dashboard</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque, eius itaque, molestias praesentium porro dicta modi vel nostrum minus corrupti earum. Tempore exercitationem totam odio! Quae reiciendis alias ad quos!</p> </template> <template id='previsao-de-clientes'> <h1>Dashboard</h1> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla inventore id aliquid nostrum! Illum omnis corrupti at earum quidem excepturi? Nam voluptas quas deleniti non quasi quos quisquam dicta. Saepe?</p> </template> <script src="assets/js/app.js"></script> </body> </html> const sidebar = document.querySelector('nav.sidebar') const main = document.querySelector('main') sidebar.onclick = (e) => { e.preventDefault() const { target } = e if (target.matches('a')) { const id = target.getAttribute('href') const template = document.querySelector(`template#${id}`) let mainContent = '<h1>Oops! Página não encontrada!</h1>' if (template) { mainContent = template.innerHTML } main.innerHTML = mainContent } } veja um exemplo funcionando aqui: https://codepen.io/washalbano/pen/xxMZYzx
  11. Olá! Talvez seja o caso de resolver com flex, veja: <main> <div><a href="https://www.admu.org.br">Quem Somos</a><a href="https://www.admu.org.br">Quem Somos</a></div> <div> <p><img src="https://loremflickr.com/220/60" width="100%" alt="" /></p> </div> </main> main { display: flex; div { &:first-child { width: 49%; background: #ff0004; text-align: left; } &:last-child { width: 30%; text-align: left; background: #fffd00; } } } https://codepen.io/washalbano/pen/jOQyvbJ Ou talvez dependa do tamanho da sua imagem
  12. Olá! Não entendi porque você criou essa variável dados. você pode resolver de outra forma. segue sugestão: <script> const tabela = document.querySelector("#tabela"); const cidade = document.querySelector("#cidade"); const adicionar = document.querySelector("#adicionar"); adicionar.addEventListener("click", add); function add() { const nome = document.querySelector("#nome").value; const indice = cidade.selectedIndex; const cidadeTexto = cidade.options[indice].text; const cidadeValor = cidade.value; const idade = document.querySelector("#idade").value; // insere uma linha na tabela const row = tabela.querySelector('tbody').insertRow() // insere a primeira célula na linha row.insertCell().innerHTML = nome // insere a segunda célula na linha row.insertCell().innerHTML = cidadeTexto // insere a terceira célula na linha row.insertCell().innerHTML = idade } </script> Se é trabalho de escola e você é obrigado a usar uma estrutura de repetição, segue outra sugestão <script> const tabela = document.querySelector("#tabela"); const cidade = document.querySelector("#cidade"); const add = () => { const rowData = [ document.querySelector("#nome").value, cidade.options[cidade.selectedIndex].text, document.querySelector("#idade").value ] // insere uma linha na tabela const row = tabela.querySelector('tbody').insertRow() for (item of rowData) { row.insertCell().innerHTML = item } } document.querySelector("#adicionar").addEventListener("click", add); </script>
  13. Olá! Essa mensagem aí está dizendo que essa requisição não encontrou nenhum recurso a ser retornado
  14. Olá! Não vi nada de php aí. Veja se era +- isso que pretendias: html <label for="quantidade">Quantidade</label> <input type="number" step='1' min='0' name="quantidade" id="quantidade" value='0'> <label for="valorunit">Valor Unitário</label> <input type="number" step='.1' min='0' name="valorunit" id="valorunit" value='0'/> <label for="desconto">Desconto</label> <input type="number" step='.1' min='0' name="desconto" id="desconto" value='0'/> <label for="valorserv">Valor</label> <input type="text" id="resultado" readonly="readonly"> js function calcular() { const quantidade = parseInt(document.getElementById("quantidade").value); const valorunit = parseFloat(document.getElementById("valorunit").value); const desconto = parseFloat(document.getElementById("desconto").value); document.getElementById("resultado").value = ( quantidade * valorunit - desconto ).toLocaleString("pt-br", { style: "currency", currency: "BRL" }); } const inputIds = ["quantidade", "valorunit", "desconto"]; for (const id of inputIds) { document.getElementById(id).addEventListener("input", calcular); } https://codepen.io/washalbano/pen/zYLMbQo
  15. Q bom q resolveu! Se a coluna se chama id_envia, por quê tá gravando nomes e não ids?
  16. Olá! Exibir com que intuito? Se for apenas para debugar, segue sugestão: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Debugar objeto</title> <style> div.objeto { font-family: monospace; white-space: pre; } </style> </head> <body> <div class="objeto"></div> <script> let meuObjeto = { nome: 'Faca', marca: 'Tramontina', valor: 'R$ 45,00' } document.querySelector('.objeto').innerHTML = JSON.stringify({ meuObjeto }, null, 2) </script> </body> </html>
  17. Olá! você precisa de um script mais robusto. Que seja capaz de te informar quando e onde há alguma falha. Segue sugestão (Oops! Tipei um arquivo em php8): index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> input { display: block } .response-table { font-family: monospace; white-space: pre; } </style> </head> <body> <main> <form> <div> <label>Curso</label> <input type="text" name="curso" value="Matemática" required autofocus> </div> <div> <label>Valor</label> <input type="number" name="valor" value="158.90" required step=".1"> </div> <div> <br> <button>Salvar</button> </div> </form> <div class="response-body"></div> <h2>Get Cursos</h2> <div class="response-table"></div> </main> <script src="assets/app.js"></script> </body> </html> assets/app.js /** * TREAT RESPONSE * @param {*} response */ const treatResponse = async (response) => { let body // se no cabeçalho da response tiver json if (response.headers.get('content-type').includes('json')) { // trata a response como json body = await response.json() } else { // trata a response como texto body = await response.text() } return body } /** * CADASTRAR * @param {*} e */ const cadastrar = async (e) => { // evita que o submit do form atualize a página e.preventDefault() // define o formData const fData = new FormData(e.target) // submete os dados do form e espera pela resposta const response = await fetch(`api/`, { method: 'post', body: fData }) const body = await treatResponse(response) // mostra a resposta na tela document.querySelector('.response-body').innerHTML = body // atualiza os dados da tabela getTableData() } // escuta o submit do form document.querySelector('form').addEventListener('submit', cadastrar) /** * GET TABLE DATA */ const getTableData = async () => { // submete a requisição e espera pela resposta const response = await fetch(`api/cursos`, { method: 'get' }) const body = await treatResponse(response) console.log('response :>> ', body) // mostra a resposta na tela document.querySelector('.response-table').innerHTML = JSON.stringify(body, null, 2) } getTableData() api/index.php <?php // se algo foi postado if (sizeof($_POST)) { // conecta ao database require 'connection.php'; // extrai as variáveis em $_POST extract($_POST); // escapa os valores das variáveis $curso = $sqli->real_escape_string($curso); $valor = $sqli->real_escape_string($valor); // monta a query de inserção $query = "insert into cursos set curso='$curso', valor='$valor'"; // executa a query $sqli->query($query); // verifica se houve alguma falha na execução da query if ($sqli->error) { // devolve json com a mensagem de erro jsonResponse('<p class="text-danger"><b>ERROR</b>: ' . $sqli->error . '</p><small class="text-secondary">' . __FILE__ . ' at line: ' . __LINE__ . '<small>', 500); // se não houve falha } elseif ($sqli->affected_rows) { // devolve mensagem de sucesso jsonResponse('Registro inserido com sucesso, chefe!'); } else { // devolve json com a mensagem de erro jsonResponse('Nada foi alterado, chefe!', 400); } } api/connection.php <?php require 'helpers/httpResponse.php'; // definição de variáveis para conexão $host = 'localhost'; // servidor $user = 'root'; // nome do utilizador $pass = 'my-secret-pw'; // senha ou password $database = 'studies'; // nome da base de dados // estabelecer conexão: $sqli = new mysqli($host, $user, $pass); // verificando se conectou de boas: if ($sqli->connect_error) { // se houver alguma falha, exibe mensagem: jsonResponse('<p class="text-danger">Falha na conexão: ' . $sqli->connect_error . '</p>', 400); } // definir o padrão de caracteres if (!$sqli->set_charset('utf8')) { // se não conseguir definir o padrão de caracteres, exibe o padrão disponível jsonResponse("<p class='text-danger'>Seu charset não é utf8, chefe!<br>$sqli->character_set_name()</p>", 400); } // selecionar/abrir o banco de dados para trabalhar if (!$sqli->select_db($database)) { // se o banco de dados não for encontrado jsonResponse("<p class='text-danger'>Banco de dados não encontrado, chefe!</p>", 400); } database.sql set names utf8mb4; drop schema if exists studies; create schema studies; use studies; create table cursos( id int not null auto_increment primary key, curso varchar(191), valor decimal(10,2), created_at timestamp default current_timestamp ); insert into cursos(curso, valor) values ('Português', 100.99); api/helpers/httpResponse.php <?php /** * @param string|array|null $data * @param int $code * @return void */ function jsonResponse(string|array $data = null, int $code = 200): void { // clear the old headers header_remove(); // set the actual code http_response_code($code); // treat this as json header('Content-Type: application/json'); $status = [ 200 => '200 OK', 400 => '400 Bad Request', 404 => '400 Not Found', 422 => 'Unprocessable Entity', 500 => '500 Internal Server Error' ]; // ok, validation error, or failure header('Status: ' . $status[$code]); if ($code !== 200) { // guarda os dados do backtrace $debug = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]; if (is_array($data)) { $data['debug'] = $debug; } else { $data .= "<small class='text-secondary'><b>FILE</b>: $debug[file], <b>LINE</b>: $debug[line]<small>"; } } // return the encoded json die(is_array($data) ? json_encode($data) : '"' . $data . '"'); } api/cursos/index.php <?php // conecta ao database require '../connection.php'; // define a query de busca $query = 'select * from cursos order by created_at desc'; // executa a query de busca e guarda o resultado em $result $result = $sqli->query($query); // verifica se houve alguma falha na execução da query if ($sqli->error) { // se houve alguma falha, exibe mensagem: jsonResponse('<p class="text-danger"><b>Falha na conexão</b>: ' . $sqli->error . '</p>', 500); // se não houve falha e algum registro foi encontrado } elseif ($result->num_rows) { // guarda os registros em $dada $data = $result->fetch_all(MYSQLI_ASSOC); // encerra o script devolvendo um json jsonResponse(['data' => $data]); // se não houve erro e nenhum registro foi encontrado } else { // devolve json com mensagem jsonResponse('Nenhum registro foi encontrado.', 404); } screenshot
  18. Olá! Não sei quando surgiu o fetch, mas uso desde 2018 O fetch veio pra solucionar uma porção de problemas do XMLHttpRequest. Acredito que talvez a solução mais conhecida seja trabalhar com promises. Segue sugestão para POST form data usando fetch: api/index.php <?php $curso = $_POST["curso"]; $valor = $_POST["valor"]; $query = "INSERT INTO cursos VALUES (null, '$curso', $valor)"; echo '<pre>$_POST: '; print_r($_POST); echo '</pre>'; echo '<pre>$query: '; print_r($query); echo '</pre>'; index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> input { display: block } </style> </head> <body> <main> <form> <div> <label>Curso</label> <input type="text" name="curso" value="Matemática" required autofocus> </div> <div> <label>Valor</label> <input type="number" name="valor" value="158.90" required step=".1"> </div> <div> <br> <button>Salvar</button> </div> </form> <div class="response-body"></div> </main> <script> const cadastrar = async (e) => { // evita que o submit do form atualize a página e.preventDefault(); // define o formData const fData = new FormData(e.target) // submete os dados do form e espera pela resposta const response = await fetch('api/', { method: 'post', body: fData }) let body // se no cabeçalho da response tiver json if (response.headers.get('content-type').includes('json')) { // trata a response como json body = await response.json() } else { // trata a response como texto body = await response.text() } // mostra a resposta na tela document.querySelector('.response-body').innerHTML = body } // escuta o submit do form document.querySelector('form').addEventListener('submit', cadastrar); </script> </body> </html> screenshot:
  19. Sugestão const body = document.querySelector('body') // set colors const colors = [ 'red', 'green', 'blue', 'gold', 'firebrick', 'olive', 'cyan', 'magenta', 'yellow', 'navy' ] // set initial color let colorIndex = 0 function changeColor() { body.style.backgroundColor = colors[colorIndex] // next index colorIndex++ // if index is equal array.length, then get back to zero colorIndex = colorIndex === colors.length ? 0 : colorIndex }
  20. Boa tarde. Acredito que cada dev vai te indicar um caminho. ⟶ ou seja: há inúmeros caminhos que podes seguir. Veja se esse roadmap te orienta: https://roadmap.sh/frontend
  21. Olá! Isso acontece por causa de um cache automático dos browsers. Pode variar entre minutos e meses. Uma forma de contornar é toda vez que atualizar seu css passar uma nova variável informando a versão onde ele é carregado. ex.: <link rel="stylesheet" href="seu-arquivo.css?v2"/> <link rel="stylesheet" href="seu-arquivo.css?v2.1"/> cada vez que essa variável mudar, um novo cache será criado Só lembrando que há outras formas de se customizar o tempo de cache para tipos específicos de arquivo. Mas exige conhecimento mais aprofundado. (q eu não tenho)

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!