Как правильно ждать отправки событий? - PullRequest
0 голосов
/ 31 марта 2020

Вот что делает мой код:

Функция checkFieldsBeforeSubmit (последняя) вызывается, когда пользователь нажимает кнопку отправки. Он запускает события focusout или change, прикрепленные ко всем входам или выборам формы (функция dispatchAllFormInputEvents()). События выполняют функции, которые проверяют ввод или выбор и соответственно изменяют атрибут поля isInputValid. Затем я проверяю все поля, чтобы проверить, является ли их isInputValid ложным.

Несмотря на выполнение этого последнего теста после .then(, если я не добавлю setTimeout, мой тест выполняется до мои события закончились.

Что setTimeout это ужасный взлом, верно? Как я могу должным образом ждать, пока эти события завершатся sh?

Не jQuery Решения настоятельно предпочтительны.

    fieldOne = document.getElementById('form_field1');
    fieldOne.addEventListener('focusout', validateFieldOneInput, false);

    // this function validate fieldOne
    function validateFieldOneInput()
    {
        let idField = "form_field1";
        let field = document.getElementById(idField);
        let input = field.value;
        let codeError= "";

        fetchInfosForValidation(input).then( (infos) => {

            if ( ! checkIfFormatCorrect() ) return false;

            // [...] other checks

            toggleFieldStatus(true, field, infos, codeError); // valid input
            return true;
        });
    }

  // this is a test use by validating functions.
    function checkIfFormatCorrect() {
        // doing stuff. return true if correct, false otherwise
    }

    // this change the state of a field, show error message.
    function toggleFieldStatus(isInputValid, field, infos, codeError) {
        field.setAttribute('isInputValid', isInputValid);
        field.classList.remove('required-border');

        if ( ! isInputValid )
        {
            field.classList.add("required-border");
            showErrorMessage(infos.errors[codeError]);
        }
    }

    // ajax call to fetch info needed for validation.
    function fetchInfosForValidation(input) {
        return new Promise(function (resolve, reject) {
            $.ajax({
                url: "/my/Url",
                type: "POST",
                data: {
                    input: input,
                },
                success: function (result) {
                    resolve(result.infos);
                },
            });
        });
    }

    // trigger all the events of the form
    async function dispatchAllFormInputEvents() {
            $('[id^="form"]').each(function(index, el) {
                var fieldEvent = new Event('focusout');
                if ( el.nodeName == "SELECT" ) fieldEvent = new Event('change');
                this.dispatchEvent(fieldEvent);
            });
    }

    // function called when 'submit' is hit.
    async function checkFieldsBeforeSubmit()
    {
        dispatchAllFormInputEvents().then( () => {
            setTimeout( () => { // WOULD LIKE TO GET RID OF THIS
                let isFormValid = true;
                $('[id^="form"]').each(function(index, el) {
                    if ( $(this).attr("isInputValid") === "false" ) isFormValid = false;
                });
                console.log(isFormValid);
            }, 1000); // HORRIBLE HACK
        });

    }
...