├── README.md ├── app.js ├── index.html └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # Formulário de Contato com JavaScript 2 | 3 | Como Enviar um Formulário HTML com JavaScript Sem Sair da Página. [Veja mais](https://www.youtube.com/watch?v=TLkds5BJ-vA). 4 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | class FormSubmit { 2 | constructor(settings) { 3 | this.settings = settings; 4 | this.form = document.querySelector(settings.form); 5 | this.formButton = document.querySelector(settings.button); 6 | if (this.form) { 7 | this.url = this.form.getAttribute("action"); 8 | } 9 | this.sendForm = this.sendForm.bind(this); 10 | } 11 | 12 | displaySuccess() { 13 | this.form.innerHTML = this.settings.success; 14 | } 15 | 16 | displayError() { 17 | this.form.innerHTML = this.settings.error; 18 | } 19 | 20 | getFormObject() { 21 | const formObject = {}; 22 | const fields = this.form.querySelectorAll("[name]"); 23 | fields.forEach((field) => { 24 | formObject[field.getAttribute("name")] = field.value; 25 | }); 26 | return formObject; 27 | } 28 | 29 | onSubmission(event) { 30 | event.preventDefault(); 31 | event.target.disabled = true; 32 | event.target.innerText = "Enviando..."; 33 | } 34 | 35 | async sendForm(event) { 36 | try { 37 | this.onSubmission(event); 38 | await fetch(this.url, { 39 | method: "POST", 40 | headers: { 41 | "Content-Type": "application/json", 42 | Accept: "application/json", 43 | }, 44 | body: JSON.stringify(this.getFormObject()), 45 | }); 46 | this.displaySuccess(); 47 | } catch (error) { 48 | this.displayError(); 49 | throw new Error(error); 50 | } 51 | } 52 | 53 | init() { 54 | if (this.form) this.formButton.addEventListener("click", this.sendForm); 55 | return this; 56 | } 57 | } 58 | 59 | const formSubmit = new FormSubmit({ 60 | form: "[data-form]", 61 | button: "[data-button]", 62 | success: "

Mensagem enviada!

", 63 | error: "

Não foi possível enviar sua mensagem.

", 64 | }); 65 | formSubmit.init(); 66 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Formulário de Contato com JavaScript 8 | 9 | 10 | 11 | 12 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | min-height: 100vh; 9 | display: grid; 10 | place-items: center; 11 | padding: 1rem; 12 | background: #272a37; 13 | font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 14 | Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; 15 | } 16 | 17 | form { 18 | width: 100%; 19 | max-width: 30rem; 20 | } 21 | 22 | label, 23 | input, 24 | textarea, 25 | button { 26 | display: block; 27 | } 28 | 29 | input, 30 | textarea, 31 | button { 32 | width: 100%; 33 | font: inherit; 34 | padding: 1.25rem; 35 | font-weight: 700; 36 | } 37 | 38 | input, 39 | textarea { 40 | margin-bottom: 1rem; 41 | color: white; 42 | background: #323644; 43 | border: 0.125rem solid transparent; 44 | border-radius: 1.125rem; 45 | transition: border-color 0.3s, box-shadow 0.3s; 46 | } 47 | 48 | input:hover, 49 | input:focus, 50 | textarea:hover, 51 | textarea:focus { 52 | outline: none; 53 | border-color: #1d90f5; 54 | box-shadow: 0 0 0 0.3125rem #26344a; 55 | } 56 | 57 | label { 58 | margin-bottom: 0.5rem; 59 | color: #84868f; 60 | } 61 | 62 | textarea { 63 | min-height: 12.5rem; 64 | resize: vertical; 65 | } 66 | 67 | button { 68 | border: none; 69 | border-radius: 99px; 70 | color: white; 71 | background: #1d90f5; 72 | cursor: pointer; 73 | transition: 0.3s; 74 | } 75 | 76 | button:hover, 77 | button:focus { 78 | outline: none; 79 | background: #1c70d3; 80 | } 81 | 82 | button:disabled { 83 | cursor: not-allowed; 84 | background: #555b69; 85 | } 86 | 87 | .success, 88 | .error { 89 | text-align: center; 90 | } 91 | 92 | .success { 93 | color: greenyellow; 94 | } 95 | 96 | .error { 97 | color: tomato; 98 | } 99 | --------------------------------------------------------------------------------