2
votes

I'm dying to solve my problem with autogenerated input in a span. I'm using the Wordpress plugin Contact Form 7 on my website and I want so animate the label while the user in using the input field.

When the input-field is on focus or something is typed in it, the class active should appear in the div with the class "grid-3".

I tried to get the javascript myself but it doesnt works:

$('.wpcf7-form-control-wrap').each(function() {
  //console.log($(this));
  $(this).on('focus', function() {
    $(this).parent().parent().addClass('active');
  });

  $(this).on('blur', function() {
    if ($(this).val().length == 0) {
      $(this).parent().parent().removeClass('active');
    }
  });

  if ($(this).val() != '') $(this).parent('.grid-3').addClass('active');

});

The HTML:

<div class="grid-3">
  <label for="schenkel2">Schenkel 2 in mm</label>
  <span class="wpcf7-form-control-wrap schenkel2">
    <input type="text" name="schenkel2" value="" size="40" class="wpcf7-form-control wpcf7-text" id="schenkel2" aria-invalid="false">
  </span>
</div>
2
why do you need to add a class on focus? is it to change styling? if so, the :focus pseudo-class is made for just such an occasion - Jaromanda X

2 Answers

1
votes

Your logic looks fine, although instead walking up two parent nodes, I'd suggest crawling up the DOM tree until you find the class you're looking for. That way it is less likely to break with changes to the DOM. In vanilla javascript something like the following should do the job. Note that it uses classList which you may need to polyfill for older versions of IE.

/**
* Walk up DOM tree to get parent element with the matching class
* @param {Element} Element to search from
* @param {string} The class name to identify target parent
* @return {Element} The parent element with targetClass or null of we reach the top of the DOM tree
**/
function getTargetParent(elem, targetClass) {
    var currElem = elem;
    while(
  	  currElem
  	  && !currElem.classList.contains(targetClass)
    ) {
    	currElem = currElem.parentNode;
    }
    return currElem;
}

/**
* Add a focus event listener to an element to add "focus" class on the parent identified by targetClass
**/
function addFocusListener(elem, targetClass) {
  var targetParent = getTargetParent(elem, targetClass);
  if(targetParent) {
		elem.addEventListener('focus', function() {
	    targetParent.classList.add('focus');
    });
    elem.addEventListener('blur', function() {
    	targetParent.classList.remove('focus');
    });
  }
}

var inputs = document.getElementsByClassName('wpcf7-form-control');
for(var i = 0; i < inputs.length; i++) {
	addFocusListener(inputs[i], 'grid-3');
}
.focus {
  color: red;
}
<div class="grid-3">
  <label for="schenkel2">Schenkel 2 in mm</label>
  <span class="wpcf7-form-control-wrap schenkel2">
    <input type="text" name="schenkel2" value="" size="40" class="wpcf7-form-control wpcf7-text" id="schenkel2" aria-invalid="false">
  </span>
</div>
0
votes

Do you use CSS for this ? I think u can achieve it easily with CSS3

 <div class="grid-3">
 <label for="schenkel2">Schenkel 2 in mm</label>
 <span class="wpcf7-form-control-wrap schenkel2">
<input type="text" name="schenkel2" value="" size="40" class="wpcf7-form-control wpcf7-text inputHover" id="schenkel2" aria-invalid="false">

input[type=text], textarea {
 -webkit-transition: all 0.30s ease-in-out;
 -moz-transition: all 0.30s ease-in-out;
 -ms-transition: all 0.30s ease-in-out;
 -o-transition: all 0.30s ease-in-out;
  outline: none;
  padding: 3px 0px 3px 3px;
  margin: 5px 1px 3px 0px;
  border: 1px solid #DDDDDD;
}

#inputHover:focus {
  box-shadow: 0 0 5px #EC8937;
  padding: 3px 0px 3px 3px;
  margin: 5px 1px 3px 0px;
  border: 1px solid #EC8937;
}

above first one is to add the default styles for a text area and second CSS is to get the on focus effect add the inputHover class into your Input tag and check