Skip to content

Disable or enable only the current button

With a PHP for each cycle, I’m bringing articles from the database. In those articles, we have a comment section with a form. I want to check with jQuery if there is something written on the input before the comment is sent.

As the articles are being brought with a PHP cycle, I want to check only the article in which it is being written a comment, but jQuery checks all the articles and only enables or disables the first or top result being brought from the database. I want jQuery to check only on the article with a written comment.

Here’s what I’m doing:

$(document).ready(function() {
  $(".comment-submit").attr("disabled", true);

  $("#group-post-comment-input").keyup(function() {
    if ($(this).val().length != 0) {
      $(".comment-submit").attr("disabled", false);
    } else {
      $(".comment-submit").attr("disabled", true);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" id="group-post-comment-input">

  <button class="comment-submit">
        Comment
    </button>
</form>

<br>

<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" id="group-post-comment-input">

  <button class="comment-submit">
        Comment
    </button>
</form>

<br>

<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" id="group-post-comment-input">

  <button class="comment-submit">
        Comment
    </button>
</form>

As you can see on the snippet above, the buttons only get enabled when text is written on the first input only. I want the buttons to get enabled when text is written on their dependent input. If input 2 has text on it, enable button 2, and so on and so on.

How can I do that?

Answer

Since IDs must be unique to the DOM tree, you might consider using a class instead.

$(function() {
  $(".group-post-comment-input").on('keyup', function() {
    let $button = $(this).next('.comment-submit');
    let disabled = !this.value;
    $button.prop('disabled', disabled);
  });
});
form {
  margin: 0 0 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" class="group-post-comment-input">
  <button class="comment-submit" disabled>Comment</button>
</form>

<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" class="group-post-comment-input">
  <button class="comment-submit" disabled>Comment</button>
</form>

<form action="comment.php" method="POST">
  <input autocomplete="off" type="text" placeholder="Add a comment" class="group-post-comment-input">
  <button class="comment-submit" disabled>Comment</button>
</form>

In my demonstration, I use jQuery’s next() to traverse from the input on which the “keyup” event is fired to its associated button.

.next( [selector ] )
Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.

Another method is to traverse up to the form element with closest() and back down to the button with find(). This might be useful if you expect your HTML structure to change in a way that could break the next() traversal.

let $button = $(this).closest('form').find('.comment-submit');

I also recommend using prop() instead of attr() to enable and disable inputs.