My server performs a query to get all country data with Eloquent relationships:
$country = Countries::with([
'description',
'provinces.Districts',
'provinces.Districts.communes',
'provinces.Districts.communes.villages'])
->where('status', 1)->get()->toArray();
Using the JavaScript below, I'm filtering the villages based on the locations already selected.
$(document).on('change', '#country_of_birth,#province_of_birth,#district_of_birth,#district_of_birth,#commune_of_birth', function (e) {
"use strict";
var data = {};
var provinces = $('#province_of_birth'),
district = $('#district_of_birth'),
commune = $('#commune_of_birth'),
village = $('#village_of_birth');
var pro = '<option value="">-</option>',distrs = '<option value="">-</option>',comms = '<option value="">-</option>', vills = '<option value="">-</option>';
var countryId = parseInt($("select[name='country_of_birth']").select2("data").element[0].dataset['id']);
if ($(this).is('#country_of_birth')) {
provinces.select2('val', '');
district.select2('val', '');
commune.select2('val', '');
village.select2('val', '');
$.each(country, function (inx, vals) {
if (parseInt(vals.id) === countryId) {
$.each(vals.provinces, function (inx, prov) {
data = prov.districts;
pro += '<option value="' + prov.prov_gis + '" data-id="' + prov.id + '"> ' + prov.eng_name + ' </option>';
});
}
});
provinces.empty().append(pro);
}
if ($(this).is('#province_of_birth')) {
var provinceId = parseInt($("select[name='province_of_birth']").select2("data").element[0].dataset['id']);
district.select2('val', '');
commune.select2('val', '');
village.select2('val', '');
$.each(country, function (inx, countr) {
if (parseInt(countr.id) !== countryId)return;
$.each(countr.provinces, function (inx, prov) {
$.each(prov.districts, function (inx, distr) {
if (parseInt(distr.prov_id) !== provinceId)return;
distrs += '<option value="' + distr.distr_gis + '" data-id="' + distr.id + '"> ' + distr.eng_name + ' </option>';
})
});
});
district.empty().append(distrs);
}
if ($(this).is('#district_of_birth')) {
var districId = parseInt($("select[name='district_of_birth']").select2("data").element[0].dataset['id']);
village.select2('val', '');
$.each(country, function (inx, countr) {
if (parseInt(countr.id) !== countryId) return;
$.each(countr.provinces, function (inx, prov) {
$.each(prov.districts, function (inx, distr) {
$.each(distr.communes, function (inx, comm) {
if (parseInt(comm.distr_id) !== districId)return;
comms += '<option value="' + comm.comm_gis + '" data-id="' + comm.id + '"> ' + comm.en_name +' </option>';
});
})
});
});
commune.empty().append(comms);
}
if ($(this).is('#commune_of_birth')) {
var commId = parseInt($("select[name='commune_of_birth']").select2("data").element[0].dataset['id']);
$.each(country, function (inx, countr) {
if (parseInt(countr.id) !== countryId)return;
$.each(countr.provinces, function (inx, prov) {
$.each(prov.districts, function (inx, distr) {
$.each(distr.communes, function (inx, comm) {
$.each(comm.villages, function (inx, vill) {
if (parseInt(vill.comm_id) !== commId)return;
vills += '<option value="' + vill.vill_gis + '"> ' + vill.en_name + ' </option>';
});
});
})
});
});
village.empty().append(vills);
}
});
It works well, but I am concerned about its performance. I want to revise it or use a Javascript builtin method instead of looping through the data repeatedly.