vuejs не будет прокручивать к началу div при ошибке формы - PullRequest
0 голосов
/ 25 октября 2019

У меня есть 2 компонента на одной странице, оба с формой. Я использую Vue.js 2.6

Вторая форма имеет кнопку отправки и при нажатии выдает свойство. Первая форма прослушивает это свойство и действует на него после получения, что все работает нормально. Эта форма делает ajax-запрос для проверки формы, которая также работает.

У меня проблема с тем, что в форме есть ошибки, прокрутите страницу до верхней части формы и нажмите кнопку отправки. внизу страницы.

Нет ошибок консоли, и отображаются все сообщения проверки, но форма НЕ будет прокручиваться вверх.

Я думаю, что проблема заключается здесь

this.$nextTick(() => {
    this.$refs.notice.scrollTop = 0;
});

Я перепробовал все ответы, которые смог найти на SO, но ничего не работает

Это первая форма

<template>
    <form id="contact-form" @submit.prevent="submit" ref="notice">
        <div class="card mb-4 border-0">
            <div class="notice notice-danger" v-show="errored">
                <strong>Error</strong> There are errors in the form!!
            </div>
            <div class="row">
                <div class="col-12">
                    <div class="form-group floating-label-form-group controls">
                        <label>Contact Name</label>
                        <input type="text" class="form-control" placeholder="Contact Name" id="contact" v-model="fields.contact" v-on:change="contactChange">
                        <div v-if="errors && errors.contact" class="text-danger">{{ errors.contact[0] }}</div>
                    </div>
                </div>
                <div class="col-12">
                    <div class="form-group floating-label-form-group controls">
                        <label>Telephone</label>
                        <input type="tel" class="form-control" placeholder="Telephone (optional)" id="telephone" v-model="fields.telephone" v-on:change="telephoneChange">
                        <div v-if="errors && errors.telephone" class="text-danger">{{ errors.telephone[0] }}</div>
                    </div>
                </div>
                <div class="col-12">
                    <div class="form-group floating-label-form-group controls">
                        <label>Email Address</label>
                        <input type="email" class="form-control" placeholder="Email" id="email" v-model="fields.email" v-on:change="emailChange">
                        <div v-if="errors && errors.email" class="text-danger">{{ errors.email[0] }}</div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</template>
<script>
export default {
    data: function() {
        return {
            errors: {},
            errored: false,
        }
    },
    mounted() {
        this.$root.$on('checkFormsValid', (customer) => {
            this.errors = {};
            this.errored = false;

            axios.post('/some/url', this.fields).then(response => {
                this.$root.$emit('validated', response.data.customer);
            }).catch(error => {
                if (error.response.status === 422) {
                    this.errors = error.response.data.errors || {};
                    this.$root.$emit('errors', this.errors);
                    this.errored = true;

                    this.$nextTick(() => {
                        this.$refs.notice.scrollTop = 0;
                    });
                }
            });
        })
    },
    methods: {
        contactChange: function() {
            delete this.errors.contact;
        },
        telephoneChange: function() {
            delete this.errors.telephone;
        },
        emailChange: function() {
            delete this.errors.email;
        },
    }
}
</script>

и уменьшенная вторая форма

<template>
    <form id="payment-form" ref="form" action="/checkout" method="POST" class="uk-padding">
        <button class="btn btn-primary btn-block" @click.prevent="okToSend()">
            Click me
        </button>
    </form>
</template>

<script>
    export default {
        data() {
            return {
                customer: '',
                loading: false,
            }
        },
        mounted() {
            this.$root.$on('validated', (customer) => {
                // do something
            })
        },
        methods: {
            okToSend: function() {
                this.$root.$emit('checkFormsValid', this.customer)
            }
        }
    }
</script>

1 Ответ

0 голосов
/ 26 октября 2019

Откройте инструменты разработчика и узнайте точное значение div, которое генерирует полосу прокрутки;Затем измените свойство scroll этого элемента.

Вы также можете просто убедиться, что определенный элемент видим, используя такую ​​функцию:

function scrollToView(element){
    var offset = element.offset().top;
    if(!element.is(":visible")) {
        element.css({"visibility":"hidden"}).show();
        var offset = element.offset().top;
        element.css({"visibility":"", "display":""});
    }

    var visible_area_start = $(window).scrollTop();
    var visible_area_end = visible_area_start + window.innerHeight;

    if(offset < visible_area_start || offset > visible_area_end){
         // Not in view so scroll to it
         $('html,body').animate({scrollTop: offset - window.innerHeight/3}, 1000);
         return false;
    }
    return true;
}
...