0xNicko
0xNicko

Reputation: 63

event.target.setCustomValidity is not a function at HTMLSelectElement in Javascript

I have a form with a client side validation with JS.

When the user clicks or types in a field, a message will be displayed below that field. This works well with input type text and select fields. But not with the multi-select field. Sometimes the error message appears and sometimes it doesn't. I'm not sure what approach I have to do to solve it: /

This is more or less my code

var y = document.querySelectorAll(".um-form-field:not(.not-required)");//I get all the inputs except the ones that are not needed


var i;
 for (i = 0; i < y.length; i++) {
    y[i].addEventListener('keyup', errorMsj, false);
    y[i].addEventListener('click', errorMsj, false);
    y[i].addEventListener('invalid', errorMsj, false);  
 };

function errorMsj (event) {
 if (event.target.value.length == 0) {
  event.target.style.background = "#eb91ae";
  event.target.setCustomValidity("error");
  divError.style.display = "block";
  divError.innerHTML  = "You must complete this field"
  event.target.parentElement.appendChild(divError);
 } else {
  event.target.style.background = "#9deb91";
  event.target.setCustomValidity("");
  divError.style.display = "none";
  }
}

//create a div for error message
var divError = document.createElement("DIV");
divError.style.display = "none";
divError.className = "um-field-error";
<input class="um-form-field" type="text" name="DEMO" id="DEMO" value="" required="">  <!-- input text works great. -->

<select name="DEMO2" id="DEMO2" class="um-form-field" required=""><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>  <!-- input select works great. -->

<select multiple="multiple" name="DEMO3" id="DEMO3" class="um-form-field" required=""><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>  <!-- input multiselect does not work well. -->

This is the error i get in my console: Uncaught TypeError: event.target.setCustomValidity is not a function at HTMLSelectElement.errorMsj

Upvotes: 1

Views: 1827

Answers (2)

0xNicko
0xNicko

Reputation: 63

EDITED 12/01: This is my solution. Thanks to Rúnar Berg

var y = document.querySelectorAll(".um-form-field:not(.not-required)");//I get all the inputs except the ones that are not needed


var i;
 for (i = 0; i < y.length; i++) {
    if (!y[i].classList.contains("um-user-keyword_0")){
        y[i].addEventListener('keyup', errorMsj, false);
        y[i].addEventListener('click', errorMsj, false);
        y[i].addEventListener('invalid', errorMsj, false);
    } else {
        y[i].addEventListener('change', errorMsj, false);
        y[i].addEventListener('input', errorMsj, false);
        y[i].addEventListener('invalid', errorMsj, false);
        };  
 };

function errorMsj (event) {
 if (event.target.value.length == 0) {
  event.target.style.background = "#eb91ae";
  event.target.setCustomValidity("error");
  divError.style.display = "block";
  divError.innerHTML  = "You must complete this field"
  event.target.parentElement.appendChild(divError);
 } else {
  event.target.style.background = "#9deb91";
  event.target.setCustomValidity("");
  divError.style.display = "none";
  }
}

//create a div for error message
var divError = document.createElement("DIV");
divError.style.display = "none";
divError.className = "um-field-error";
<input class="um-form-field" type="text" name="DEMO" id="DEMO" value="" required="">  <!-- input text works great. -->

<select name="DEMO2" id="DEMO2" class="um-form-field" required=""><option value=""></option><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>  <!-- input select works great. -->

<select multiple="multiple" name="DEMO3" id="DEMO3" class="um-form-field um-user-keyword_0" required=""><option value=""></option><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>  <!-- input multiselect does not work well. -->

Upvotes: 0

R&#250;nar Berg
R&#250;nar Berg

Reputation: 4832

The problem is that you are targeting the <option> elements with your click handlers which do not implement the validation API. What you need to do instead is to listen for the change and input events.

y[i].addEventListener('change', errorMsj, false);
y[i].addEventListener('input', errorMsj, false);

These will be triggered on the parent <select> elements which do implement the validation API.

Here is a working example:

var y = document.querySelectorAll(".um-form-field:not(.not-required)");

var i;
 for (i = 0; i < y.length; i++) {
    // NOTE! Target `change` and `input` events
    y[i].addEventListener('change', errorMsj, false);
    y[i].addEventListener('input', errorMsj, false);
    y[i].addEventListener('invalid', errorMsj, false);  
 };

function errorMsj (event) {
 if (event.target.value.length == 0) {
  event.target.style.background = "#eb91ae";
  event.target.setCustomValidity("error");
  divError.style.display = "block";
  divError.innerHTML  = "You must complete this field"
  event.target.parentElement.appendChild(divError);
 } else {
  event.target.style.background = "#9deb91";
  event.target.setCustomValidity("");
  divError.style.display = "none";
  }
}

//create a div for error message
var divError = document.createElement("DIV");
divError.style.display = "none";
divError.className = "um-field-error";
<input class="um-form-field" type="text" name="DEMO" id="DEMO" value="" required="">

<select name="DEMO2" id="DEMO2" class="um-form-field" required=""><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>

<select multiple="multiple" name="DEMO3" id="DEMO3" class="um-form-field" required=""><option value="one">one</option><option value="two">two</option><option value="three">three</option></select>

Upvotes: 1

Related Questions