How can I modify the color of a div when a validation error occurs?

I have recently completed a contact form with validation using the constraint validation api. Although the files are functioning as intended, I am curious if there is a method to make the error boxes turn red when an error occurs and white (or hidden) when there are no validation errors. Some of the code may be redundant at this point, but my plan is to clean it up once I am satisfied with the functionality. Currently, it seems like errors are being displayed even when everything is valid.

const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
const emailError = document.querySelector('#mail + span.error');
const navn = document.getElementById('navn');
const navnError = document.querySelector('#navn + span.error');
const telefon = document.getElementById('telefon');
const telefonError = document.querySelector('#telefon + span.error')
const message = document.getElementById('message');
const messageError = document.querySelector('#message + span.error')
const personvern = document.getElementById('personvern');
const personvernError = document.querySelector('#personvern + span.error')


// THIS DIV WILL CONTAIN ERROR MESSAGES
const errOutput = document.querySelector('.errorsOutput')


email.addEventListener('input', function(event) {
  if (email.validity.valid) {
    emailError.innerHTML = '';
    emailError.className = 'error';
  } else {
    showError();
  }

});


navn.addEventListener('input', function(event) {

  if (navn.validity.valid) {
    navnError.innerHTML = '';
    navnError.className = 'error';

  } else {
    showError();
  }

})

telefon.addEventListener('input', function(event) {

  if (telefon.validity.valid) {
    telefonError.innerHTML = '';
    telefonError.className = 'error';

  } else {
    showError();
  }

})


message.addEventListener('input', function(event) {

  if (message.validity.valid) {
    messageError.innerHTML = '';
    messageError.className = 'error';

  } else {
    showError();
  }

})

form.addEventListener('submit', function(event) {

  if (!email.validity.valid || !navn.validity.valid || !telefon.validity.valid || !message.validity.valid) {
    showError();
    event.preventDefault();
  }

});



function showError() {

  // EMPTY ERRORS DIV
  errOutput.innerHTML = ''


  if (navn.validity.valueMissing) {
    navnError.textContent = '* Du må fylle inn navnet ditt';
  } else if (navn.validity.tooShort) {
    navnError.textContect = '* Du må fylle inn hele navnet ditt'
  }
  // OUTPUT ERRORS IN DIV

  if (navnError.textContent != '') {
    errOutput.innerHTML += '<p>Navn error!</p>'
  }

  if (email.validity.valueMissing) {

    emailError.textContent = '* Vennligst fyll inn e-posten din';
  } else if (email.validity.typeMismatch) {

    emailError.textContent = '* Dette er ikke en gyldig e-postadresse.';
  } else if (email.validity.tooShort) {

    emailError.textContent = `* Email should be at least ${ email.minLength } characters; you entered ${ email.value.length }.`;
  }
  // OUTPUT ERRORS IN DIV
  if (emailError.textContent != '') {
    errOutput.innerHTML += '<p>Email error!</p>'
  }



  if (telefon.validity.valueMissing) {
    telefonError.textContent = '* Du må fylle inn telefonnummeret ditt'
  } else if (telefon.validity.tooShort) {
    telefonError.textContent = '* Du mangler ett eller flere tall. Vennligst dobbeltsjekk.'
  }
  // OUTPUT ERRORS IN DIV
  if (telefonError.textContent != '') {
    errOutput.innerHTML += '<p>Telefonnummer error!</p>'
  }

  if (message.validity.valueMissing) {
    messageError.textContent = '* Beskjeden mangler, vennligst fyll inn'
  } else if (message.validity.tooShort) {
    messageError.textContent = `* Beskjed må være minst ${ message.minLength } tegn.`;
  }
  // OUTPUT ERRORS IN DIV
  if (messageError.textContent != '') {
    errOutput.innerHTML += '<p>Beskjed error!</p>'
  }
}


// Set the styling appropriately
emailError.className = 'error active';
navnError.className = 'error active';
telefonError.className = 'error active';
messageError.className = 'error active';
personvernError.className = 'error active';
body {
  width: 600px;
  padding: 0;
  margin: 0 auto;
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
  font-size: 1.1rem;
}

p * {
  display: block;
}

input[type=text] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 500px;
  width: 100% !important;
  padding: 15px;
  border: 1px solid #333;
  margin: 0;
  font-family: inherit;
  font-size: 90%;
  box-sizing: border-box;
}

