Kyle Underhill
Kyle Underhill

Reputation: 109

How can I limit my selector to a specific element related to an input?

I want the character counting code to work on multiple inputs but I can't figure out how to implement an each function on my keyup so that the .char-count works on the closest .input

function checkTextAreaMaxLength(textBox, e) {
  var maxLength = parseInt($(textBox).data("length"));
  if (!checkSpecialKeys(e)) {
    if (textBox.value.length > maxLength - 1)
      textBox.value = textBox.value.substring(0, maxLength);
  }
  $(".char-count").html(maxLength - textBox.value.length);
  return true;
}
function checkSpecialKeys(e) {
  if (
    e.keyCode != 8 &&
    e.keyCode != 46 &&
    e.keyCode != 37 &&
    e.keyCode != 38 &&
    e.keyCode != 39 &&
    e.keyCode != 40
  )
    return false;
  else return true;
}

$(".input").on("keyup", function(event) {
  checkTextAreaMaxLength(this, event);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="item">
    <textarea class='input' rows='3' data-length=250 data-min-rows='3'></textarea>
    <h4><span class="char-count">250</span> chars remaining</h4>
</div>

<div class="item">
    <input class='input' data-length=120/>
    <h4><span class="char-count">120</span> chars remaining</h4>
</div>

Upvotes: 2

Views: 100

Answers (3)

Siddharth Pal
Siddharth Pal

Reputation: 1458

We can traverse to the changed input parent(s) with item as a selector and then find the char-count class in it.

$(textBox).parents(".item").find(".char-count"); // Here we are traversing from input to class="item" div(which is the parent of input) and then we are finding char-count respective to that and changing its html value.

function checkTextAreaMaxLength(textBox, e) {
  var maxLength = parseInt($(textBox).data("length"));
  if (!checkSpecialKeys(e)) {
    if (textBox.value.length > maxLength - 1)
      textBox.value = textBox.value.substring(0, maxLength);
  }
  $(textBox).parents(".item").find(".char-count").html(maxLength - textBox.value.length);
  return true;
}
function checkSpecialKeys(e) {
  if (
    e.keyCode != 8 &&
    e.keyCode != 46 &&
    e.keyCode != 37 &&
    e.keyCode != 38 &&
    e.keyCode != 39 &&
    e.keyCode != 40
  )
    return false;
  else return true;
}

$(".input").on("keyup", function(event) {
  checkTextAreaMaxLength(this, event);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
<textarea class='input' rows='3' data-length=250 data-min-rows='3'></textarea>
<h4><div><span class="char-count">250</span> chars remaining</h4>
</div></div>
<div class="item">
<input class='input' data-length=120></input>
<h4><span class="char-count">120</span> chars remaining</h4>
</div>

Upvotes: 2

isherwood
isherwood

Reputation: 61063

Just reduce your selector using DOM traversal. There are many ways to do this. Here's one approach using an ancestor element:

$(textBox).closest('.item').find('.char-count').html(maxLength - textBox.value.length);

Another would be to use a sibling selector:

$(textBox).siblings().find('.char-count').html(maxLength - textBox.value.length);

Or, more specifically, the next element selector:

$(textBox).next().find('.char-count').html(maxLength - textBox.value.length);

I like to be a little more specific with the ancestor selector in case the interior markup structure changes. parent() is fragile sometimes. If you were to add a wrapper around the input for layout purposes, for example (as in when using Bootstrap), parent() is no longer appropriate and your script breaks. I find it more durable to target the outermost element in your markup group. The same idea is true of siblings() and next(). It's better to leave some flexibility in your selector.

function checkTextAreaMaxLength(textBox, e) {
var maxLength = parseInt($(textBox).data("length"));

if (!checkSpecialKeys(e)) {
    if (textBox.value.length > maxLength - 1)
        textBox.value = textBox.value.substring(0, maxLength);
}

$(textBox).closest('.item').find('.char-count').html(maxLength - textBox.value.length);

return true;
}

function checkSpecialKeys(e) {
if (
    e.keyCode != 8 &&
    e.keyCode != 46 &&
    e.keyCode != 37 &&
    e.keyCode != 38 &&
    e.keyCode != 39 &&
    e.keyCode != 40
)
    return false;
else return true;
}

$(".input").on("keyup", function(event) {
checkTextAreaMaxLength(this, event);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
<textarea class='input' rows='3' data-length=250 data-min-rows='3'></textarea>
<h4><span class="char-count">250</span> chars remaining</h4>
</div>
<div class="item">
<input class='input' data-length=120></input>
<h4><span class="char-count">120</span> chars remaining</h4>
</div>

Upvotes: 2

Roy Bogado
Roy Bogado

Reputation: 4472

The key is here:

$(textBox).parent().find('span.char-count').html(maxLength - textBox.value.length);

from the edited element you should go parent() and find() the span.char-count from the div item.

function checkTextAreaMaxLength(textBox, e) {
  var maxLength = parseInt($(textBox).data("length"));
  if (!checkSpecialKeys(e)) {
    if (textBox.value.length > maxLength - 1)
      textBox.value = textBox.value.substring(0, maxLength);
  }
  $(textBox).parent().find('span.char-count').html(maxLength - textBox.value.length);
  return true;
}
function checkSpecialKeys(e) {
  if (
    e.keyCode != 8 &&
    e.keyCode != 46 &&
    e.keyCode != 37 &&
    e.keyCode != 38 &&
    e.keyCode != 39 &&
    e.keyCode != 40
  )
    return false;
  else return true;
}

$(".input").on("keyup", function(event) {
  checkTextAreaMaxLength(this, event);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
<textarea class='input' rows='3' data-length=250 data-min-rows='3'></textarea>
<h4><span class="char-count">250</span> chars remaining</h4>
</div>
<div class="item">
<input class='input' data-length=120></input>
<h4><span class="char-count">120</span> chars remaining</h4>
</div>

Upvotes: 2

Related Questions