Search code examples
htmlcssvue.jscss-animationsbootstrap-vue

How to check on page load if input and select boxes are empty with Javascript


I am using Vue.js to create a form. Currently my HTML looks like this:

<div class="form-group m-0" role="group">
    <label class="d-block form-label" for="code_part3">Last Three</label>
    <div>
        <input class="form-input form-control is-invalid hasError" type="text"><!----><!----><!---->
    </div>
</div>

When a user focuses on an input, or changes a select box, a class (.focused) is added to the main parent (.form-group). This animates the label to sit on top of the input/select box. And on blur a method is ran to check if the input value is to empty.

resetAnimateInputLabel() {
  var target = event.currentTarget;
  var inputValue = event.currentTarget.value;
  var parentOfParent = target.parentElement.parentElement;
  if (inputValue == "") {
    //remove focused class to Parent of Parent to animate
    parentOfParent.classList.remove("focused");
  }
}

However I am using localStorage which will prepopulate the input fields when a user returns to the page. This causes an issue where the label is restored back to its original position (within the input itself) and both text clash.

What is the best way to solve this, so that on page load, if an input or select box is empty, for the label to remain animated?

I have tried the following:

Created a new method:

checkInputEmpty() {
  var inputs = document.getElementsByClassName("form-input");

  for (var i = 0; i < inputs.length; i++) {
    if (inputs[i].value == "") {
      inputs[i].parentElement.parentElement.classList.remove("focused");
    } else {
      inputs[i].parentElement.parentElement.classList.add("focused");
    }
  }
}

and called it here:

mounted() {

 this.checkInputEmpty();

 if (localStorage.email !== "undefined") {
   this.form.email = localStorage.email;
 }
}

Solution

  • You could do two things differently to handle this in a simple and elegant way:

    First - Checking input values:

    Step 1: Having data property for storing the input value

    data () {
      return {
        inputValue: '',
      }
    }
    

    Step 2: Binding your input to that property

    <input v-model="inputValue" />
    

    Step 3: Investigating the data property and handling both cases as needed (wherever needed)

    if (this.inputValue) {
      // here, the input value is non-empty ("", null, undefined would evaluate to false)
    } else {
      // here, the input value is empty
    }
    

    Second - Class toggling

    Step 1: You don't have to set and remove classes in this complicated way:

    inputs[i].parentElement.parentElement.classList.add("focused");
    

    Instead you can, again, create a data property for storing toggled state of the focused class:

    data () {
      return {
        inputValue: '',
        formFocused: false
      }
    }
    

    Step 2: Dynamically assign the class to your element like this:

    <div
      class="form-group m-0" role="group"
      :class="{ 'focused' : formFocused }"
    >
     ...
    </div>
    

    Step 3: And handle the property as needed, in your case probably like this:

    if (this.inputValue) {
      this.formFocused = false;
    } else {
      this.formFocused = true;
    }
    

    Which is the same as:

    this.formFocused = !this.inputValue;
    

    For more info:

    https://v2.vuejs.org/v2/guide/forms.html#v-model-with-Components

    https://v2.vuejs.org/v2/guide/class-and-style.html