Search code examples
javascriptformsvalidationbootstrap-5

Form validation fails


I try to create form for POST the new user but have a problem. I use the bootstrap form validation (Browser defaults). Have a button:

<button class="btn btn-primary btn-addUser" type="submit">Add User</button>

This button also has the function of creating a new post based on the data from the input:

const addUsersBtn = document.querySelector(".btn-addUser");

// post add button in html
addUsersBtn.addEventListener("click", postNewUser);

// Post a user
function postNewUser(e) {
  e.preventDefault();
  // write value from form inputs
  const name = form.elements.namedItem("name").value;
  const username = form.elements.namedItem("username").value;
  const email = form.elements.namedItem("email").value;
  const phone = form.elements.namedItem("phone").value;
  const website = form.elements.namedItem("website").value;

  // create our user object from data recorded in variables from form inputs
  const newPost = {
    name: name,
    username: username,
    email: email,
    phone: phone,
    website: website,
    user_id: `id_${Math.random() * Math.random()}`,
  };

  // create a post
  createPost(newPost, (response) => {
    const card = newPostTemplate(response);
    container.insertAdjacentElement("afterbegin", card);
    form.reset();
    initPopovers();
  });
}

But if i use the function postNewUser validation has not work. If i delete the "btn-addUser" class from button validation works. My code from addUser.js file:

// получаем нашу форму
const form = document.forms["addUser"];
// create a “create post” function
function createPost(body, callback) {
  return new Promise((resolve, reject) => {
    const request = new XMLHttpRequest();
    request.open("POST", "https://jsonplaceholder.typicode.com/posts");
    request.addEventListener("load", () => {
      const response = JSON.parse(request.responseText);
      //   console.log(response);
      if (request.status >= 400) {
        reject(request.response);
      } else {
        resolve(request.response);
      }
      callback(response);
    });
    request.setRequestHeader("Content-type", "application/json; charset=UTF-8");
    request.send(JSON.stringify(body));
  });
}
// template for the post in which it will be built
function newPostTemplate(post) {
  const card = document.createElement("div");
  card.classList.add("card");

  const cardBody = document.createElement("div");
  cardBody.classList.add("card-body");

  const userBtn = document.createElement("button");
  userBtn.setAttribute("type", "button");
  userBtn.classList.add("btn", "btn-info", "btn-lg");
  userBtn.setAttribute("data-bs-toggle", "popover");
  userBtn.setAttribute("data-bs-html", "true");
  userBtn.setAttribute(
    "data-bs-title",
    "Additional information about the user: "
  );
  userBtn.setAttribute(
    "data-bs-content",
    `Username: ${post.username}<br/>Email: ${post.email}<br/>Phone: ${post.phone}<br/> Website: ${post.website}`
  );
  const title = document.createElement("h5");
  title.classList.add("card-title");
  title.textContent = post.name;

  userBtn.appendChild(title);
  cardBody.appendChild(userBtn);
  card.appendChild(cardBody);
  return card;
}
// button to add post in html
addUsersBtn.addEventListener("click", postNewUser);
// function Post user
function postNewUser(e) {
  e.preventDefault();
  // write value from form inputs
  const name = form.elements.namedItem("name").value;
  const username = form.elements.namedItem("username").value;
  const email = form.elements.namedItem("email").value;
  const phone = form.elements.namedItem("phone").value;
  const website = form.elements.namedItem("website").value;
  // create our user object from data recorded in variables from form inputs
  const newPost = {
    name: name,
    username: username,
    email: email,
    phone: phone,
    website: website,
    user_id: `id_${Math.random() * Math.random()}`,
  };
  // create a post
  createPost(newPost, (response) => {
    const card = newPostTemplate(response);
    container.insertAdjacentElement("afterbegin", card);
    form.reset();
    initPopovers();
  });
}

I wanna ask some questions:

  1. Can I create two buttons: first button without 'btn-addUser' class and second button with 'btn-addUser' class? I want to add a button disabled state (bootstrap) and remove them when submit without 'btn-addUser' class receives a positive response from validation. After click button with 'btn-addUser' this button will be disabled. It's really? I don't know how to get a positive response from validation.
  2. Or maybe I'm doing garbage and it can be done much simpler?

Solution

  • e.preventDefault() in your submit event handler likely prevents browser to automatically perform its built-in validation checks when the form attempts to submit. You should manuallly check if form is valid using form.checkValidity() like this:

    function postNewUser(e) {
      e.preventDefault();
    
      if (form.checkValidity()) {
        // Form is valid, proceed with creating the new user
        // Add your custom logic here
      } else {
        // Form is invalid, trigger validation UI
        // form.classList.add("was-validated");
      }
    }
    

    Make sure your form has the necessary Bootstrap validation attributes and classes, such as novalidate on the form element and the appropriate validation classes on the form inputs.