Как применить постоянный плагин alpinejs к зависимому раскрывающемуся списку

Я пытаюсь сохранить выбранные значения в зависимых раскрывающихся списках после неудачной отправки формы. Я заставил его работать для раскрывающегося списка «Провинция», но когда я попробовал раскрывающийся список «Муниципалитет» и раскрывающийся список «Район», это не сработало. Единственный раскрывающийся список, который сохраняет свое значение, когда я обновляю страницу или отправляю форму, даже если есть пустые данные, — это раскрывающийся список «Провинция». Вот мои коды:

fca-профиль-edit.blade.php

<!DOCTYPE html>
<html lang = "{{ str_replace('_', '-', app()->getLocale()) }}">

@include('shared.head')

<body x-data = "associationAddressDropdown()" x-init = "initialize()">
    @include('components.navigation-header')
    @include('layouts.navigation')

    <div class = "container mt-2">
        @if ($associationProfile)
            <a href = "{{ route('fca.view') }}" class = "edit-link">View</a>
            <hr>
        @endif
        <form action = "{{ route('fca.update') }}" method = "post" enctype = "multipart/form-data">
            @csrf

            @include('fca-profile-edit.association-profile')
            <hr>
            <input type = "submit" value = "{{ isset($fca) ? 'Update' : 'Submit' }}"
                class = "btn btn-success text-white col-md-4 rounded-pill mb-2 mx-auto d-block">

        </form>
    </div>
    <script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
        integrity = "sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"     crossorigin = "anonymous">
    </script>
    <script src = "{{ asset('js/fca-profile.js') }}"></script>
</body>

</html>

ассоциация-профиль.blade.php

<div class = "row">

    <div class = "col-md-4 mb-2">
        <label for = "associationProvince" class = "form-label label-style">Province</label>
        <select x-model = "province" x-on:change = "onProvinceChange" id = "associationProvince" name = "associationProvince"
            class = "form-select">
            <option value = "">Choose Province</option>
            @foreach ($provinceValues as $id => $provinceValue)
                <option value = "{{ $provinceValue->id }}">{{ $provinceValue->province_name }}</option>
            @endforeach
        </select>
        @error('associationProvince')
            <span class = "fs-6 text-danger">Please choose a province.</span>
        @enderror
    </div>

    <div class = "col-md-4 mb-2">
        <label for = "associationMunicipality" class = "form-label label-style">Municipality</label>
        <select x-model = "municipality" x-on:change = "onMunicipalityChange" id = "associationMunicipality"
            name = "associationMunicipality" class = "form-select">
            <option value = "">Choose Municipality</option>
            <template x-for = "municipality in municipalities" :key = "municipality.id">
                <option :value = "municipality.id" x-text = "municipality.municipality_name"></option>
            </template>
        </select>
        @error('associationMunicipality')
            <span class = "fs-6 text-danger">Please choose a municipality.</span>
        @enderror
    </div>

    <div class = "col-md-4 mb-2">
        <label for = "associationDistrict" class = "form-label label-style">District</label>
        <select x-model = "district" id = "associationDistrict" name = "associationDistrict" class = "form-select">
            <option value = "">Choose District</option>
            <template x-for = "district in districts" :key = "district.id">
                <option :value = "district.id" x-text = "district.district_name"></option>
            </template>
        </select>
        @error('associationDistrict')
            <span class = "fs-6 text-danger">Please choose a district.</span>
        @enderror
    </div>

</div>

fca-profile.js

function associationAddressDropdown() {
    return {
        province: Alpine.$persist(''),
        municipality: Alpine.$persist(''),
        district: Alpine.$persist(''),
        municipality: '',
        district: '',
        municipalities: [],
        districts: [],
        initialize() {
            if (this.province) {
                this.fetchMunicipalities(this.province);
            }
        },
        onProvinceChange(event) {
            this.province = event.target.value;
            this.fetchMunicipalities(this.province);
        },
        onMunicipalityChange(event) {
            this.municipality = event.target.value;
            this.fetchDistricts(this.municipality);
        },
        fetchMunicipalities(province) {
            axios.get(`/provinces/${province}`).then(res => {
                this.municipalities = res.data;
                this.districts = [];
            }).catch(error => {
                console.error('Error fetching municipalities:', error);
            });
        },
        fetchDistricts(municipality) {
            axios.get(`/municipalities/${municipality}`).then(res => {
                this.districts = res.data;
            }).catch(error => {
                console.error('Error fetching districts:', error);
            });
        }
    };
}