input[type=email] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 500px;
  width: 100% !important;
  padding: 15px;
  border: 1px solid #333;
  margin: 0;
  font-family: inherit;
  font-size: 90%;
  box-sizing: border-box;
}

input[type=tel] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 500px;
  width: 100% !important;
  padding: 15px;
  border: 1px solid #333;
  margin: 0;
  font-family: inherit;
  font-size: 90%;
  box-sizing: border-box;
}


/* This is our style for the invalid fields */

input:invalid {
  border-color: #900;
  background-color: #FDD;
}

input:focus:invalid {
  outline: none;
}


/* This is the style of our error messages */

.error {
  width: 100%;
  padding: 15px;
  min-height: 20px;
  font-size: 100%;
  color: white;
  background-color: #900;
  display: flex;
  justify-content: flex-start;
  margin: 1rem 0;
}

.error.active {
  padding: 0;
}

.errorsOutput {
  background-color: #ac0606;
  color: white;
  margin: 0 0 5px 0;
}

.errorsOutput p {
  padding: 1px;
}
<!DOCTYPE html>
<html>

<head>
  <script src="jquery-3.6.0.min.js"></script>
  <script src="kontaktskjema.js"></script>
  <link rel="stylesheet" href="kontakt.css">
  <meta charset="utf-8">
  <title>Kontaktskjema</title>
</head>

<body>

  <!-- THIS DIV WILL CONTAIN ERROR MESSAGES -->
  <div class="errorsOutput">
  </div>

  <div class="kontaktskjema">
    <div class="error">
      <form novalidate>
        <p>
          <label for="navn">
          <span>Navn:</span>
        <input type="text" id="navn" name="navn" required minlength="3">
        <span class="error" aria-live="polite"></span>
      </label>
        </p>
    </div>
    <div class="error">
      <form novalidate>
        <p>
          <label for="name">
            <span>Telefonnummer:</span>
            <input type="tel" id="telefon" name="telefon" required minlength="8" required maxlength="8">
            <span class="error" aria-live="polite"></span>
          </label>
        </p>
    </div>
    <div class="error">
      <form novalidate>
        <p>
          <label for="mail">
                <span>E-post:</span>
                <input type="email" id="mail" name="mail" required minlength="6">
                <span class="error" aria-live="polite"></span>
              </label>
        </p>
    </div>
    <div class="error">
      <form novalidate>
        <p>
          <label for="message">
                    <span>Beskjed:</span>
                    <input type="text" id="message" name="message" required minlength="10">
                    <span class="error" aria-live="polite"></span>
                  </label>
        </p>
    </div>
    <form>
      <p>
        <label for="personvern">
                      <div class="personvern">
                      <span>Personvern:</span>
                      <br>
                      <input type="checkbox" id="personvern" name="personvern" required>
                      <span>Jeg har lest og godkjent <a href="https://demo2108.mobilpluss.no/ac/personvern">Personvernserklæringen</a></span>
                      <span class="error" aria-live="polite"></span>
                    </div>
                    </label>
      </p>

      <button>Send</button>
    </form>
  </div>
  <script src="kontakt.js"></script>

</body>

</html>

Thank you!

Answer №1

One method I would utilize is by incorporating custom attributes for specific elements in the application.

CSS fully embraces attribute selectors. By assigning a particular attribute, such as data-validation-error=true, to the div element, you can then style it accordingly in your CSS.

div[data-validation-error="true"] {
   /* red */
}

div[data-validation-error="ok"] {
  display: none; /* hidden */
}

In JavaScript, you can manipulate the desired div using the setAttribute function.

It's important to note that I opted for the data- prefix, which serves as the standardized HTML attribute prefix for user or application-defined attributes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to creating a unique React component for displaying a single popup upon clicking with the ability to pass props to it

As someone who is still learning React, I decided to challenge myself by creating a Jeopardy game using this framework. My current idea is to have a popup appear when a player clicks on a box on the Jeopardy board, displaying the clue associated with that ...

Is it possible to dynamically close the parent modal based on input from the child component?

As I follow a tutorial, I am working on importing the stripe function from two js files. The goal is to display my stripe payment in a modal. However, I am unsure how to close the modal once I receive a successful payment message in the child. Below are s ...

Tips for ending a page prematurely

