javascripteventsthisfocusoutfocusin

How to get focusin for all textbox? using javascript event not using jquery


Hello Guys, I need help a little bit. Can anyone help me, how to use this keyword in my case?

<form>
    <div class="form-group">
        <label for="txtFirstName">Your name</label>
        <input id="txtFirstName" name="txtFirstName" type="text" autocomplete="off" class="inputBox" />
    </div>              
    <div class="form-group">
        <label for="txtEmail">Email address</label>
        <input id="txtEmail" name="txtEmail" type="email" autocomplete="off" class="inputBox" />
    </div>
    <div class="form-group">                            
        <select id="drpPosition" name="drpPosition">
            <option>I would describe my user type as </option>
            <option>Web developer </option>
            <option>Web designer </option>
        </select>
    </div>
    <div class="form-group">
        <label for="txtPassword">Password</label>
        <input id="txtPassword" type="password" class="cool" autocomplete="off" class="inputBox" />
        <small>Minimum 8 characters</small>
    </div>       
    <div class="form-group">
        <input type="submit" name="btnSubmit" id="btnSubmit" value="Next" />
    </div>
</form>

This is my JavaScript Code:

var inputFirstName = document.querySelector('.inputBox');
console.log(inputFirstName);
this.addEventListener('focusin', inputAddClassFunc);
this.addEventListener('focusout', inputRemoveClassFunc);

function inputAddClassFunc(event){ 
    console.log(this);     
    this.previousElementSibling.classList.add('active');    
}
function inputRemoveClassFunc(event){    
    var hasValue = this.value;    
    if(!hasValue) {
        this.previousElementSibling.classList.remove('active');
    }    
}

When I focusin into the textbox, active class will be added to it's sibling's lable And in my case, It only works in first textbox but not for all textbox. How can I use "this" to works for all textbox?


Solution

  • I'd use event delegation instead - add focusin and focusout listeners to the form, and when the event fires, if the target of the event is one of the .inputBoxes, carry out the logic to change the class of the event.target.previousElementSibling:

    const form = document.querySelector('form');
    form.addEventListener('focusin', inputAddClassFunc);
    form.addEventListener('focusout', inputRemoveClassFunc);
    
    function inputAddClassFunc(event) {
      if (event.target.matches('.inputBox')) {
        event.target.previousElementSibling.classList.add('active');
      }
    }
    
    function inputRemoveClassFunc(event) {
      if (event.target.matches('.inputBox')) {
        var hasValue = event.target.value;
        if (!hasValue) {
          event.target.previousElementSibling.classList.remove('active');
        }
      }
    }
    .active {
      background-color: yellow;
    }
    <form>
      <div class="form-group">
        <label for="txtFirstName">Your name</label>
        <input id="txtFirstName" name="txtFirstName" type="text" autocomplete="off" class="inputBox" />
      </div>
      <div class="form-group">
        <label for="txtEmail">Email address</label>
        <input id="txtEmail" name="txtEmail" type="email" autocomplete="off" class="inputBox" />
      </div>
      <div class="form-group">
        <select id="drpPosition" name="drpPosition">
          <option>I would describe my user type as </option>
          <option>Web developer </option>
          <option>Web designer </option>
        </select>
      </div>
      <div class="form-group">
        <label for="txtPassword">Password</label>
        <input id="txtPassword" type="password" autocomplete="off" class="inputBox" />
        <small>Minimum 8 characters</small>
      </div>
      <div class="form-group">
        <input type="submit" name="btnSubmit" id="btnSubmit" value="Next" />
      </div>
    </form>

    Also note that if you want the txtPassword element to have the inputBox class, you should change

    <input id="txtPassword" type="password" class="cool" autocomplete="off" class="inputBox" />
    

    to

    <input id="txtPassword" type="password" autocomplete="off" class="inputBox" />
    

    (remove the duplicate cool attribute)