Hiển thị các bài đăng có nhãn novalidate form. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn novalidate form. Hiển thị tất cả bài đăng

Thứ Tư, 24 tháng 12, 2025

Bắt lỗi JS khi submit mà chưa nhập dữ liệu

 ** Note: không có novalidate js sẽ không hiểu và hiện lỗi trình duyệt chứ không phải JS


novalidate


<form action="javascript:void(0)" method="post" id="dkthanhvien" enctype="multipart/form-data" autocomplete="off" novalidate>

<input type="text"  name="lastname"  required>

** JS
$(function () {

    const form = $('#dkthanhvien');
    const phoneInput = form.find('input[name="txt_phone1"]');

    /* ===============================
       CHỈ CHO NHẬP SỐ Ở Ô PHONE
    =============================== */
    phoneInput.on('keypress', function (e) {
        const charCode = e.which ? e.which : e.keyCode;
        if (charCode < 48 || charCode > 57) {
            e.preventDefault();
        }
    });

    phoneInput.on('input', function () {
        this.value = this.value.replace(/[^0-9]/g, '');
    });

    /* ===============================
       SUBMIT FORM
    =============================== */
    form.on('submit', function (e) {
        e.preventDefault();

        let isValid = true;

        /* ===== Reset lỗi ===== */
        form.find('.error-msg').remove();
        form.find('.error').removeClass('error');
        $('.error-field').remove();

        /* ===============================
           VALIDATE DROPDOWN CUSTOM
        =============================== */
        if ($('#value1').val().trim() === '') {
            isValid = false;
            $('.selectedBox').addClass('error');

            if (!$('#dropdown1 .error-msg').length) {
                $('#dropdown1').append(
                    '<div class="error-msg">Vui lòng chọn quốc tịch.</div>'
                );
            }
        }

        /* ===============================
           VALIDATE SELECT REQUIRED
        =============================== */
        // form.find('select[required]').each(function () {
        //     if ($(this).val() === '') {
        //         isValid = false;
        //         $(this).addClass('error');
        //         $(this).parent().append(
        //             '<div class="error-msg">Chọn danh xưng</div>'
        //         );
        //     }
        // });


        form.find('select[required]').each(function () {
            const select = $(this);
            const wrapper = select.closest('.select-wrapper');

            // Xóa lỗi cũ (nếu có)
            wrapper.find('.error-msg').remove();
            select.removeClass('error');

            if (select.val() === '') {
                isValid = false;

                select.addClass('error');

                wrapper.append(
                    '<div class="error-msg">Vui lòng chọn danh xưng</div>'
                );
            }
        });


        /* ===============================
           VALIDATE INPUT / TEXTAREA REQUIRED
        =============================== */
        form.find('input[required], textarea[required]').each(function () {
            if (!$(this).val().trim()) {
                isValid = false;
                $(this).addClass('error');
                $(this).parent().append(
                    '<div class="error-msg">Vui lòng nhập form</div>'
                );
            }
        });

         ===============================
           VALIDATE PASSWORD MATCH
        =============================== 
        const password = $('#password');
        const confirmPassword = $('#confirm_password');

        if (password.val().trim() && confirmPassword.val().trim()) {
            if (password.val() !== confirmPassword.val()) {
                isValid = false;
                password.addClass('error');
                confirmPassword.addClass('error');
                confirmPassword.parent().append(
                    '<div class="error-msg">Mật khẩu xác nhận không khớp.</div>'
                );
            }
        }

        /* ===============================
           VALIDATE PHONE
        =============================== */
        const phoneVal = phoneInput.val().trim();

        if (phoneVal) {
            if (!/^[0-9]+$/.test(phoneVal)) {
                isValid = false;
                phoneInput.addClass('error');
                phoneInput.parent().append(
                    '<div class="error-msg">Chỉ được nhập số.</div>'
                );
            } else if (phoneVal.length < 9 || phoneVal.length > 11) {
                isValid = false;
                phoneInput.addClass('error');
                phoneInput.parent().append(
                    '<div class="error-msg">Số điện thoại từ 9–11 chữ số.</div>'
                );
            }
        }

        /* ===============================
           ❌ FORM INVALID → DỪNG
        =============================== */
        if (!isValid) {
            console.log('FORM INVALID - STOP');
            return false;
        }

        /* ===============================
           ✅ FORM HỢP LỆ → AJAX
        =============================== */
        let percent = 0;
        $('#loadingPercent').text('0%');
        $('#loadingOverlay').fadeIn(200);

        const loadingTimer = setInterval(function () {
            if (percent < 90) {
                percent += 5;
                $('#loadingPercent').text(percent + '%');
            }
        }, 150);

        const data = new FormData(this);

        $.ajax({
            type: 'POST',
            url: '/modules.php?name=Your_Account&op=save__newuser',
            data: data,
            cache: false,
            contentType: false,
            processData: false
        })
        .done(function (res) {
            console.log('AJAX RESPONSE >>>', res);

            clearInterval(loadingTimer);
            $('#loadingPercent').text('100%');

            setTimeout(function () {
                $('#loadingOverlay').fadeOut(300);
                $('#toastSuccess').fadeIn(300);

                setTimeout(function () {
                    $('#toastSuccess').fadeOut(400);
                }, 5000);

                form[0].reset();
            }, 400);
        })
        .fail(function (jqXHR) {
            clearInterval(loadingTimer);
            $('#loadingOverlay').fadeOut(300);
            console.log(jqXHR.responseText);
        });

    });

});