Trying to change background color on same valued inputs

Viewed 92

I've been trying to change the input on a same valued inputs. The input ids are (Input${i} (Input0 , Input1 and etc., iterating them with loop), I have a button which evokes the function,

The best I got so far is this:

function fnValidate(current, value){
  var hasDuplicates = false

  for(var i =0; i<5 ; i++) {
    if(i !== current && document.getElementById(`Input` + i).value == value) {
     hasDuplicates = true
     break;
    }
   }
 

  document.getElementById(`Input${i}`).style.backgroundColor = hasDuplicates ? '#F00' : '#FFF'
}


fnValidate()
3 Answers

Few things to correct with your code:

  1. Your are calling the function without any arguments, which you haven't specified as optional
  2. You are breaking the loop as soon as your condition is satisfied, hence the color changing line is never executed.

Run the following snippet:

function fnValidate(current, value){
  var hasDuplicates = false

  for(var i =0; i<5 ; i++) {
  
    if(i !== +current && document.getElementById(`Input` + i).value == value) {
     hasDuplicates = true
     document.getElementById(`Input${i}`).style.backgroundColor = hasDuplicates ? '#F00' : '#FFF'
     alert();
     break;
    }
   }
 

  
}


document.ready = fnValidate('1',1)
<input type="text" id="Input0" value="1">
<input type="text" id="Input1">
<input type="text" id="Input2">
<input type="text" id="Input3">
<input type="text" id="Input4">
<input type="text" id="Input5">

You need to pass the parameters right in the event listeners and you can directly change the color as follows:

function fnValidate(current, value) {
  for(var i = 0; i < 5 ; i++) {
    const currentValue = document.getElementById(`Input` + i).value;
    if(currentValue && i !== current && currentValue == value) {
      document.getElementById(`Input${i}`).style.backgroundColor = '#F00';
      break;
    }
  }
}

[...document.querySelectorAll(".myInp")].forEach((inp, index) =>
  inp.addEventListener("input", () => fnValidate(index, inp.value))
);
<input id="Input0" class="myInp"/>
<input id="Input1" class="myInp"/>
<input id="Input2" class="myInp"/>
<input id="Input3" class="myInp"/>
<input id="Input4" class="myInp"/>

I think you probably want to learn to do something like:

//<![CDATA[
/* js/external.js */
let  doc, htm, bod, nav, M, I, mobile, S, Q, hC, aC, rC, tC; // for use on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
  var w = within || doc;
  return w.querySelector(selector);
}
Q = (selector, within)=>{
  var w = within || doc;
  return w.querySelectorAll(selector);
}
hC = function(node, className){
  return node.classList.contains(className);
}
aC = function(){
  const a = [...arguments];
  a.shift().classList.add(...a);
  return aC;
}
rC = function(){
  const a = [...arguments];
  a.shift().classList.remove(...a);
  return rC;
}
tC = function(){
  const a = [...arguments];
  a.shift().classList.toggle(...a);
  return tC;
}
// you could put the below on a separate script in a load Event, if you want
function aaIndex(value, arrayOfArrays){
  for(let i=0,v,l=arrayOfArrays.length; i<l; i++){
    v = arrayOfArrays[i].indexOf(value);
    if(v !== -1){
      return i;
    }
  }
  return -1;
}
function dups(collection){
  const a = [];
  for(let i=0,v,x,l=collection.length; i<l; i++){
    v = collection[i].value;
    for(let n=0; n<l; n++){
      if(v !== '' && i !== n && collection[n].value === v){
        x = aaIndex(i, a);
        if(x === -1){
          a.push([i, n]);
        }
        else{
          a[x].push(n);
        }
      }
    }
  }
  return a;
}
const q = Q('.test');
for(let n of q){
  n.onfocus = ()=>{
    aC(n, 'focus');
  }
  n.onblur = ()=>{
    rC(n, 'focus');
  }
  n.onkeyup =()=>{
    let d = dups(q), m = 0;
    for(let v of q){
      rC(v, 'match1', 'match2', 'match3');
    }
    for(let a of d){
      m++;
      for(let i of a){
        aC(q[i], 'match'+m);
      }
    }
  }
}
}); // end load
/* css/external.css */
*{
  box-sizing:border-box; font:22px Tahoma, Geneva, sans-serif; color:#000; padding:0; margin:0; overflow:hidden;
}
html,body,.main{
  width:100%; height:100%;
}
.main{
  background:#333; overflow-y:auto;
}
.test{
  width:calc(100% - 10px); padding:3px 5px; margin:5px; border:2px solid #ccc; border-radius:2px;
}
.focus{
  border-color:#cc0;
}
.match1{
  border-color:#f70;
}
.match2{
  border-color:#c0c;
}
.match3{
  border-color:#c00;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  <head>
    <meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
    <title>Title Here</title>
    <link type='text/css' rel='stylesheet' href='css/external.css' />
    <script src='js/external.js'></script>
  </head>
<body>
  <div class='main'>
    <input class='test' value='' />
    <input class='test' value='' />
    <input class='test' value='' />
    <input class='test' value='' />
    <input class='test' value='' />
    <input class='test' value='' />
    <input class='test' value='' />
  </div>
</body>
</html>

You'll notice this design supports more than one match.

Related