Валидация формы до отправки, отправка (ajax/php), закрытие модального окна, отображение toast

Почему одновременно не работает валидация формы и скрытие модального окна с показом toast после отправки?

Либо (строка event.preventDefault(); в блоке ajax закомментирована):

  • форма валидируется (при нажатии на Отправить, без заполненных полей, требует заполнение поле)
  • отправляется (срабатывает send.php)
  • закрывается
  • НЕ отображается toast

Либо (строка event.preventDefault(); в блоке ajax НЕ закомментирована):

  • форма НЕ валидируется (при нажатии на Отправить, без заполненных полей, ничего не происходит)
  • отправляется (срабатывает send.php)
  • НЕ закрывается
  • отображается toast

Как реализовать и валидацию формы и скрытие модального окна с последующим показом toast?

Кнопка (упрощён):

<div class="container py-3">
    <div class="row">
        <div class="col-sm-3">
            <div class="card mb-3 rounded-3 shadow-sm">
                <div class="card-body" style="background: #6C757E;">
                    <div class="d-flex justify-content-between align-items-center">
                        <div class="btn-group">
                            <button type="button" class="btn btn-sm btn-outline-light" data-bs-toggle="modal" data-bs-target="#bid"><i class="far fa-envelope"></i></button>
                        </div>
                    </div>
                </div>
            </div>
        </div>

Модальное окно (форма):

<div class="modal fade" id="bid" tabindex="-1" aria-labelledby="bid" aria-hidden="true">
    <div class="modal-dialog modal-sm modal-dialog-centered modal-dialog-scrollable">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="bid">Modal</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <form class="row g-2 needs-validation" id="fbid" novalidate>
                    <div class="input-group mb-2">
                        <span class="input-group-text" id="basic-addon1">@</span>
                        <input type="text" class="form-control" name='username' id="username" placeholder="username" aria-label="username" aria-describedby="basic-addon1" required>
                    </div>
                    <div class="mb-2">
                        <textarea class="form-control" name='task' id="task" placeholder="task" aria-label="task" rows="2" required></textarea>
                    </div>
                    <button class="btn btn-success btn-sm" id="submit" value="validate">send</button>
                </form>
            </div>
        </div>
    </div>
</div>

Валидация формы:

<script type="text/javascript">
    // https://getbootstrap.com/docs/5.1/forms/validation/
    (function () {'use strict'
        var forms = document.querySelectorAll('.needs-validation')
        Array.prototype.slice.call(forms)
        .forEach(function (form) {
            form.addEventListener('submit', function (event) {
                if (!form.checkValidity()) {
                    event.preventDefault()
                    event.stopPropagation()}
                    form.classList.add('was-validated')}, false)})})
    ()
</script>

Ajax:

<script type="text/javascript">
    $(document).ready(function() {
        $("#submit").click(
            function(){
                $.ajax({
                    url: "php/send.php",
                    type: "POST",
                    dataType: "html",
                    cache:false,
                    data: $("#fbid").serialize(),
                    success: function(response) {
                        console.log($.parseJSON(response).status);
                        if($.parseJSON(response).status == 'success'){
                            $('.toast').toast('show');
                        }
                    }
                });
                // event.preventDefault();
                // если закомментировано - форма валидируется (при нажатии на Отправить требует заполнение поле), отправляется (срабатывает send.php), закрывается, но НЕ отображается toast ($('.toast').toast('show');)
                // если НЕ закомментировано - форма НЕ валидируется (при нажатии на Отправить ничего не происходит), отправляется (срабатывает send.php), НЕ закрывается, отображается toast ($('.toast').toast('show');)
                // необходимо: валидация, отправка, закрытие, toast
            }
            );
    });
</script>

toast:

<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11; width: 300px;">
    <div class="toast align-items-center text-white bg-success border-0" role="alert" aria-live="polite" aria-atomic="true" data-bs-delay="2000">
        <div class="toast-header">
            <strong class="me-auto">title</strong>
            <small>now</small>
            <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Закрыть"></button>
        </div>
        <div class="toast-body">success</div>
    </div>
</div>

PHP:

<?php
$config = require __DIR__.'/conf_send.php';
if($_POST['username'] != '' && $_POST["task"] != '') {
    $data = array(
        'chat_id' => $config['chat_id'],
        'text' => "@".$_POST['username']."\n".$_POST['task'],
        'parse_mode' => 'html',
        'disable_web_page_preview' => true
    );
      $ch = curl_init('https://api.telegram.org/bot'.$config['token'].'/sendMessage');
      curl_setopt_array($ch, array(
          CURLOPT_HEADER => 0,
          CURLOPT_RETURNTRANSFER => 1,
          CURLOPT_POST => 1,
          CURLOPT_POSTFIELDS => $data
      ));
      curl_exec($ch);
      curl_close($ch);
      echo json_encode(array('status' => 'success'));
}
else {
  echo json_encode(array('status' => 'error'));
}
?>

Ответы (0 шт):