Я попробовал это сделать муниципалитет: Alpine.$persist(''), район: Альпийский.$persist(''),

Прямо как в провинции, потому что там это работало провинция: Alpine.$persist(''),

Объект, возвращаемый функцией AssociationAddressDropdown(), имеет несколько определений для муниципалитета и района. Уберите municipality: '' и district: ''.

TUPKAP 21.06.2024 08:18

@TUPKAP Его уже удалили, но выбранные значения все еще не сохраняются.

Christian Tejano 21.06.2024 08:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
2
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При рендеринге страницы, если есть сохраненный муниципалитет, необходимо загрузить районы, как это сделано для муниципалитетов.
Выбрав провинцию, вы должны сбросить муниципалитет и район, выбрав муниципалитет, вы должны сбросить муниципалитет.

Самое важное: в x-for отображаются опции, проверяющие сохраненное значение для select и установку атрибута selected

HTML

.....

<body x-data = "associationAddressDropdown()">

    .....

    <div ..... >

        .....

        <select x-model = "municipality"
                x-on:change = "onMunicipalityChange"
                id = "associationMunicipality"
                name = "associationMunicipality"
                class = "form-select"
        >
            <option value = "">Choose Municipality</option>

            <template x-for = "municipality_row in municipalities" :key = "municipality_row.id">

                <option :value = "municipality_row.id"
                        :selected = "municipality_row.id == municipality"
                        x-text = "municipality_row.municipality_name"
                >
                </option>

            </template>

        </select>

        .....

    </div>

    <div .....>
    
       ..... 
    
        <select x-model = "district"
                id = "associationDistrict"
                name = "associationDistrict"
                class = "form-select"
        >
            <option value = "">Choose District</option>
    
            <template x-for = "district_row in districts" :key = "district_row.id">
    
                <option :value = "district_row.id"
                        :selected = "district_row.id == district"
                        x-text = "district_row.district_name"
                >
                </option>
    
            </template>
    
        </select>
    
        .....
    
    </div>

    .....

</body>

Javascript:

function associationAddressDropdown() {

    return {

        province: Alpine.$persist(null).using(sessionStorage),
        municipality: Alpine.$persist(null).using(sessionStorage),
        district: Alpine.$persist(null).using(sessionStorage),

        municipalities: [],
        districts: [],


        init() {

            if (this.province) {
                this.fetchMunicipalities(this.province);
            }

            if (this.municipality) {
                this.fetchDistricts(this.municipality);
            }
        },


        onProvinceChange() {

            this.district = null;
            this.districts = [];

            this.municipality = null;
            this.fetchMunicipalities(this.province);
        },


        onMunicipalityChange() {

            this.district = null;
            this.fetchDistricts(this.municipality);
        },


        fetchMunicipalities(province) {

            axios.get(`/provinces/${province}`).then(res => {
                this.municipalities = res.data;
                // this.districts = []; ~~~> moved 
            }).catch(error => {
                console.error('Error fetching municipalities:', error);
            });
        },

        .....
    };
}

Я также применил следующие изменения:

  • Я удалил x-init из <body> и переименовал метод Initialize() в init(), поэтому он выполняется автоматически, когда AlpineJS инициализирует объект.

  • Я использовал sessionStorage (.using(sessionStorage)) для сохранения, чтобы разрешить свежие значения, когда браузер закрывается, а затем снова открывается.

  • В x-for я переименовал текущую строку с суффиксом _row (муниципалитет_строка и район_строка), чтобы избежать путаницы с одноимёнными объектами недвижимости.

  • в обработчиках событий — onProvinceChange() и onMunicipalityChange() — я удалил назначения свойств, потому что это уже сделано AlpineJs благодаря x-модели, и назначение вручную также может вызвать конфликты

  • Я перенес сброс массива районов из метода fetchMunicipalities() в onProvinceChange() для лучшего применения принципа единой ответственности.

Другие вопросы по теме