Non puoi selezionare più di 25 argomenti
Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
210 righe
9.3 KiB
210 righe
9.3 KiB
<?php |
|
|
|
use App\WGS\Utils\Dto\ProvinceDistrictCellDto\DistrictCellDto; |
|
use App\WGS\Utils\Enum\ProvinceDistrictFields; |
|
use App\WGS\Utils\Helper\ProvinceDistrictFieldHelper; |
|
|
|
/** |
|
* @var DistrictCellDto $districtCellConfig |
|
*/ |
|
|
|
$options = [ |
|
"id" => $districtCellConfig->fieldId, |
|
'label' => __($districtCellConfig->fieldLabel), |
|
'type' => $districtCellConfig->fieldType->value, |
|
"empty" => true, |
|
"disabled" => $districtCellConfig->disabled, |
|
'required' => $districtCellConfig->fieldRequired |
|
]; |
|
|
|
if (!empty($districtCellConfig->fieldValue)) { |
|
$options['data-value'] = $districtCellConfig->fieldValue; |
|
} |
|
?> |
|
|
|
<?php if ($districtCellConfig->fieldId !== null && $districtCellConfig->fieldName !== null): ?> |
|
<?= $this->Form->control($districtCellConfig->fieldName, $options) ?> |
|
<?php if (isset($districtCellConfig->entity) && $districtCellConfig->entity->hasErrors($districtCellConfig->fieldName)): ?> |
|
<div id="district-error" class="invalid-feedback d-block"> |
|
<?php |
|
$errors = $districtCellConfig->entity->getError($districtCellConfig->fieldName); |
|
|
|
/* |
|
* Qui ci finisco solo se siamo in un ciclo e quindi il nome del field non matcha con la rule |
|
*/ |
|
if(empty($errors)) { |
|
$errors = $districtCellConfig->entity->getError("district"); |
|
} |
|
|
|
if (is_array($errors) && isset($errors['validDistrict'])) { |
|
echo h($errors['validDistrict']); |
|
} else { |
|
echo is_array($errors) ? h(implode(', ', $errors)) : h($errors); |
|
} |
|
?> |
|
</div> |
|
<?php endif; ?> |
|
|
|
<script> |
|
/** |
|
* La IFEE è utile per isolare il contesto di esecuzione, visto che su |
|
* applicants potrebbero esserci più istanze dello stesso element. |
|
*/ |
|
(() => { |
|
"use strict"; |
|
|
|
const provinceFieldId = '<?= $districtCellConfig->provinceFieldId ?? null ?>'; |
|
const fieldId = '<?= $districtCellConfig->fieldId ?>'; |
|
const provinceMap = <?= json_encode($provinces ?? []) ?>; |
|
const codProvFieldName = "<?= ProvinceDistrictFieldHelper::raw(ProvinceDistrictFields::PROVINCE_CODE)?>"; |
|
|
|
// Variabile d'appoggio per salvare la last province selected. |
|
let lastProvinceSelected = null; |
|
const districtCache = {}; |
|
|
|
const select2ConfigObject = ($province, hasProv) => { |
|
return { |
|
minimumInputLength: hasProv ? 0 : 3, |
|
width: '100%', |
|
language: { |
|
inputTooShort: function (input_params) { |
|
return (input_params.input.length === 0 ? 'Digitare almeno ' : 'Digitare altri ') + |
|
(input_params.minimum - input_params.input.length) + ' caratteri'; |
|
}, |
|
noResults: function () { |
|
return 'Nessun risultato!'; |
|
}, |
|
searching: function () { |
|
return 'Caricamento...'; |
|
}, |
|
}, |
|
ajax: { |
|
url: '/districts/search_districts', |
|
cache: true, |
|
dataType: 'json', |
|
delay: 500, |
|
transport: function (params, success, failure) { |
|
const codProv = provinceMap[$province.val()] ?? null; |
|
const term = params.data.term || ''; |
|
const isEmptySearch = term.trim() === ''; |
|
|
|
if (hasProv && isEmptySearch && lastProvinceSelected === codProv && districtCache[codProv]) { |
|
success({results: districtCache[codProv]}); |
|
return null; |
|
} |
|
lastProvinceSelected = codProv; |
|
|
|
return $.ajax(params).done(data => { |
|
const parsed = Object.entries(data?.districts || {}).map( |
|
([id, text]) => ({id, text}) |
|
); |
|
if (isEmptySearch && codProv) { |
|
districtCache[codProv] = parsed; |
|
} |
|
success({results: parsed}); |
|
}).fail(failure); |
|
}, |
|
data: function (params) { |
|
if (hasProv && !$province.val()) return {}; |
|
|
|
const codProv = provinceMap[$province.val()] ?? null; |
|
let searchTerms = { |
|
...params |
|
}; |
|
|
|
if (codProv !== null) { |
|
searchTerms[codProvFieldName] = codProv; |
|
} |
|
|
|
return searchTerms; |
|
} |
|
}, |
|
}; |
|
}; |
|
|
|
|
|
function initDistrictSelect($districtSelect, $province, hasProv) { |
|
if ($districtSelect.hasClass('select2-hidden-accessible')) { |
|
$districtSelect.select2('destroy'); |
|
} |
|
|
|
const selectedProvince = hasProv && !!$province.val(); |
|
const shouldDisable = hasProv && !selectedProvince; |
|
const isDisabled = <?= $districtCellConfig->disabled ? "true" : "false" ?>; |
|
|
|
$districtSelect |
|
.val(null) |
|
.empty() |
|
.prop('disabled', shouldDisable || isDisabled) |
|
.select2({ |
|
...select2ConfigObject($province, hasProv), |
|
minimumInputLength: hasProv ? 0 : 3 |
|
}) |
|
.on('select2:opening', function (e) { |
|
if ($(this).prop('disabled')) e.preventDefault(); |
|
}); |
|
|
|
|
|
// Se ho un valore essendo che le options vengono passate via ajax |
|
// dobbiamo forzare il set, altrimenti non vedremo mai il selected Value. |
|
const selectedValue = $districtSelect.data('value'); |
|
if (selectedValue) { |
|
const currentText = $districtSelect.find('option:selected').text() || selectedValue; |
|
const newOption = new Option(currentText, selectedValue, true, true); |
|
$districtSelect |
|
.append(newOption) |
|
.val(selectedValue) |
|
.trigger("change") |
|
.prop('disabled', shouldDisable || isDisabled) |
|
} |
|
} |
|
|
|
window.addEventListener('DOMContentLoaded', function () { |
|
const $districtSelect = $('[id="' + fieldId + '"]'); |
|
const $province = provinceFieldId ? $('#' + provinceFieldId) : null; |
|
const hasProv = provinceFieldId && provinceFieldId.trim() !== '' && $('select[id="' + provinceFieldId + '"]').length > 0; |
|
|
|
initDistrictSelect($districtSelect, $province, hasProv); |
|
if (hasProv) { |
|
$province.on('change', () => { |
|
initDistrictSelect($districtSelect, $province, hasProv) |
|
}); |
|
} |
|
}) |
|
|
|
/** |
|
* Questo è un custom event progettato solo per ascoltare un evento custom |
|
* L'evento custom viene scatenato dal tasto aggiungi per inserire un nuovo applicants. |
|
* Questo garantisce di inizializzare opportunamente la nuova select appena inserita. |
|
* Da considerare che nei casi in cui l'element o la cell non vengono utilizzate nel contesto di |
|
* applicants, questo evento non verrà mai scatenato a meno di dispatch espliciti. |
|
* Questo garantisce che il codice all'interno non venga mai invocato. |
|
* Pertanto non serve inserire altri controlli all'interno al momento. |
|
*/ |
|
window.addEventListener('applicantBlockAdded', (e) => { |
|
const $districtSelect = $('[id="' + fieldId + '"]'); |
|
const $province = provinceFieldId ? $('#' + provinceFieldId) : null; |
|
const hasProv = provinceFieldId && provinceFieldId.trim() !== '' && $('select[id="' + provinceFieldId + '"]').length > 0; |
|
|
|
const applicants_id = e.detail.id; |
|
// Se per qualsiasi motivo arriva un id nullo non facciamo nulla. |
|
if (applicants_id === null) { |
|
console.error("applicants id is null"); |
|
return; |
|
} |
|
|
|
// Ci assicuriamo che l'id che arriva, sia quello che configurato lato server |
|
// rispetto a ciò che ci viene passato nel custom event. |
|
const addedFieldId = `applicants-${applicants_id}-district` |
|
if (addedFieldId === fieldId) { |
|
initDistrictSelect($districtSelect, $province, hasProv); |
|
if (hasProv) { |
|
$province.on('change', () => { |
|
initDistrictSelect($districtSelect, $province, hasProv) |
|
}); |
|
} |
|
} |
|
}); |
|
})(); |
|
</script> |
|
<?php endif; ?>
|
|
|