0

It's been some years since I have had to do DOM manipulation with CSS and vanilla JavaScript.

I have an input element some default css that is being added to its wrapping div and not the input element itself like so:

<div class="field animated-label text required">
 <label class="control-label" for="answer">Answer</label>
 <input class="form-control" />
</div>

So the default css for this input element is dictated by this selector:

.rds-form .animated-label {
  border: 2px solid #ccc;
  border-radius: 2px;
  color: #767676
  display: block;
  min-height: 40px;
  position: relative;
}

However when the user clicks out of the input element not having typed anything in, this selector gets appended on to give a red error border around the input element:

.rds-form .field-group.error, .rds-form
.field.text.error, .rds-form
.field.select.error, .rds-form .field.textarea.error {
  border: 2px solid #cc2233;
  position: relative;
}

How would this be handled in JavaScript? I am assuming this is handled by some JavaScript logic.

halfer
  • 19,824
  • 17
  • 99
  • 186
Daniel
  • 14,004
  • 16
  • 96
  • 156
  • 5
    Does this answer your question? [Vanilla JavaScript adding classes to elements](https://stackoverflow.com/questions/51826516/vanilla-javascript-adding-classes-to-elements) – kmoser Aug 23 '20 at 17:22
  • If you are seeing that the CSS rule is not getting triggered (upon adding/removing classes) have a look at this: https://stackoverflow.com/questions/22093141/adding-class-via-js-wont-trigger-css-animation – Rahul Bharadwaj Aug 23 '20 at 17:24

1 Answers1

1

Add two handlers to the <input> field:

// When the input field has focus, remove the 'error' class from .animated-label:
document.querySelector('input').addEventListener('focus', function(e) {
    document.querySelector('.animated-label').classList.remove('error');
});

// When the input field loses focus, determine whether to add or remove the 'error' class:
document.querySelector('input').addEventListener('blur', function(e) {
    if (e.target.value.match(/^\s*$/)) { // Input is empty
        document.querySelector('.animated-label').classList.add('error');
    } else {
        document.querySelector('.animated-label').classList.remove('error');
    }
});
kmoser
  • 8,780
  • 3
  • 24
  • 40
  • what exactly is the regex of `/^\s*$/` doing? – Daniel Aug 23 '20 at 18:59
  • It matches a string that is either empty (`''`) or contains just whitespace: `^` means beginning of string; `\s*` means zero or more whitespace chars (space, tab, or newline); `$` means end of string. https://stackoverflow.com/a/19121435/378779 – kmoser Aug 23 '20 at 21:53