'Why on event submit it excute another function? [duplicate]

I am making a form, I have a function to reset all the fields, and I have a function to validate the fields. I have two buttons, send email and reset form. The botton to send the email it is type = "submit", and the reset button is a simple button.

The problem is when I click the reset button, it executes the send function, it is something like the browser think reset button is submiting the the form.

//Variables
const sendBtn = document.querySelector("#enviar");
const resetBtn = document.querySelector("#resetBtn");
const email = document.querySelector("#email");
const subject = document.querySelector("#asunto");
const message = document.querySelector("#mensaje");
const form = document.querySelector("#enviar-mail");
const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;


loadEventListeners()
//eventlistener
function loadEventListeners() {
    //when the app starts
    document.addEventListener("DOMContentLoaded", startApp);

    //form fields
    email.addEventListener("blur", validateForm);
    subject.addEventListener("blur", validateForm);
    message.addEventListener("blur", validateForm);

    //submit button
    form.addEventListener("submit", sendEmail);

    //reset form
    resetBtn.addEventListener("click", resetFields);


}

//functions
function startApp() {
    sendBtn.disabled = true;
    sendBtn.classList.add("cursor-not-allowed", "opacity-50");
}

//validate form
function validateForm(e) {

    //validate if there is text on the field
    if(e.target.value.length > 0 ) {
        //delete the errors
        const error = document.querySelector("p.error");
        if(error){
            error.remove();
        };
        
        e.target.style.border = "2px solid green";

    }else {
        e.target.style.border = "2px solid red";
        showError("Todos los campos son obligatorios");
    };

    //validate email with regular expresion
    if(e.target.type === "email") {
        

        if(re.test( e.target.value ) ) {
            const error = document.querySelector("p.error");
            if(error){
                error.remove();
            };
            e.target.style.border = "2px solid green";
        } else if(e.target.value === ""){
            const error = document.querySelector("p.error");
            if(error){
                error.remove();
            };
            showError("Todos los campos son obligatorios");
        } else {
            e.target.style.border = "2px solid red";
            showError("El email no es correcto!");
        }
    }

    //if everything is ok
    if( re.test( email.value ) && message.value !== "" && subject.value !== ""){
        sendBtn.disabled = false;
        sendBtn.classList.remove("cursor-not-allowed", "opacity-50");
    }

}

function showError(message) {
    let textError = document.createElement("p");
    textError.textContent = message;
    textError.style.border = "1px solid red";
    textError.style.color = "red";
    textError.style.marginTop = "5px";
    textError.classList.add("error"); //to identify the error message

    //avoid duplicate error message
    const errors = document.querySelectorAll(".error"); //to know if there is an error
    if(errors.length < 1) {
        form.appendChild(textError);
    };

}

function sendEmail(e) {
    e.preventDefault();

    //Showing the spinner
    const spinner = document.querySelector("#spinner");
    spinner.style.display = "flex";

    //after 3 seconds of showinf the spinner

    setTimeout( () => {
        spinner.style.display = "none";
        console.log("mensaje enviado");
        resetFields();}, 3000);
}

function resetFields() {
    //#1 way
    // email.value = "";
    // subject.value = "";
    // message.value = '';
    // 

    //#2 way
    form.reset();
    email.style.border = "";
    subject.style.border = "";
    message.style.border = '';

    startApp();
}
body {
    background: #43cea2;
    background: -webkit-linear-gradient(to right, #185a9d, #43cea2);
    background: linear-gradient(to right, #185a9d, #43cea2); 
}
#contenido {
    background-color: white;
    margin-top: 40px;
    -webkit-box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3);
    box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.3);
}
#contenido::after {
    clear: both;
    display: block;
    content: '';
}
header {
    padding: 10px;
    text-align: center;
    color: white;
    font-size: 22px;
    font-family: 'Raleway', sans-serif;
    font-weight: 100;
}
form {
    margin: 30px 0;
}
#loaders {
    text-align: center;
}
#resetBtn {
    float: right;
}

#spinner {
    display: none;
    justify-content: center;
    padding: 3rem 0;
}


