Я пытаюсь сохранить выбранные значения в зависимых раскрывающихся списках после неудачной отправки формы. Я заставил его работать для раскрывающегося списка «Провинция», но когда я попробовал раскрывающийся список «Муниципалитет» и раскрывающийся список «Район», это не сработало. Единственный раскрывающийся список, который сохраняет свое значение, когда я обновляю страницу или отправляю форму, даже если есть пустые данные, — это раскрывающийся список «Провинция». Вот мои коды:
<!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>
<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>
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(''),
@TUPKAP Его уже удалили, но выбранные значения все еще не сохраняются.






При рендеринге страницы, если есть сохраненный муниципалитет, необходимо загрузить районы, как это сделано для муниципалитетов.
Выбрав провинцию, вы должны сбросить муниципалитет и район, выбрав муниципалитет, вы должны сбросить муниципалитет.
Самое важное: в 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() для лучшего применения принципа единой ответственности.
Объект, возвращаемый функцией AssociationAddressDropdown(), имеет несколько определений для муниципалитета и района. Уберите
municipality: ''иdistrict: ''.