skip to Main Content

I have made a blogging application in Laravel 8. I am currently working on adding comment replies via jQuery (v3.5.0) AJAX.

In comment-form.blade.php I have:

<div class="form-wrapper">
  <div class="alert-box-ajax alert-box alert-box--success">
    Your comment is pending
  </div>

  <div class="alert-box-ajax alert-box alert-box--error">
    Failed to add comment!
  </div>

  <form class="commentForm" method="post" action="{{ route('comment.submit') }}" autocomplete="off">
    @csrf
      <fieldset>
        <input type="hidden" name="article_id" value="{{ isset($article->id) ? $article->id : $article_id }}">
        <input type="hidden" name="parent_id" value="{{ $comment->id ?? '' }}">

        <div class="message form-field">
            <textarea name="msg" id="message" class="h-full-width" placeholder="Your Message" required></textarea>

            @error('msg')
            <p class="help-block text-danger">{{ $message }}</p>
            @enderror
        </div>
        <br>
        <input name="submit" id="submit" class="btn btn--primary btn-wide btn--large h-full-width" value="Add Comment" type="submit">
      </fieldset>
  </form>
</div>

The template above, of course, repeats for every comment, so that replies can be added to any of them.

Replies are submitted via jQuery Ajax:

$(".commentForm").each(function () {
    var form = $(this);
    form.validate({
        errorElement: "p",
        errorClass: "help-block text-danger",

        submitHandler: function (_form, event) {
            event.preventDefault();
            var $fields = form.find("textarea"),
                url = form.attr("action"),
                data = form.serialize();
            $.ajax({
                dataType: "json",
                type: "post",
                url: url,
                data: data,
                cache: false,
                success: function (response) {
                  if (response.status === 'success') {
                    form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
                        .slideDown(250)
                        .delay(2500)
                        .slideUp(250);
                  $fields.val("");
                  } else {
                    form.closest(".form-wrapper").find(".alert-box--error").slideDown(250).delay(2500).slideUp(250)
                        .slideDown(250)
                        .delay(2500)
                        .slideUp(250);
                  }
                },
                error: function (err) {    
                  console.log(err);
                },
            });
        },
    });
});

The problem

There is an option to load a maximum of 10 comemnts for each post initially, the rest being loaded on page scroll, via an Ajax call.

When this option is active, the script above fails to prevent the default behavior of the forms loaded via Ajax.

!Note: The issue is not the submit event, but its prevention.

Questions

  1. What causes this issue?
  2. What is the most reliable solution to the problem?

2

Answers


  1. That would work no matter how many forms for each comment as each form would belong to single comment.

    $(document).on("submit", ".commentForm", function (event) {
        event.preventDefault();
    
        var form = $(this);
        form.validate({
          errorElement: "p",
          errorClass: "help-block text-danger",
    
          submitHandler: function (_form, event) {
            event.preventDefault();
            var $fields = form.find("textarea"),
              url = form.attr("action"),
              data = form.serialize();
            $.ajax({
              dataType: "json",
              type: "post",
              url: url,
              data: data,
              cache: false,
              success: function (response) {
                if (response.status === 'success') {
                  form.closest(".form-wrapper").find(".alert-box--success").slideDown(250).delay(2500).slideUp(250)
                    .slideDown(250)
                    .delay(2500)
                    .slideUp(250);
                  $fields.val("");
                } else {
                  form.closest(".form-wrapper").find(".alert-box--error").slideDown(250).delay(2500).slideUp(250)
                    .slideDown(250)
                    .delay(2500)
                    .slideUp(250);
                }
              },
              error: function (err) {
                console.log(err);
              },
            });
          },
        });
      });
    
    
    Login or Signup to reply.
  2. You are using the validate function of the jQuery validate plugin incorrectly.

    You need to run it once after the form is loaded into the HTML, not on submit. validate sets up event handlers for you, so it needs to run in advance and not after the fact!

    Right now, you are setting up a submit handler after the submit already happened so it’s too late. That handler will therefore never be fired, and instead the current submit will be executed with default behavior.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search