I am currently facing an issue with hosting images on my webpage where the bottom of the images are uneven, creating a messy look at the bottom of the page. https://i.sstatic.net/N3XvJ.png Normally I would attempt to align them in a perfect square layout ...

Quantities with decimal points and units can be either negative or positive

I need a specialized input field that only accepts negative or positive values with decimals, followed by predefined units stored in an array. Examples of accepted values include: var inputValue = "150px"; <---- This could be anything (from the input) ...

What is the best way to access a promise's value in global scope within a reactjs application?

Currently tackling user authentication using web tokens in react. My approach involves utilizing the fetch() method to send a POST request to my backend, facilitating CORS. The issue arises when attempting to employ the setToken() hook within the .then() b ...

Make sure to include the "active" class in the pager once the slider begins

After coming across this fiddle, I noticed that it closely resembles the task I am working on. However, there is one issue - currently, only the first item has an active class when the slider autostarts. The next or previous items do not receive the acti ...

chosen problem concerning jquery

My objective is to transfer li elements from one container to another container when the user clicks on the li span. I have a choices container and a choices display, so when a user clicks on the li span with the id of "add" in the first container, the r ...

How can I adjust the height of the carousel slider to fit the course section perfectly?

I am currently working on a new website that includes a carousel slider in one of its sections. I am trying to figure out how to make the slider fit within that section while still maintaining responsiveness. Any suggestions on how to achieve this? I am u ...

Guide on accessing an array within a JSON object?

I have the following JSON object: [ { "comments": [ { "created_at": "2011-02-09T14:42:42-08:00", "thumb": "xxxxxxx", "level" ...

Bringing in data using .json files in a react native environment with Redux

I have developed a fitness app and I am utilizing Redux to store all the sets and workouts. Currently, I have manually entered all the exercises into Redux data for testing purposes. However, I now have all the exercises stored in a .json file and I want t ...

Guide on updating location and reloading page in AngularJS

I have a special function: $scope.insert = function(){ var info = { 'username' : $scope.username, 'password' : $scope.password, 'full_name' : $scope.full_name } $http({ method: &ap ...

directive ng-click not responding

drawer-card.html (template) <div class="drawer-card-wrapper"> <div class="drawer-card-icon" ngClick="dcCtrl.toggle()"> <i class="icon--{{ icon }}"/> </div> <div class="{{'drawer-card ' + (classesToAdd || '&apo ...

swap out a JavaScript function for a fresh function

In our ordering system, there is a hidden function that I cannot access. Interestingly, this function contains a spelling error which causes a grammar issue to appear in a popup when a user interacts with it. Is there any way for me to either modify the t ...

Validating Age Using jQuery UI Datepicker

Creating a dating platform for users over the age of 18, I am utilizing jQuery UI datepicker. To ensure only individuals above the age of 18 can register, I need the YEAR section to display 18 years earlier (1997) instead of the current year (2016). This w ...

Enhance the functionality of NodeJS core applications

I recently attempted to modify some custom functions in the FS module of NodeJS, which is an integral part of NodeJS' core modules. The specific file I targeted was fs.js, located in /usr/lib/nodejs. However, despite making changes to the code, I noti ...

An object-c alternative to encodeURIComponent

Having difficulty finding information on this through a search engine. Is there a similar method in Objective-C for encoding URI components? http://www.w3schools.com/jsref/jsref_encodeuricomponent.asp This is a common task, but I am unable to locate any ...

Editing the object retrieved from JSON is not possible once it has been fetched

Project. Input text in the field and it appears on the shirt. When you click "see back," there is an issue where new text overlaps old text. Clicking on "see front" allows you to enter new text, with the previous text saved underneath. Question: How can ...

It is impossible for me to invoke a method within a function

I am new to working with typescript and I have encountered an issue while trying to call the drawMarker() method from locateMe(). The problem seems to be arising because I am calling drawMarker from inside the .on('locationfound', function(e: any ...

Turn off slider trace animation?

Check out the slider component in MUI here: https://mui.com/material-ui/react-slider/ I'm currently exploring how to disable the animation on the nub so it moves instantly to the new position. Any advice on how to achieve this? ...

Issue with bidirectional data binding in Angular 2 on input element not functioning as expected

Looking at the code snippet below, I have noticed that even though the textchange function is called when the input value changes, the text property of the InputMaskComponent remains constant. I am not able to identify the issue in my code. InputMaskCompo ...