.sk-chase {
    width: 40px;
    height: 40px;
    position: relative;
    animation: sk-chase 2.5s infinite linear both;
  }
  
  .sk-chase-dot {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0; 
    animation: sk-chase-dot 2.0s infinite ease-in-out both; 
  }
  
  .sk-chase-dot:before {
    content: '';
    display: block;
    width: 25%;
    height: 25%;
    background-color: #0288d1;
    border-radius: 100%;
    animation: sk-chase-dot-before 2.0s infinite ease-in-out both; 
  }
  
  .sk-chase-dot:nth-child(1) { animation-delay: -1.1s; }
  .sk-chase-dot:nth-child(2) { animation-delay: -1.0s; }
  .sk-chase-dot:nth-child(3) { animation-delay: -0.9s; }
  .sk-chase-dot:nth-child(4) { animation-delay: -0.8s; }
  .sk-chase-dot:nth-child(5) { animation-delay: -0.7s; }
  .sk-chase-dot:nth-child(6) { animation-delay: -0.6s; }
  .sk-chase-dot:nth-child(1):before { animation-delay: -1.1s; }
  .sk-chase-dot:nth-child(2):before { animation-delay: -1.0s; }
  .sk-chase-dot:nth-child(3):before { animation-delay: -0.9s; }
  .sk-chase-dot:nth-child(4):before { animation-delay: -0.8s; }
  .sk-chase-dot:nth-child(5):before { animation-delay: -0.7s; }
  .sk-chase-dot:nth-child(6):before { animation-delay: -0.6s; }
  
  @keyframes sk-chase {
    100% { transform: rotate(360deg); } 
  }
  
  @keyframes sk-chase-dot {
    80%, 100% { transform: rotate(360deg); } 
  }
  
  @keyframes sk-chase-dot-before {
    50% {
      transform: scale(0.4); 
    } 100%, 0% {
      transform: scale(1.0); 
    } 
  }

  
<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Raleway:100,300" rel="stylesheet">
    <!-- <link type="text/css" rel="stylesheet" href="https://github.com/albinr3/proyecto-enviar-email/blob/master/css/tailwind.min.css"  media="screen,projection"/> -->
    <link rel="stylesheet" href="css/custom.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Enviar Email</title>
    <script src="https://cdn.tailwindcss.com"></script>
  </head>
  <body>

    <div class="container mx-auto mt-20 bg-white">     
        <header id="header" class="bg-pink-800 p-3 font-bold">
            Enviar Nuevo Mail
        </header>


        <form id="enviar-mail" class="py-10 px-5 max-w-lg mx-auto">
            <div class="mb-10">
                <label for="email">Para:</label>
                <input class="bg-gray-100 border shadow p-3 w-full"  id="email" type="email">
            </div>
            <div class="mb-10">
                <label for="asunto">Asunto</label>
                <input class="bg-gray-100 border shadow p-3 w-full"  id="asunto" type="text">
            </div>
            <div class="mb-10"> 
                <label for="mensaje">Mensaje</label>
                <textarea class="bg-gray-100 border shadow p-3 w-full" id="mensaje"></textarea>
            </div>

            <div  id="spinner">
                <div class="sk-chase">
                    <div class="sk-chase-dot"></div>
                    <div class="sk-chase-dot"></div>
                    <div class="sk-chase-dot"></div>
                    <div class="sk-chase-dot"></div>
                    <div class="sk-chase-dot"></div>
                    <div class="sk-chase-dot"></div>
                </div>
            </div>
            
            <div class="flex justify-between">
                    <button 
                        id="enviar" class="w-full bg-blue-600 px-2 py-5 text-white items-center cursor-not-allowed opacity-50 mr-5 uppercase font-bold items-center flex justify-center" 
                        type="submit" 
                    >Send
                        <i class="material-icons right text-white ml-3">send</i>
                    </button>

                    <button 
                        id="resetBtn" 
                        class="w-full bg-green-600 px-2 py-5 text-white items-center uppercase font-bold items-center flex justify-center">Reset Form<i class="material-icons right ml-3"></i>
                    </button>
            </div>
        </form> 
    </div>

    <script src="js/app.js"></script>
  </body>
</html>


Solution 1:[1]

Since <button> inside the <form> tag is always acting as submit, unless you specify otherwise.

In order to fix that behavior, you could add type="button" or dedicated type="reset" attribute:

                    <button 
                        id="resetBtn"
                        type="button" 
                        class="w-full bg-green-600 px-2 py-5 text-white items-center uppercase font-bold items-center flex justify-center">Reset Form<i class="material-icons right ml-3"></i>
                    </button>

Documentation reference

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1